<reponame>vishalbelsare/SLAPP3<gh_stars>1-10
# to understand whot is done here and why, look at myGayss.md

# about the root of random numbers in Python
# https://github.com/python/cpython/blob/master/Lib/random.py

import os
import random as r
import math
import commonVar as common
#import urllib.request
import zipfile, requests, io

# the myGauss calculation is possible via common.mg=myGauss.myG() in paramenters.property
# then  call it with common.mg.myGauss(...)

class myG():
    # When x and y are two variables from [0, 1), uniformly
    # distributed, then
    #
    #    cos(2*pi*x)*sqrt(-2*log(1-y))
    #    sin(2*pi*x)*sqrt(-2*log(1-y))
    #
    # are two *independent* variables with normal distribution
    # (mu = a = 1).
    # tnx to Lambert Meertens, https://en.wikipedia.org/wiki/Lambert_Meertens

    # cos and sin produce small differences in tails in Mac, Linux, Windows
    # so we cut them; we do not truncate them with floor(x*10**n)*10**-n
    # to avoid subtle division errors (1/10 in base 2)

    def __init__(self):

        self.TWOPI=2.0*math.pi
        self.gauss_next=None
        self.caseList=["1","2","3","4","5","6","7","7b","8","8b","9","9b","10","11"] # book cases
        # NB cases 0a and 0b use another version of SLAPP, in Python2
        self.error=False
        self.link = \
         "https://raw.githubusercontent.com/terna/oligopolyBookCasesGaussianValues/master/"
         # this is for the zip file, but it is exactly the same of a .txt one; you calculation
         # verify opening 'View raw' for a large file

        #common.fgOu is set by default to None in commmonVar.py
        #for the cases of the book Rethinking ... of Mazzoli, Morini,
        #and Terna, we have recorded the same gaussaian values used there, whith random.gauss();
        #if those values are missing, they are anyway calculated using the non perfectly portable
        #random.gauss() tool and the common.fgOu value is != None to acrivate [$] below

        #is this a book ASHAM case?
        if common.case in self.caseList: #check if the recorded gaussian values are on disk
                try: #local file existing
                    z = zipfile.ZipFile(common.project+"/exampleGauss/"+common.case+".txt.zip")
                    common.fgIn=z.open(common.case+".txt")
                    print("\nBook case",common.case,"\n",\
                          "\nReading gaussian random values locally.\n")

                except:                  #if not, check if rerded gaussian values are online
                    try: # online file
                        r = requests.get(self.link+common.case+".txt.zip",\
                                headers = { "User-Agent":"My new User-Agent"})
                                # "My new User-Agent" is a trick from
                                # http://wolfprojects.altervista.org/articles/change-urllib-user-agent/
                                # unnecessary with github repositories, but does not hurt if left there
                        z = zipfile.ZipFile(io.BytesIO(r.content))
                        z.extractall()
                        common.fgIn=z.open(common.case+".txt")

                        print("\nBook case",common.case,"\n",\
                              "\nReading gaussian random values from:",self.link,"\n")
                    except: #data does not exists, we will record them (see [$] above and below)
                        common.fgOu=open(common.project+\
                                "/exampleGauss/"+common.case+".txt","w")
                        print("\nBook case",common.case,"\n",\
                              "\nWriting gaussian random values to local 'exampleGauss' folder\n")
                        # the final zip operation is done in oActions.py look "#closing fgOu"
        else:
                if common.case== "": common.case="'unknown'"
                print("\n\nThe running case "+common.case+" is outside book (Mazzoli et al. 2019) cases\n"\
                      "Neither using past random gaussian values nor saving the new generated ones\n")

    # internal method
    # the following result is the same in any operating system, using recorded
    # values from previous cases (values generated by gauss() or new values
    # generated by myGauss(), stable in all the operating systems)
    def myGauss0(self,mu, sigma):

        z = self.gauss_next
        self.gauss_next=None
        if z is None:
          x2pi = r.random() * self.TWOPI
          g2rad = math.sqrt(-2.0 * math.log(1.0 - r.random()))
          g2rad=('%1.20f' % g2rad)             # converts also exponent 'e'
                                               # with an extra number of digits
          g2rad=float(g2rad[0:12])      # cutting 'dangeorus' digits (rounding
                                        # effects and different tails in Mac or Linux)


          myCos=('%1.20f' % math.cos(x2pi))    # converts also exponent 'e'
          mySin=('%1.20f' % math.sin(x2pi))    # with an extra number of digits

          myCos=float(myCos[0:12])  # cutting 'dangeorus' digits (rounding
          mySin=float(mySin[0:12])  # effects and different tails in Mac or Linux)

          z = myCos * g2rad
        return mu + z*sigma

    # use this method
    def myGauss(self,mu, sigma):

        # new cases
        if common.fgIn == None and common.fgOu==None:
            return self.myGauss0(mu, sigma)

        # cases of the book
        if common.fgIn != None:
            g=float(common.fgIn.readline())
            r.gauss(mu, sigma) # void destination, the call is made to keep safe
                               # the original sequence of random number generation
            return g

        # [$] - see above the comment with [$] inside
        if common.fgOu != None: # [$] see  comment above
            g=r.gauss(mu, sigma)
            print(g,file=common.fgOu) #the close() is in oActions.py
            return g

