Exemplo n.º 1
0
    def __init__(self, efloat_mode="float"):
        self.efloat_mode = efloat_mode
        self.efloat = EFloat(efloat_mode)

        self.alphas = []
        self.betas = []
        self.unique_id_string = ""
Exemplo n.º 2
0
def _tanhsinh(s, h):
    N = s

    k = numpy.array(range(-N//2, N//2+1))
    if floatmode == "float":

        x = numpy.tanh(0.5*numpy.pi*numpy.sinh(k*h))
        w = 0.5*h*numpy.pi*numpy.cosh(k*h)/numpy.power(numpy.cosh(0.5*numpy.pi*numpy.sinh(k*h)), 2.0)

        # To interval [0;1]
        x = (x+1.0)*0.5
        w *= 0.5

    elif floatmode == "mpfloat":

        efloat_mode="mpfloat"
        efloat = ef.EFloat(efloat_mode)
        import mpmath as mp

        x = efloat.fromArray(numpy.zeros([N]))
        w = efloat.fromArray(numpy.zeros([N]))

        for i in range(N):
            x[i,0] = mp.mp.tanh(0.5*mp.mp.pi*mp.mp.sinh(k[i]*h))
            w[i,0] = 0.5*h*mp.mp.pi*mp.mp.cosh(k[i]*h)/mp.mp.power(mp.mp.cosh(0.5*mp.mp.pi*mp.mp.sinh(k[i]*h)), 2.0)

        # To interval [0;1]
        x = (x+1.0)*0.5
        w *= 0.5

        x = numpy.array(x.tolist(), dtype=float)[:,0]
        w = numpy.array(w.tolist(), dtype=float)[:,0]

    return x, w
Exemplo n.º 3
0
    def toFloat(self):
        c = REXICoefficients()

        c.efloat = EFloat("float")
        c.function_name = self.function_name

        if self.efloat != None:
            if self.efloat.abs(self.efloat.im(self.gamma)) > 1e-10:
                print("WARNING")
                print("WARNING")
                print("WARNING")
                print("WARNING: Imaginary value " +
                      str(self.efloat.im(self.gamma)) +
                      " should be close to zero")
                print("WARNING")
                print("WARNING")
                print("WARNING")

            c.gamma = float(self.efloat.re(self.gamma))
        else:
            c.gamma = float(self.gamma.real)

        c.alphas = [complex(a) for a in self.alphas]
        c.betas = [complex(b) for b in self.betas]

        c.unique_id_string = self.unique_id_string

        return c
Exemplo n.º 4
0
    def __init__(self, efloat_mode="float"):
        self.efloat_mode = efloat_mode
        self.efloat = EFloat(efloat_mode)

        self.unique_id_string = ""

        self.section_factory = SectionFactory()
        self.section_list = []
Exemplo n.º 5
0
def main():
    # double precision
    floatmode = 'float'

    # multiprecision floating point numbers
    #floatmode = 'mpfloat'

    # load float handling library
    efloat = ef.EFloat(floatmode)

    h = efloat.to(0.2)
    M = 64
    print("M: " + str(M))
    print("h: " + str(h))
    print("")

    for half in [False, True]:

        print("*" * 80)
        print("* Original REXI coefficients")

        rexi = TREXI(
            N=M,
            h=h,
            function_name="phi0",
            reduce_to_half=half,
            floatmode=floatmode,
        )

        print("")
        print("*" * 80)
        print("Running tests...")
        rexi.runTests()

        print("*" * 80)
        print("* REXI coefficients based on original REXI mu")
        print("*" * 80)

        rexi = TREXI(
            N=M,
            h=h,
            ratgauss_basis_function_spacing=1.0,
            ratgauss_basis_function_rat_shift=efloat.to(
                '-4.31532151087502402475593044073320925235748291015625'),
            reduce_to_half=half,
            floatmode=floatmode,
        )
        print("*" * 80)
        print("Rational approx. of Gaussian data:")
        #rexi.ratgauss_coeffs.print_coefficients()

        print("")
        print("*" * 80)
        print("Running tests...")
        rexi.runTests()
Exemplo n.º 6
0
	def __init__(
			self,
                        gaussphi0_N,	# required argument
                        gaussphi0_basis_function_spacing,	# required argument

			floatmode = None
	):
		self.efloat = ef.EFloat(floatmode)

		self.h = self.efloat.to(gaussphi0_basis_function_spacing)
		self.M = int(gaussphi0_N)

		self.b = [self.efloat.exp(self.h*self.h)*self.efloat.exp(-1j*(float(m)*self.h)) for m in range(-self.M, self.M+1)]

		# Generate dummy Gaussian function
		fafcoeffs = TREXI_GaussianCoefficients()
		fafcoeffs.function_name = 'gaussianorig'
		fafcoeffs.function_scaling = self.efloat.to(1.0)
Exemplo n.º 7
0
    def __init__(
        self,
        function_name = "phi0",
        efloat_mode = None
    ):
        self.efloat = ef.EFloat(efloat_mode)

        self.function_name = function_name

        self.function_complex = True

        if self.efloat.floatmode == 'mpfloat':
            import mpmath as mp
            # Set numerical threshold to half of precision
            self.epsthreshold = 1e-15
        else:
            self.epsthreshold = 1e-10


        # Exponential integrator: phi0
        if self.function_name[0:3] == 'phi':

            N = int(self.function_name[3:])

            def fun(x):
                return self.phiN(N, x)

            self.eval = fun

            if self.function_complex:
                self.is_real_symmetric = True
                self.is_complex_conjugate_symmetric = True
            else:
                self.is_real_symmetric = True
                self.is_complex_conjugate_symmetric = False

        elif self.function_name[0:3] == 'ups':

            N = int(self.function_name[3:])

            if self.efloat.floatmode == 'mpfloat':
                import mpmath as mp
                # Set numerical threshold to half of precision
                self.epsthreshold = 1e-10
            else:
                self.epsthreshold = 1e-10


            if N == 1:
                #
                # Setup \upsilon_1 for EDTRK4
                # See document notes_on_time_splitting_methods.lyx
                #
                def fun(x):
                    K = x
                    if abs(x) < self.epsthreshold:
                        return self.efloat.to(1.0)/self.efloat.to(2.0*3.0)
                    else:
                        return (-self.efloat.to(4.0)-K+self.efloat.exp(K)*(self.efloat.to(4.0)-self.efloat.to(3.0)*K+K*K))/(K*K*K)
                self.eval = fun

                if self.function_complex:
                    self.is_real_symmetric = True
                    self.is_complex_conjugate_symmetric = True
                else:
                    self.is_real_symmetric = True
                    self.is_complex_conjugate_symmetric = False


            elif N == 2:
                #
                # Setup \upsilon_2 for EDTRK4
                # See document notes_on_time_splitting_methods.lyx
                #
                def fun(x):
                    K = x
                    if abs(x) < self.epsthreshold:
                        return self.efloat.to(1.0)/self.efloat.to(2.0*3.0)
                    else:
                        return (self.efloat.to(2.0)+1.0*K+self.efloat.exp(K)*(self.efloat.to(-2.0)+K))/(K*K*K)
                self.eval = fun

                if self.function_complex:
                    self.is_real_symmetric = True
                    self.is_complex_conjugate_symmetric = True
                else:
                    self.is_real_symmetric = True
                    self.is_complex_conjugate_symmetric = False


            elif N == 3:
                #
                # Setup \upsilon_3 for EDTRK4
                # See document notes_on_time_splitting_methods.lyx
                #
                def fun(x):
                    K = x
                    if abs(x) < self.epsthreshold:
                        return self.efloat.to(1.0)/self.efloat.to(2.0*3.0)
                    else:
                        return (-self.efloat.to(4.0) - 3.0*K - K*K + self.efloat.exp(K)*(self.efloat.to(4.0)-K))/(K*K*K)
                self.eval = fun

                if self.function_complex:
                    self.is_real_symmetric = True
                    self.is_complex_conjugate_symmetric = True
                else:
                    self.is_real_symmetric = True
                    self.is_complex_conjugate_symmetric = False

            else:
                print("Unknown ups function "+str(N))
                sys.exit(1)

        else:
            print("Unknown basis function "+str(self.function_name))
            sys.exit(1)
Exemplo n.º 8
0
 def __init__(
     self,
     efloat_mode = None,
 ):
     self.efloat = ef.EFloat(efloat_mode)
Exemplo n.º 9
0
def _golubwelsch(n, lo=-1, hi=1, radau=False):

    if floatmode == "float":

        beta = .5 / numpy.sqrt(1-(2*(numpy.arange(1,n)))**(-2.)) # 3-term recurrence coeffs
        T = numpy.diag(beta,1) + numpy.diag(beta,-1);     # Jacobi matrix
        if radau:
            # Eq. 2.4 of Gautschi, Gauss–Radau formulae for Jacobi and Laguerre weight functions, 2000
            if n == 1:
                T[-1,-1] = 1
            else:
                T[-1,-1] = 1 - 2*(n-1)**2 / (2*(n-1)*(2*(n-1)+1))

        D, V = numpy.linalg.eigh(T)                      # Eigenvalue decomposition

        i = numpy.argsort(D)         # Legendre points
        x = D[i]
        w = 2*V[0,i]**2                   # Quadrature weights
        x = 0.5*((hi+lo) + (hi-lo)*x)
        w = 0.5*(hi-lo)*w



    elif floatmode == "mpfloat":

        efloat_mode="mpfloat"
        efloat = ef.EFloat(efloat_mode)

        T = efloat.fromArray(numpy.zeros([n,n]))

        for i in range(1,n):
            beta = .5 / efloat.sqrt(1.-(2*(i))**(-2.))   # 3-term recurrence coeffs

            # upper diagonal
            T[i,i-1] = beta

            # lower diagonal
            T[i-1,i] = beta

        if radau:
            # Eq. 2.4 of Gautschi, Gauss–Radau formulae for Jacobi and Laguerre weight functions, 2000
            if n == 1:
                T[-1,-1] = 1
            else:
                T[-1,-1] = 1 - 2*(n-1)**2 / (2*(n-1)*(2*(n-1)+1))

        D, V = efloat.eigh(T)                      # Eigenvalue decomposition

        N = len(D)

        i = numpy.argsort(D)         # Legendre points

        x = efloat.fromArray(numpy.zeros(N))
        w = efloat.fromArray(numpy.zeros(N))

        for i in range(len(D)):
            x[i] = D[i]

            w[i] = 2*V[0,i]**2

            x[i] = 0.5*((hi+lo) + (hi-lo)*x[i])
            w[i] = 0.5*(hi-lo)*w[i]

        x = numpy.array(x.tolist(), dtype=float)[:,0]
        w = numpy.array(w.tolist(), dtype=float)[:,0]

    else:
        raise Exception("Unsupported floatmode")

    return x, w
Exemplo n.º 10
0
class ELREXI:

    #
    # Constructor
    # See setup(...) for documentation on parameters
    #
    def __init__(self, efloat_mode="float"):
        self.efloat_mode = efloat_mode
        self.efloat = EFloat(efloat_mode)

        self.alphas = []
        self.betas = []
        self.unique_id_string = ""

    def setup(self,
              function_name,
              N: int,
              lambda_max_real: float = None,
              lambda_max_imag: float = None):
        """
        Setup coefficients for Cauchy contour integral coefficients
        using an ellipse with height given by lambda_max_imag
        and width given by lambda_max_real
        See doc/rexi/rexi_wit_laplace for details

        Args:
            N (int):
                Number of points on Cauchy contour.

        """

        self.alphas = []
        self.betas = []
        self.function_name = function_name
        self.N = N
        gamma = lambda_max_imag
        delta = lambda_max_real
        r = np.sqrt((1 - delta / gamma) / (1 + delta / gamma))
        d = r + (1.0 / r)
        self.fun = Functions(function_name, efloat_mode=self.efloat_mode)

        #print("Setting up ellipse:")
        #print("gamma: ", gamma)
        #print("delta: ", delta)
        #print("r:     ", r)

        if lambda_max_real == None or lambda_max_imag == None:
            raise Exception(
                "ELREXI: please provide max imag and real values of contour")

        c1 = (gamma * self.efloat.i / d)
        c2 = -(gamma / d)
        for j in range(N):
            theta_j = self.efloat.pi2 * (j + self.efloat.to(0.5)) / N

            # sampling position of support point
            sn = c1 * (r * self.efloat.exp(self.efloat.i * theta_j) +
                       (1.0 / r) * self.efloat.exp(-self.efloat.i * theta_j))

            #metric term
            sn_prime = c2 * (
                r * self.efloat.exp(self.efloat.i * theta_j) -
                (1.0 / r) * self.efloat.exp(-self.efloat.i * theta_j))

            self.betas.append(-self.efloat.i * self.fun.eval(sn) * sn_prime /
                              N)
            self.alphas.append(sn)

        coeffs = REXICoefficients()
        coeffs.alphas = self.alphas[:]
        coeffs.betas = self.betas[:]
        coeffs.gamma = 0
        coeffs.function_name = self.function_name

        self.unique_id_string = ""
        self.unique_id_string += self.function_name
        self.unique_id_string += "_N" + str(self.N)
        self.unique_id_string += "_im" + str(self.efloat.re(lambda_max_imag))
        self.unique_id_string += "_re" + str(self.efloat.re(lambda_max_real))

        coeffs.unique_id_string = self.getUniqueId()

        return coeffs

    def getUniqueId(self):
        return "ELREXI_" + self.unique_id_string
Exemplo n.º 11
0
class CIREXI:

    #
    # Constructor
    # See setup(...) for documentation on parameters
    #
    def __init__(self, efloat_mode="float"):
        self.efloat_mode = efloat_mode
        self.efloat = EFloat(efloat_mode)

        self.alphas = []
        self.betas = []
        self.unique_id_string = ""

    def setup(self,
              function_name,
              N: int,
              R: float = None,
              lambda_shift: complex = None,
              lambda_max_real: float = None,
              lambda_include_imag: float = None):
        self.alphas = []
        self.betas = []
        self.function_name = ""

        if lambda_shift != None:
            self.setup_shifted_circle(function_name,
                                      N=N,
                                      R=R,
                                      lambda_shift=lambda_shift)

        elif lambda_max_real != None:
            self.setup_limited_circle(function_name,
                                      N=N,
                                      lambda_max_real=lambda_max_real,
                                      lambda_include_imag=lambda_include_imag)

        else:
            self.setup_circle(function_name, N=N, R=R)

        coeffs = REXICoefficients()
        coeffs.alphas = self.alphas[:]
        coeffs.betas = self.betas[:]
        coeffs.gamma = 0
        coeffs.function_name = self.function_name

        coeffs.unique_id_string = self.getUniqueId()

        return coeffs

    def setup_shifted_circle(self, function_name, N: int, R: float,
                             lambda_shift: complex):
        """
		Setup coefficients for Cauchy contour integral coefficients
		using a shifted circle with the shift given by lambda_shift
		which fulfills the constraints given by lambda_*

		Args:
			N (int):
				Number of points on Cauchy contour.

			R (float):
				Radius of circle for Cauchy contour

			lambda_shift (complex):
	`			Shift of center of circle on complex plane
		"""

        self.function_name = function_name
        self.lambda_shift = lambda_shift

        self.fun = Functions(function_name, efloat_mode=self.efloat_mode)

        for j in range(N):
            theta_j = self.efloat.pi2 * (j + self.efloat.to(0.5)) / N

            # sampling position of support point
            pos = R * self.efloat.exp(self.efloat.i * theta_j)

            # shifted position
            gamma_j = pos + lambda_shift

            self.betas.append(-self.fun.eval(gamma_j) * pos / N)
            self.alphas.append(-gamma_j)

        self.unique_id_string = "shic"
        self.unique_id_string += "_" + function_name
        self.unique_id_string += "_" + str(N)
        self.unique_id_string += "_" + str(self.efloat.re(lambda_shift))
        self.unique_id_string += "_" + str(self.efloat.im(lambda_shift))

    def setup_circle(self, function_name, N: int, R: float):
        """
		Setup circle contour integral centered at origin

		Args:
			N (int):
				Number of quadrature poles

			R (float):
				Radius of circle
		"""

        self.setup_shifted_circle(function_name, N, R, 0.0)

        self.unique_id_string = "circ"
        self.unique_id_string += "_" + function_name
        self.unique_id_string += "_" + str(N)
        self.unique_id_string += "_" + str(lambda_max_real)
        self.unique_id_string += "_" + str(lambda_include_imag)

    def setup_limited_circle(self, function_name: str, N: int,
                             lambda_max_real: float,
                             lambda_include_imag: float):
        """
		Setup coefficients for Cauchy contour integral coefficients circle
		which fulfills the constraints given by lambda_*

		Args:
			N (int):
				Number of points on Cauchy contour.

			lambda_max_real (float):
				Maximum allowed real number on contour.

			lambda_include_imag (float):
				Include at least this imaginary value as part of the contour.
				Even, if the contour has to be enlarged
		"""

        # If the maximal real number is larger than the max to be included imaginary number, set a lower value for the max real number
        if lambda_max_real > lambda_include_imag:
            lambda_max_real = lambda_include_imag

        x0 = lambda_max_real
        xm = lambda_include_imag
        r = (x0 * x0 + xm * xm) / (2.0 * x0)
        center = lambda_max_real - r

        self.setup_shifted_circle(function_name, N, r, center)

        self.unique_id_string = "limc"
        self.unique_id_string += "_" + str(N)
        self.unique_id_string += "_" + function_name
        self.unique_id_string += "_" + str(lambda_max_real)
        self.unique_id_string += "_" + str(lambda_include_imag)

    def getUniqueId(self):
        return "CIREXI_" + self.unique_id_string
Exemplo n.º 12
0
 def setupFloatmode(self):
     self.efloat = ef.EFloat(self.floatmode, self.mpfloat_digits)
     self.floatmode = self.efloat.floatmode
Exemplo n.º 13
0
        new_alphas = []
        new_betas = []

        self.symmetric_reduction_applied = True
        if not '_betafilter' in self.unique_id_string:
            self.unique_id_string += '_betafilter'

        return

    def eval(self, x):
        retval = self.gamma

        for i in range(len(self.alphas)):
            retval += self.betas[i] / (x + self.alphas[i])

        return retval


if __name__ == "__main__":

    r = REXICoefficients()
    r.efloat = EFloat()
    r.gamma = 1e-12
    r.alphas.append(1j + 2.0)
    r.betas.append(3j + 4.0)

    r.write_file("/tmp/test.txt")

    r2 = r.toFloat()