def compute_legendre_dot_product_derivatives(basis_dimension): """ Compute dot products of Legendre polynomials and their derivatives. Input: - basis_dimension: dict Give the number of basis functions for each state Outputs: - dot_product_12: ndarray Array containing the dot products of Legendre polynomials with their derivatives - dot_product_22: ndarray Array containing the dot products of Legendre polynomials derivatives """ # Compute the dimension of the problem dimension = np.sum([basis_dimension[elt] for elt in basis_dimension]) dot_product_12 = np.zeros([dimension, dimension]) dot_product_22 = np.zeros([dimension, dimension]) i, j = 0, 0 # Loop over states for state1 in basis_dimension: for state2 in basis_dimension: for k in range(basis_dimension[state1]): c_k = np.zeros(basis_dimension[state1]) c_k[k] += 1 # Create Legendre class for k-th polynomial c_k = Legendre(c_k, domain=[0, 1]) # Compute derivative c_k_deriv = c_k.deriv() for l in range(basis_dimension[state2]): c_l = np.zeros(basis_dimension[state2]) c_l[l] += 1 # Create Legendre class for k-th polynomial c_l = Legendre(c_l, domain=[0, 1]) # Compute derivative c_l_deriv = c_l.deriv() # Multiply polynomials product_12 = legmul(list(c_k), list(c_l_deriv)) product_22 = legmul(list(c_k_deriv), list(c_l_deriv)) # Create classes product_12 = Legendre(product_12, domain=[0, 1]) product_22 = Legendre(product_22, domain=[0, 1]) # Integrate int_product_12 = product_12.integ() int_product_22 = product_22.integ() # Evaluate at the endpoints _, traj_deriv_12 = int_product_12.linspace(n=2) _, traj_deriv_22 = int_product_22.linspace(n=2) # Deduce dot products dot_product_12[i + k, j + l] += traj_deriv_12[1] dot_product_12[i + k, j + l] -= traj_deriv_12[0] dot_product_22[i + k, j + l] += traj_deriv_22[1] dot_product_22[i + k, j + l] -= traj_deriv_22[0] j += basis_dimension[state2] j = 0 i += basis_dimension[state1] return dot_product_12, dot_product_22
def _reval_legendre(y, p): """Re-evaluate Legendre polynomials.""" P = np.zeros((p + 1, len(y))) dP = np.zeros((p + 1, 1, len(y))) P[0] = 1. - y P[1] = y dP[0][0] = -1. + 0. * y dP[1][0] = 1. + 0. * y x = 2. * y - 1. for n in range(2, p + 1): c = np.zeros(n) c[n - 1] = 1. s = Legendre(c).integ(lbnd=-1) scale = np.sqrt((2. * n - 1.) / 2.) P[n] = s(x) * scale dP[n][0] = 2 * s.deriv()(x) * scale return P, dP