# to understand whot is done here and why, look at myGayss.md

# about the root of random numbers in Python
# https://github.com/python/cpython/blob/master/Lib/random.py

import os
import random as r
import math
import commonVar as common
#import urllib.request
import zipfile, requests, io

# the myGauss calculation is possible via common.mg=myGauss.myG() in paramenters.property
# then  call it with common.mg.myGauss(...)

class myG():
    # When x and y are two variables from [0, 1), uniformly
    # distributed, then
    #
    #    cos(2*pi*x)*sqrt(-2*log(1-y))
    #    sin(2*pi*x)*sqrt(-2*log(1-y))
    #
    # are two *independent* variables with normal distribution
    # (mu = a = 1).
    # tnx to Lambert Meertens, https://en.wikipedia.org/wiki/Lambert_Meertens

    # cos and sin produce small differences in tails in Mac, Linux, Windows
    # so we cut them; we do not truncate them with floor(x*10**n)*10**-n
    # to avoid subtle division errors (1/10 in base 2)

    def __init__(self):

        self.TWOPI=2.0*math.pi
        self.gauss_next=None
        self.caseList=["1","2","3","4","5","6","7","7b","8","8b","9","9b","10","11"] # book cases
        # NB cases 0a and 0b use another version of SLAPP, in Python2
        self.error=False
        self.link = \
         "https://raw.githubusercontent.com/terna/oligopolyBookCasesGaussianValues/master/"
         # this is for the zip file, but it is exactly the same of a .txt one; you calculation
         # verify opening 'View raw' for a large file

        #common.fgOu is set by default to None in commmonVar.py
        #for the cases of the book Rethinking ... of Mazzoli, Morini,
        #and Terna, we have recorded the same gaussaian values used there, whith random.gauss();
        #if those values are missing, they are anyway calculated using the non perfectly portable
        #random.gauss() tool and the common.fgOu value is != None to acrivate [$] below

        #is this a book ASHAM case?
        if common.case in self.caseList: #check if the recorded gaussian values are on disk
                try: #local file existing
                    z = zipfile.ZipFile(common.project+"/exampleGauss/"+common.case+".txt.zip")
                    common.fgIn=z.open(common.case+".txt")
                    print("\nBook case",common.case,"\n",\
                          "\nReading gaussian random values locally.\n")

                except:                  #if not, check if rerded gaussian values are online
                    try: # online file
                        r = requests.get(self.link+common.case+".txt.zip",\
                                headers = { "User-Agent":"My new User-Agent"})
                                # "My new User-Agent" is a trick from
                                # http://wolfprojects.altervista.org/articles/change-urllib-user-agent/
                                # unnecessary with github repositories, but does not hurt if left there
                        z = zipfile.ZipFile(io.BytesIO(r.content))
                        z.extractall()
                        common.fgIn=z.open(common.case+".txt")

                        print("\nBook case",common.case,"\n",\
                              "\nReading gaussian random values from:",self.link,"\n")
                    except: #data does not exists, we will record them (see [$] above and below)
                        common.fgOu=open(common.project+\
                                "/exampleGauss/"+common.case+".txt","w")
                        print("\nBook case",common.case,"\n",\
                              "\nWriting gaussian random values to local 'exampleGauss' folder\n")
                        # the final zip operation is done in oActions.py look "#closing fgOu"
        else:
                if common.case== "": common.case="'unknown'"
                print("\n\nThe running case "+common.case+" is outside book (Mazzoli et al. 2019) cases\n"\
                      "Neither using past random gaussian values nor saving the new generated ones\n")

    # internal method
    # the following result is the same in any operating system, using recorded
    # values from previous cases (values generated by gauss() or new values
    # generated by myGauss(), stable in all the operating systems)
    def myGauss0(self,mu, sigma):

        z = self.gauss_next
        self.gauss_next=None
        if z is None:
          x2pi = r.random() * self.TWOPI
          g2rad = math.sqrt(-2.0 * math.log(1.0 - r.random()))
          g2rad=('%1.20f' % g2rad)             # converts also exponent 'e'
                                               # with an extra number of digits
          g2rad=float(g2rad[0:12])      # cutting 'dangeorus' digits (rounding
                                        # effects and different tails in Mac or Linux)


          myCos=('%1.20f' % math.cos(x2pi))    # converts also exponent 'e'
          mySin=('%1.20f' % math.sin(x2pi))    # with an extra number of digits

          myCos=float(myCos[0:12])  # cutting 'dangeorus' digits (rounding
          mySin=float(mySin[0:12])  # effects and different tails in Mac or Linux)

          z = myCos * g2rad
        return mu + z*sigma

    # use this method
    def myGauss(self,mu, sigma):

        # new cases
        if common.fgIn == None and common.fgOu==None:
            return self.myGauss0(mu, sigma)

        # cases of the book
        if common.fgIn != None:
            g=float(common.fgIn.readline())
            r.gauss(mu, sigma) # void destination, the call is made to keep safe
                               # the original sequence of random number generation
            return g

        # [$] - see above the comment with [$] inside
        if common.fgOu != None: # [$] see  comment above
            g=r.gauss(mu, sigma)
            print(g,file=common.fgOu) #the close() is in oActions.py
            return g
