Ejemplo n.º 1
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
Ejemplo n.º 2
0
	def __init__(
		self,
		floatmode = None,
		**kwargs
	):
		self.efloat = ef.EFloat(floatmode)
		self.basis_function_name = "gaussianorig"

		self.setup(floatmode = floatmode, **kwargs)
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
        fun = Functions(self.function_name, efloat_mode='float')

        target_value = fun.eval(0)

        rescale = target_value / val

        self.betas = [i * rescale for i in self.betas]

        self.unique_id_string += "_nrm"

    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()
Ejemplo n.º 5
0
 def setupFloatmode(self):
 	self.efloat = ef.EFloat(self.floatmode, self.mpfloat_digits)
 	self.floatmode = self.efloat.floatmode
Ejemplo n.º 6
0
    def __init__(self, fafcoeffs):
        #		if not isinstance(fafcoeffs, FAFCoefficients):
        #			raise TypeError("Invalid type for fafcoeffs")

        self.efloat = ef.EFloat()

        self.function_name = fafcoeffs.function_name
        self.function_scaling = fafcoeffs.function_scaling

        if self.efloat.floatmode == 'mpfloat':
            import mpmath as mp
            # Set numerical threshold to half of precision
            #self.epsthreshold = self.efloat.pow(10, -mp.mp.dps/2)
            #self.epsthreshold = self.efloat.pow(10, -mp.mp.dps/2)
            self.epsthreshold = 1e-10
        else:
            self.epsthreshold = 1e-10

        # Gaussian basis function, original formulation from Terry's paper 2015
        if self.function_name == 'gaussianorig':

            def fun(x):
                x = x * self.function_scaling
                return self.efloat.exp(
                    -(x * x) /
                    (4.0 * self.function_scaling * self.function_scaling)
                ) / self.efloat.sqrt(4.0 * self.efloat.pi)

            self.fun = fun

            self.is_real_symmetric = True
            self.is_complex_conjugate_symmetric = True  # 0 imag

        # Gaussian basis function, simplified exp(-x*x) formulation
        elif self.function_name == 'gaussianopti':

            def fun(x):
                x = x * self.function_scaling
                return self.efloat.exp(-x * x)

            self.fun = fun

            self.is_real_symmetric = True
            self.is_complex_conjugate_symmetric = True

        # Diffusion
        elif self.function_name == 'expx':

            def fun(x):
                return self.efloat.exp(x)

            self.fun = fun

            self.is_real_symmetric = False
            self.is_complex_conjugate_symmetric = False

        # Exponential integrator: phi0
        elif self.function_name == 'phi0':

            def fun(x):
                return self.efloat.exp(self.efloat.i * x)

            self.fun = fun

            if fafcoeffs.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

        #
        # Exponential integrator: phi1
        #
        # \phi_1(z) = \frac{e^z - 1}{z}
        #
        # http://www.wolframalpha.com/input/?i=(exp(i*x)-1)%2F(i*x)
        #
        elif self.function_name == 'phi1':
            #
            # Cope with singularity at x=0
            # Note that this is only important for the approximation
            #
            def fun(x):
                K = self.efloat.i * x

                if abs(x) < self.epsthreshold:
                    # L'hopital (or written like that)
                    # Use LH: 1 times on (exp(x)-1.0)/(x)
                    return 1.0
                else:
                    return (self.efloat.exp(K) - 1.0) / K

            self.fun = fun

            if fafcoeffs.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

        #
        # Exponential integrator: phi2
        #
        # Recurrence formula (See Hochbruck, Ostermann, Exponential Integrators, Acta Numerica, Equation (2.11))
        #
        # \phi_{n+1}(z) = \frac{ \phi_n(z) - \phi_n(0) }{z}
        #
        # \phi_2(z) = \frac{e^z - 1 - z}{z^2}
        #
        # http://www.wolframalpha.com/input/?i=(exp(i*x)-1-i*x)%2F(i*x*i*x)
        #
        elif self.function_name == 'phi2':
            #
            # Cope with singularity at x=0
            # Note that this is only important for the approximation
            #
            def fun(x):
                K = self.efloat.i * x
                if abs(x) < self.epsthreshold:
                    # Use LH: 2 times on (exp(x)-1.0-x)/(x*x) => 1.0/2.0
                    return self.efloat.to(0.5)
                else:
                    return (self.efloat.exp(K) - self.efloat.to(1.0) -
                            K) / (K * K)

            self.fun = fun

            if fafcoeffs.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

        #
        # Exponential integrator: phi3
        #
        elif self.function_name == 'phi3':
            # Cope with singularity at x=0
            def fun(x):
                K = self.efloat.i * x
                if abs(x) < self.epsthreshold:
                    # Use LH: 3 times on exp(x)/(x*x*x) - 1.0/(x*x*x) - 1.0/(x*x) - 1.0/(2.0*x)
                    return self.efloat.to(1.0 / (2.0 * 3.0))
                else:
                    return (self.efloat.exp(K) - self.efloat.to(1.0) - K -
                            K * K) / (K * K * K)

            self.fun = fun

            if fafcoeffs.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 == 'ups1':
            #
            # Setup \upsilon_1 for EDTRK4
            # See document notes_on_time_splitting_methods.lyx
            #
            def fun(x):
                K = self.efloat.i * 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.fun = fun

            if fafcoeffs.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 == 'ups2':
            #
            # Setup \upsilon_2 for EDTRK4
            # See document notes_on_time_splitting_methods.lyx
            #
            def fun(x):
                K = self.efloat.i * 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.fun = fun

            if fafcoeffs.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 == 'ups3':
            #
            # Setup \upsilon_3 for EDTRK4
            # See document notes_on_time_splitting_methods.lyx
            #
            def fun(x):
                K = self.efloat.i * 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.fun = fun

            if fafcoeffs.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 basis function " + str(self.function_name))
            sys.exit(1)
