Beispiel #1
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
Beispiel #2
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