def eval_hermite(xi, alpha): assert xi.shape[1] == len(alpha) P = np.zeros((xi.shape[0], len(alpha))) for i in range(len(alpha)): p = orthpol.OrthogonalPolynomial(alpha[i], rv=st.norm()) P[:,i] = p(xi[:,i])[:,0] return np.prod(P, axis = 1)
def find_bsdo_ncap(J, domain, nof_coefficients, min_ncap=10000, step_ncap=1000, max_ncap=60000, stop_abs=1e-10, stop_rel=1e-10, threshold=1e-15): """ See get_bsdo_from_convergence method """ assert 0 < min_ncap < max_ncap assert step_ncap > 0 poly = orthpol.OrthogonalPolynomial(nof_coefficients - 1, left=domain[0], right=domain[1], wf=J, ncap=min_ncap) last_alpha, last_beta = np.array(poly.alpha), np.array(poly.beta) for ncap in range(min_ncap+step_ncap, max_ncap+step_ncap, step_ncap): poly = orthpol.OrthogonalPolynomial(nof_coefficients - 1, left=domain[0], right=domain[1], wf=J, ncap=ncap) curr_alpha, curr_beta = np.array(poly.alpha), np.array(poly.beta) if check_array_convergence(last_alpha, last_beta, curr_alpha, curr_beta, stop_abs, stop_rel, threshold=threshold): return ncap last_alpha, last_beta = last_alpha, last_beta print('Did not reach convergence, use maximum ncap = ' + str(max_ncap)) return max_ncap
def get_monic_recurrence(nof_coefficients, support, wf, ncap): """ Calculates two-point coefficients(alpha, beta) for monic polynomials using py-orthpol :param nof_coefficients: Number of coefficients to calculate :param support: Support of the orthognal polynomials :param wf: Weight function for the inner product :param ncap: Used by py-orthpol to determine the accuracy for the calculation of the coefficients coefficients. Must be <= 60000. A larger ncap results in greater accuracy at the cost of runtime. :return: Tuple of lists (alpha, beta) of length nof_coefficients each """ # First positional argument of OrthogonalPolynomial is actually the order of the polynomial to generate # OrthogonalPolynomial actually generates one additional coefficient (if order 2 was selected, it would # generate coefficients alpha_0, alpha_1 and alpha_2 for example!) poly = orthpol.OrthogonalPolynomial(nof_coefficients-1, left=support[0], right=support[1], wf=wf, ncap=ncap) return np.array(poly.alpha), np.array(poly.beta)
def get_bsdo(J, domain, nof_coefficients, orthpol_ncap=None): """ Computes chain bsdo coefficients (TEDOPA coefficients, see Chin et al., J. Math. Phys. 51, 092109 (2010)) using monic orthogonal polynomial recurrence :param J: Spectral density of the bath :param domain: Domain (support) of the spectral density :param nof_coefficients: Number of coefficients to be calculated :param orthpol_ncap: Accuracy parameter for orthpol (internal discretization parameter). If set None a default of 60000 is used. :return: c0 (System-Bath coupling), omega (Bath energies), t (bath-bath couplings) """ if orthpol_ncap is None: orthpol_ncap = 60000 poly = orthpol.OrthogonalPolynomial(nof_coefficients - 1, left=domain[0], right=domain[1], wf=J, ncap=orthpol_ncap) alpha, beta = np.array(poly.alpha), np.array(poly.beta) return np.sqrt(beta[0]), alpha, np.sqrt(beta[1:])
3/18/2014 """ import orthpol import math import numpy as np import matplotlib.pyplot as plt import scipy.stats # The desired degree degree = 4 # The first way of doing it is write down the random variable: rv = scipy.stats.norm() # Construct it: p = orthpol.OrthogonalPolynomial(degree, rv=rv) # An orthogonal polynomial is though of as a function. # Here is how to get the number of inputs and outputs of that function print 'Number of inputs:', p.num_input print 'Number of outputs:', p.num_output # Test if the polynomials are normalized (i.e., their norm is 1.): print 'Is normalized:', p.is_normalized # Get the degree of the polynomial: print 'Polynomial degree:', p.degree # Get the alpha-beta recursion coefficients: print 'Alpha:', p.alpha print 'Beta:', p.beta # The following should print a description of the polynomial print str(p) # Now you can evaluate the polynomial at any points you want: X = np.linspace(-2., 2., 100)
3/18/2014 """ import orthpol import math import numpy as np import matplotlib.pyplot as plt # The desired degree degree = 4 # The first way of doing it is by directly supplying the weight function. wf = lambda x: 1. / np.sqrt(1. - x) # Construct it: p = orthpol.OrthogonalPolynomial(degree, left=-1., right=1., # Domain wf=wf) # An orthogonal polynomial is though of as a function. # Here is how to get the number of inputs and outputs of that function print('Number of inputs:', p.num_input) print('Number of outputs:', p.num_output) # Test if the polynomials are normalized (i.e., their norm is 1.): print('Is normalized:', p.is_normalized) # Get the degree of the polynomial: print('Polynomial degree:', p.degree) # Get the alpha-beta recursion coefficients: print('Alpha:', p.alpha) print('Beta:', p.beta) # The following should print a description of the polynomial print(str(p)) # Now you can evaluate the polynomial at any points you want:
""" import orthpol import math import numpy as np import matplotlib.pyplot as plt # The desired degree degree = 4 # The first way of doing it is by directly supplying the weight function. wf = lambda (x): np.exp(-x) # Construct it: p = orthpol.OrthogonalPolynomial( degree, left=0, right=np.inf, # Domain wf=wf) # An orthogonal polynomial is though of as a function. # Here is how to get the number of inputs and outputs of that function print 'Number of inputs:', p.num_input print 'Number of outputs:', p.num_output # Test if the polynomials are normalized (i.e., their norm is 1.): print 'Is normalized:', p.is_normalized # Get the degree of the polynomial: print 'Polynomial degree:', p.degree # Get the alpha-beta recursion coefficients: print 'Alpha:', p.alpha print 'Beta:', p.beta # The following should print a description of the polynomial print str(p)
def recurrenceCoefficients(n, lb, rb, j, g, ncap=60000): """ Calculate recurrence coefficients for given spectral density Recurrence coeffcients for an arbitrary measure are defined as follows. Given some measure :math:`d\mu(x)`, which defines the set :math:`\\{\\pi_n(x)\\in \\mathbb{P}_n,n=0,1,2,\\ldots\\}` of monic orthogonal polynomials with respect to the measure, the following recurrence relation holds. .. math:: \\pi_{k+1}(x)=(x- \\alpha_k)\\pi_k(x)-\\beta_k\\pi_{k-1}(x), \\quad k=0,1,2... where :math:`\\pi_{-1}(x)\\equiv 0`, and the recurrence coefficients are: .. math:: \\alpha_k=\\frac{\\langle x \\pi_k,\pi_k\\rangle}{\\langle \\pi_k,\\pi_k\\rangle}, \\quad \\beta_k=\\frac{\\langle \\pi_k,\\pi_k\\rangle}{\\langle \\pi_{k-1},\\pi_{k-1}\\rangle}. The TEDOPA mapping for a given spectral density relies on calculating the recurrence coefficients with respect to the measure :math:`d\mu(x)=h^2(x)dx`, where :math:`J(\\omega)=\\pi h^2[g^{-1}(\\omega)] \\frac{dg^{-1}(\\omega)}{d\\omega}` and :math:`g(x) = gx`. Thus, this function first calculates the function :math:`h^2(x)` from :math:`J(\\omega)` and then calls py-orthpol package to find the recurrence coefficients. For more details, see Journal of Mathematical Physics 51, 092109 (2010); doi: 10.1063/1.3490188 and ACM Trans. Math. Softw. 20, 21-62 (1994); doi: 10.1145/174603.174605 Note that the input `j` must be a python lambda function representing the spectral density :math:`J(\omega)` Args: n (int): Number of recurrence coefficients required. g (float): Constant g, assuming that for J(omega) it is g(omega)=g*omega. lb (float): Left bound of interval on which J is defined. rb (float): Right bound of interval on which J is defined. j (types.LambdaType): :math:`J(\omega)` defined on the interval (lb, rb) ncap (int): Number internally used by py-orthpol to determine the accuracy with which the recurrence coefficients are calculated. Must be >n and <=60000. Between 10000 and 60000 recommended, the higher the number the higher the accuracy and the longer the execution time. (Default value = 60000) Returns: list[list[float], list[float]]: A list of two lists, each with the respective recurrence coefficients :math:`\{\\alpha_i: i = 1,2,\\dots,n\}` and :math:`\{\\beta_i: i = 1,2,\\dots,n\}` defined above. """ # It would also be possible to give lists of J(omega) and intervals as input # if the py-orthpol package was changed accordingly, adding the quadrature # points obtained there. But that turned out to return coefficients which # were too inaccurate for our purposes. # Also the procedure does not work for ncap > 60000, it would return wrong # values. n must be < ncap for orthpol to work # ToDo: Check if ncap <= 60000 is system dependent or holds everywhere if ncap > 60000: raise ValueError("ncap <= 60000 is not fulfilled") if n > ncap: raise ValueError("n must be smaller than ncap.") lb, rb, h_squared = _j_to_hsquared(func=j, lb=lb, rb=rb, g=g) p = orth.OrthogonalPolynomial(n, left=lb, right=rb, wf=h_squared, ncap=ncap) return p.alpha, p.beta