Ejemplo n.º 7
0
def main():
	# double precision
	floatmode = 'float'

	# multiprecision floating point numbers
	#floatmode = 'mpfloat'


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

	max_error = efloat.to(1e-10)
	#max_error = None
	max_error_double_precision = max_error
	#max_error_double_precision = None

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

	for merge in [False, True]:
		for half in [False, True]:

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

			rexi = REXI(
				N = M,
				h = h,

				ratgauss_load_original_ratgaussian_poles = True,
				function_name = "phi0",

				reduce_to_half = half,
				floatmode = floatmode,
				merge = merge
			)

			if False:
				print("alphas:")
				for i in range(len(rexi.alpha)):
					print(str(i)+": "+str(rexi.alpha[i]))
				print("")

				print("betas:")
				for i in range(len(rexi.beta)):
					print(str(i)+": "+str(rexi.beta[i]))
				print("")

			print("")
			print("*"*80)
			print("* N: "+str(len(rexi.alpha)))
			print("* h: "+str(h))
			print("* half: "+str(half))
			print("* merge: "+str(merge))
			print("*"*80)

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


			""" CONTINUE """
			continue
			""" CONTINUE """


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

			rexi = REXI(
				ratgauss_load_original_ratgaussian_poles = True,

				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 = REXI(
				N = M,
				h = h,

				max_error = max_error,
				max_error_double_precision = max_error_double_precision,
				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()


			print("*"*80)
			print("* REXI coefficients with optimized mu (if found)")
			print("*"*80)

			rexi = REXI(
				N = M,
				h = h,

				max_error = max_error,
				max_error_double_precision = max_error_double_precision,
				ratgauss_basis_function_spacing = 1.0,
				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()

		#for function_name in ["phi0", "phi1", "phi2"]:
		for function_name in []:

			print("*"*80)
			print("* Testing REXI for "+function_name)
			print("*"*80)

			test_max = M*h-efloat.pi
			test_min = -test_max

			rexi = REXI(
				test_min = test_min,
				test_max = test_max,

				max_error = max_error,
				max_error_double_precision = max_error_double_precision,
				ratgauss_basis_function_spacing = 1.0,
				reduce_to_half = False,

				basis_function_name = "rationalcplx",
				function_name = function_name,

				floatmode = floatmode
			)

			print("*"*80)
			print("* Coefficient file")
			print("*"*80)
			print("Filename: "+rexi.fafcoeffs.filename)
			print("")
			print("*"*80)
			print("Running tests...")
			rexi.runTests()
			print("")
Ejemplo n.º 8
0
            b = self.efloat.re(self.approx_fun(x))

            e = abs(a - b)
            #print("Error at "+str(float(x))+": "+str(float(e)))
            maxerror = max(e, maxerror)

        print("Max error: " + str(maxerror))
        print("Max error (float): " + str(float(maxerror)))


if __name__ == "__main__":

    ef.default_floatmode = 'mpfloat'

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

    ##################################################
    ##################################################
    ##################################################

    print("")
    h = 0.1
    M = 64

    print("*" * 80)
    print("Approx of Phi0 (Original REXI coefficients)")
    print("*" * 80)
    phi0 = REXIGaussianPhi0(gaussphi0_N=M, gaussphi0_basis_function_spacing=h)

    phi0.runTests()
Ejemplo n.º 9
0
	def process_args(self, argv, avoid_efloat_update = False):
		def toString(value):
			if value == '-':
				return None

			return value

		def toStringArray(value):
			if value == '-':
				return []

			return value.split(',')

		def toFloat(value):
			if value == '-':
				return None

			return self.efloat.to(value)

		def toInt(value):
			if value == '-':
				return None

			return int(value)


		self.args_i = 1

		efloat_updated = False

		while self.args_i < len(argv):
			self.args_value = None

			if self.argsInt("mpfloat_digits", argv):
				self.mpfloat_digits = self.args_value

				if not avoid_efloat_update:
					efloat_updated = True
				continue

			if self.argsInt("N", argv):
				self.N = toInt(self.args_value)
				continue

			if self.argsFloat("max_error", argv):
				self.max_error = self.args_value
				continue

			if self.argsFloat("max_error_double_precision", argv):
				self.max_error_double_precision = self.args_value
				continue

			if self.argsString("function_name", argv):
				self.function_name = self.args_value
				continue

			if self.argsFloat("function_scaling", argv):
				self.function_scaling = self.args_value
				continue

			if self.argsBool("function_complex", argv):
				self.function_complex = self.args_value
				continue

			if self.argsString("basis_function_name", argv):
				self.basis_function_name = self.args_value
				continue

			if self.argsFloat("basis_function_spacing", argv):
				self.basis_function_spacing = self.args_value
				continue

			if self.argsFloat("basis_function_scaling", argv):
				self.basis_function_scaling = self.args_value
				continue

			if self.argsFloat("basis_function_rat_shift", argv):
				self.basis_function_rat_shift = self.args_value
				continue

			if self.argsString("optimizer_method", argv):
				self.optimizer_method = self.args_value
				continue

			if self.argsStringArray("optimizer_vars", argv):
				self.optimizer_vars = self.args_value
				continue

			if self.argsBool("optimizer_opti_double_precision", argv):
				self.optimizer_opti_double_precision = self.args_value
				continue

			if self.argsString("floatmode", argv):
				self.floatmode = self.args_value

				if not avoid_efloat_update:
					efloat_updated = True
				continue

			if self.argsInt("gen_os_samples_per_unit", argv):
				self.gen_os_samples_per_unit = self.args_value
				continue

			if self.argsString("gen_mainsetup", argv):
				self.gen_mainsetup = self.args_value
				continue

			if self.argsString("gen_solver_method", argv):
				self.gen_solver_method = self.args_value
				continue


			#
			# testing
			#
			if self.argsInt("test_samples_per_unit", argv):
				self.test_samples_per_unit = self.args_value
				continue

			if self.argsFloat("test_min", argv):
				self.test_min = self.args_value
				continue

			if self.argsFloat("test_max", argv):
				self.test_max = self.args_value
				continue

			print("Invalid option "+argv[self.args_i])
			sys.exit(1)

		if efloat_updated:
			self.efloat = ef.EFloat(self.floatmode, self.mpfloat_digits)
			self.process_args(argv, True)
Ejemplo n.º 10
0
	def load_coefficients_file(self, filename, avoid_efloat_update = False):

		self.reset()

		def toString(value):
			if value == '-' or value == 'None':
				return None

			return value

		def toStringArray(value):
			if value == '-' or value == 'None':
				return []

			return value.split(',')

		def toFloat(value):
			if value == '-' or value == 'None':
				return None

			return self.efloat.to(value)

		def toInt(value):
			if value == '-' or value == 'None':
				return None

			return int(value)

		def toBool(value):
			if value == '-' or value == 'None':
				return None

			if value == '1':
				return True
			elif value == '0':
				return False

			raise Exception("Unknown boolean value "+value)



		self.filename = filename

		content = open(filename).readlines()

		efloat_updated = False

		max_weight_len = 0
		for c in content:
			c = c.replace('\n', '')

			stra = '# mpfloat_digits '
			if c[0:len(stra)] == stra:
				if c[len(stra):] == 'None':
					self.mpfloat_digits = None
				else:
					self.mpfloat_digits = toInt(c[len(stra):])

				if not avoid_efloat_update:
					efloat_updated = True

				continue

			stra = '# floatmode '
			if c[0:len(stra)] == stra:
				self.floatmode = c[len(stra):]

				if not avoid_efloat_update:
					efloat_updated = True

			stra = '# max_error '
			if c[0:len(stra)] == stra:
				self.max_error = toFloat(c[len(stra):])
				continue

			stra = '# max_error_double_precision '
			if c[0:len(stra)] == stra:
				self.max_error_double_precision = toFloat(c[len(stra):])
				continue

			stra = '# function_name '
			if c[0:len(stra)] == stra:
				self.function_name = c[len(stra):]
				continue

			stra = '# function_scaling '
			if c[0:len(stra)] == stra:
				self.function_scaling = toFloat(c[len(stra):])
				continue

			stra = '# function_complex '
			if c[0:len(stra)] == stra:
				self.function_complex = toBool(c[len(stra):])
				continue

			stra = '# basis_function_name '
			if c[0:len(stra)] == stra:
				self.basis_function_name = c[len(stra):]
				continue

			stra = '# basis_function_spacing '
			if c[0:len(stra)] == stra:
				self.basis_function_spacing = toFloat(c[len(stra):])
				continue

			stra = '# basis_function_scaling '
			if c[0:len(stra)] == stra:
				self.basis_function_scaling = toFloat(c[len(stra):])
				continue

			stra = '# basis_function_rat_shift '
			if c[0:len(stra)] == stra:
				self.basis_function_rat_shift = toFloat(c[len(stra):])
				continue

			stra = '# gen_os_samples_per_unit '
			if c[0:len(stra)] == stra:
				self.gen_os_samples_per_unit = toInt(c[len(stra):])
				continue

			stra = '# gen_mainsetup '
			if c[0:len(stra)] == stra:
				self.gen_mainsetup = c[len(stra):]
				continue

			stra = '# gen_os_min '
			if c[0:len(stra)] == stra:
				self.gen_os_min = toFloat(c[len(stra):])
				continue

			stra = '# gen_os_max '
			if c[0:len(stra)] == stra:
				self.gen_os_max = toFloat(c[len(stra):])
				continue

			stra = '# gen_solver_method '
			if c[0:len(stra)] == stra:
				self.gen_solver_method = c[len(stra):]
				continue

			stra = '# optimizer_method '
			if c[0:len(stra)] == stra:
				self.optimizer_method = c[len(stra):]
				continue

			stra = '# optimizer_vars '
			if c[0:len(stra)] == stra:
				self.optimizer_vars = c[len(stra):].split(',')
				continue

			stra = '# optimizer_opti_double_precision '
			if c[0:len(stra)] == stra:
				self.optimizer_opti_double_precision = toBool(c[len(stra):])
				continue

			stra = '# test_samples_per_unit '
			if c[0:len(stra)] == stra:
				self.test_samples_per_unit = int(c[len(stra):])
				continue

			stra = '# test_min '
			if c[0:len(stra)] == stra:
				self.test_min = toFloat(c[len(stra):])
				continue

			stra = '# test_max '
			if c[0:len(stra)] == stra:
				self.test_max = toFloat(c[len(stra):])
				continue

			if c[0] == '#':
				# ignore the rest
				continue

			nums = c.split('\t')
			self.weights_str.append(nums)

			if len(nums) != 2:
				print("ERROR in file "+filename+" with line:")
				print(c)
				sys.exit(1)

			max_weight_len = max(max_weight_len, len(nums[0]), len(nums[1]))

		self.N = len(self.weights_str)

#		if floatmode == 'mpfloat':
#			if mp.mp.dps < max_weight_len:
#				print("WARNING: mp.dps accuracy is smaller than input values")

		for w in self.weights_str:
			self.weights.append([self.efloat.to(w[0]), self.efloat.to(w[1])])
			self.weights_cplx.append(self.efloat.to(w[0]) + self.efloat.i*self.efloat.to(w[1]))

		self.x0s = self.compute_basis_support_points()

		if efloat_updated:
			self.efloat = ef.EFloat(self.floatmode, self.mpfloat_digits)
			# reload coefficients
			self.load_coefficients_file(filename, True)

		return True