# to understand whot is done here and why, look at myGayss.md # about the root of random numbers in Python # https://github.com/python/cpython/blob/master/Lib/random.py #import urllib.request # the myGauss calculation is possible via common.mg=myGauss.myG() in paramenters.property # then  call it with common.mg.myGauss(...) # When x and y are two variables from [0, 1), uniformly # distributed, then # #    cos(2*pi*x)*sqrt(-2*log(1-y)) #    sin(2*pi*x)*sqrt(-2*log(1-y)) # # are two *independent* variables with normal distribution # (mu = a = 1). # tnx to Lambert Meertens, https://en.wikipedia.org/wiki/Lambert_Meertens # cos and sin produce small differences in tails in Mac, Linux, Windows # so we cut them; we do not truncate them with floor(x*10**n)*10**-n # to avoid subtle division errors (1/10 in base 2) # book cases # NB cases 0a and 0b use another version of SLAPP, in Python2 # this is for the zip file, but it is exactly the same of a .txt one; you calculation # verify opening 'View raw' for a large file #common.fgOu is set by default to None in commmonVar.py #for the cases of the book Rethinking ... of Mazzoli, Morini, #and Terna, we have recorded the same gaussaian values used there, whith random.gauss(); #if those values are missing, they are anyway calculated using the non perfectly portable #random.gauss() tool and the common.fgOu value is != None to acrivate [$] below #is this a book ASHAM case? #check if the recorded gaussian values are on disk #local file existing #if not, check if rerded gaussian values are online # online file # "My new User-Agent" is a trick from # http://wolfprojects.altervista.org/articles/change-urllib-user-agent/ # unnecessary with github repositories, but does not hurt if left there #data does not exists, we will record them (see [$] above and below) # the final zip operation is done in oActions.py look "#closing fgOu" # internal method # the following result is the same in any operating system, using recorded # values from previous cases (values generated by gauss() or new values # generated by myGauss(), stable in all the operating systems) # converts also exponent 'e' # with an extra number of digits # cutting 'dangeorus' digits (rounding # effects and different tails in Mac or Linux) # converts also exponent 'e' # with an extra number of digits # cutting 'dangeorus' digits (rounding # effects and different tails in Mac or Linux) # use this method # new cases # cases of the book # void destination, the call is made to keep safe # the original sequence of random number generation # [$] - see above the comment with [$] inside # [$] see  comment above #the close() is in oActions.py