def director_field_vectorized(self, k, x, jac=False): """ Returns the value of the vector field for a nonlinear class at a given point. args: k (int) : indexes which nonlinear class x (numpy.array) : (2,N) kwargs: jac: If True then returns the Jacobian of the vector-field too. returns: out1: ndarray (2,N) out2: ndarray (2,2,N) if jac==True """ from numpy.polynomial.legendre import legval2d, legder theta = legval2d(x[0] / self.width, x[1] / self.height, self.theta_coeffs[k]) out1 = np.array([np.cos(theta), np.sin(theta)]) if jac: dtheta_dx = legval2d(x[0] / self.width, x[1] / self.height, legder(self.theta_coeffs[k], axis=0)) / self.width dtheta_dy = legval2d(x[0] / self.width, x[1] / self.height, legder(self.theta_coeffs[k], axis=1)) / self.height N = x.shape[1] out2 = np.zeros((2, 2, N)) out2[0, 0, :] = -out1[1] * dtheta_dx out2[0, 1, :] = -out1[1] * dtheta_dy out2[1, 0, :] = out1[0] * dtheta_dx out2[1, 1, :] = out1[0] * dtheta_dy return out1, out2 return out1
def director_field(self, k, x, jac=False): """ Returns the value of the vector field for a nonlinear class. args: x: ndarray (2,) k: int kwargs: jac: If True then returns the Jacobian of the vector-field too. returns: out1: ndarray (2,) out2: ndarray (2,2) if jac==True """ from numpy.polynomial.legendre import legval2d, legder theta = legval2d(x[0] / self.width, x[1] / self.height, self.theta_coeffs[k]) #NOTE: Yes, I know this scaling seems off by a factor of 2. At the moment, this is correct. However, this should be refactored so that we use a scaling convention that is consistent with the rest of the code-base (e.g. posteriors.x_given_k out1 = np.array([np.cos(theta), np.sin(theta)]) if jac: dtheta_dx = legval2d(x[0] / self.width, x[1] / self.height, legder(self.theta_coeffs[k], axis=0)) / self.width dtheta_dy = legval2d(x[0] / self.width, x[1] / self.height, legder(self.theta_coeffs[k], axis=1)) / self.height out2 = np.zeros((2, 2)) out2[0, 0] = -out1[1] * dtheta_dx out2[0, 1] = -out1[1] * dtheta_dy out2[1, 0] = out1[0] * dtheta_dx out2[1, 1] = out1[0] * dtheta_dy return out1, out2 return out1
def __gradient(self, point_grid: ndarray) -> (NUMPY_TYPE, NUMPY_TYPE): coeffs_of_grad_x = legder(self.__c.mat / self.__scale.mat, axis=0) coeffs_of_grad_y = legder(self.__c.mat / self.__scale.mat, axis=1) sqrt_p = legval2d(*point_grid, self.__c.mat/self.__scale.mat) factor = 2.0 * self.__controller.N grad_x = factor * sqrt_p * legval2d(*point_grid, coeffs_of_grad_x) grad_y = factor * sqrt_p * legval2d(*point_grid, coeffs_of_grad_y) return self.__map.out(grad_x), self.__map.out(grad_y)
def hamiltonian(coefs, func=BASIS_FUNC, V=V, C=C): '''hamiltonian operator acting on wavefunction''' if func == 'legendre': ham = -C * L.legder(L.legder(coefs)) + V * L.Legendre(coefs) return ham elif func == 'fourier': ham = [V] + [(i**2) * C * coefs[i] for i in range(1, len(coefs))] return ham
def parallels_transitions(turbine, joints_parallel, joints_vel_parallel, joints_acc_parallel, times_parallel, step=.1, number_of_points=8.): """ Given all parallels solutions, i.e., joints solutions for all waypoints split in parallels (lists), this method computes cubic polynomials to interpolate the two points: end of a parallel - begin of the next parallel, in joint space, considering velocities. It will return the parallels and the computed transition paths between them. Obs.: This is taking too long. No improvements are being made since plates can be used on the transition part. Args: turbine: (@ref Turbine) turbine object joints_parallel: (float[m][n<SUB>i</SUB>][nDOF]) list of joints for all parallels times_parallel: (float[m][n<SUB>i</SUB>]) list of deltatimes for all parallels step: distance (meters) between points number_of_points: minimal number of points max_acc: maximum permitted acceleration (percentage) Returns: Modifies the current joints_parallel and times_parallel with the computed transitions. """ robot = turbine.robot for i in range(len(joints_parallel) - 1): joint_0 = joints_parallel[2 * i][-1] vel_0 = joints_vel_parallel[2 * i][-1] joint_1 = joints_parallel[2 * i + 1][0] vel_1 = joints_vel_parallel[2 * i + 1][0] c = mathtools.legn_path(3, [joint_0, joint_1], [vel_0, vel_1]) joints = [] joints_vel = [] joints_acc = [] times = [] dt = min([step, 1. / number_of_points]) for t in linspace(0, 1., max([1. / step, number_of_points])): joints.append(legendre.legval(t, c)) joints_vel.append(legendre.legval(t, legendre.legder(c, 1))) joints_acc.append(legendre.legval(t, legendre.legder(c, 2))) times.append(dt) joints = joints[1:-1] joints_vel = joints_vel[1:-1] joints_acc = joints_acc[1:-1] times_parallel[2 * i + 1][0] = times[-1] times = times[1:-1] joints_parallel.insert(2 * i + 1, joints) joints_vel_parallel.insert(2 * i + 1, joints_vel) joints_acc_parallel.insert(2 * i + 1, joints_acc) times_parallel.insert(2 * i + 1, times) return joints_parallel, joints_vel_parallel, joints_acc_parallel, times_parallel
def test_legder_axis(self): # check that axis keyword works c2d = np.random.random((3, 4)) tgt = np.vstack([leg.legder(c) for c in c2d.T]).T res = leg.legder(c2d, axis=0) assert_almost_equal(res, tgt) tgt = np.vstack([leg.legder(c) for c in c2d]) res = leg.legder(c2d, axis=1) assert_almost_equal(res, tgt)
def make_grid(self): import numpy as np from numpy.polynomial.legendre import legder, legroots, legval N = self._N self.NN = N + 1 L = self.L factor = L / 2 d1 = np.zeros((N + 1, N + 1)) cp = legder([0] * N + [1]) zg = np.hstack([-1.0, legroots(cp), 1.0]) P_N = legval(zg, [0] * N + [1]) with np.errstate(divide='ignore'): d1 = P_N[:, None] / (P_N[None, :] * (zg[:, None] - zg[None, :])) d1[np.diag_indices(N + 1)] = 0.0 d1[0, 0] = -N * (N + 1) / 4 d1[N, N] = +N * (N + 1) / 4 d2 = np.dot(d1, d1) self.zg = (zg + 1) * L / 2 + self.zmin self.d0 = np.eye(self.NN) self.d1 = d1 / factor self.d2 = d2 / factor**2 # Call other objects that depend on the grid for callback in self._observers: callback()
def Stormer_Verlet(x0, y0, x1, y1, n_steps, theta, V_scale, Delta_t=1.0): from numpy.polynomial.legendre import legder,legval2d theta_x = legder( theta, axis=0, m=1) theta_y = legder( theta, axis=1, m=1) x_pred = np.zeros(n_steps) y_pred = np.zeros(n_steps) x_pred[0],x_pred[1] = (x0,x1) y_pred[0],y_pred[1] = (y0,y1) for k in range(n_steps-2): x1,y1 = (x_pred[k+1],y_pred[k+1]) x0,y0 = (x_pred[k],y_pred[k]) V_x = legval2d( x1/V_scale[0], y1/V_scale[1], theta_x )/V_scale[0] V_y = legval2d( x1/V_scale[0], y1/V_scale[1], theta_y )/V_scale[1] x_pred[k+2] = 2*x1 - x0 - Delta_t**2 * V_x y_pred[k+2] = 2*y1 - y0 - Delta_t**2 * V_y return x_pred, y_pred
def Stormer_Verlet(x0, y0, x1, y1, n_steps, theta, V_scale, Delta_t=1.0): from numpy.polynomial.legendre import legder, legval2d theta_x = legder(theta, axis=0, m=1) theta_y = legder(theta, axis=1, m=1) x_pred = np.zeros(n_steps) y_pred = np.zeros(n_steps) x_pred[0], x_pred[1] = (x0, x1) y_pred[0], y_pred[1] = (y0, y1) for k in range(n_steps - 2): x1, y1 = (x_pred[k + 1], y_pred[k + 1]) x0, y0 = (x_pred[k], y_pred[k]) V_x = legval2d(x1 / V_scale[0], y1 / V_scale[1], theta_x) / V_scale[0] V_y = legval2d(x1 / V_scale[0], y1 / V_scale[1], theta_y) / V_scale[1] x_pred[k + 2] = 2 * x1 - x0 - Delta_t**2 * V_x y_pred[k + 2] = 2 * y1 - y0 - Delta_t**2 * V_y return x_pred, y_pred
def _getNodes(self): """ Computes Gauss-Lobatto integration nodes. Calculates the Gauss-Lobatto integration nodes via a root calculation of derivatives of the legendre polynomials. Note that the precision of float 64 is not guarantied. Copyright by Dieter Moser, 2014 Returns: np.ndarray: array of Gauss-Lobatto nodes """ M = self.num_nodes a = self.tleft b = self.tright roots = leg.legroots( leg.legder(np.array([0] * (M - 1) + [1], dtype=np.float64))) nodes = np.array(np.append([-1.0], np.append(roots, [1.0])), dtype=np.float64) nodes = (a * (1 - nodes) + b * (1 + nodes)) / 2 return nodes
def quad_custom(fun, n=10): P_n = [0 for i in range(1, n)] + [1] P_n_roots = leg.legroots(P_n) d_P_n = leg.legder(P_n) d_P_n_vals = leg.legval(P_n_roots, d_P_n) weights = 2 / ((1 - np.power(P_n_roots, 2)) * np.power(d_P_n_vals, 2)) result = np.sum(weights * fun(P_n_roots)) return result
def gaussian_latitudes(n): """Construct latitudes and latitude bounds for a Gaussian grid. Args: * n: The Gaussian grid number (half the number of latitudes in the grid. Returns: A 2-tuple where the first element is a length `n` array of latitudes (in degrees) and the second element is an `(n, 2)` array of bounds. """ if abs(int(n)) != n: raise ValueError('n must be a non-negative integer') nlat = 2 * n # Create the coefficients of the Legendre polynomial and construct the # companion matrix: cs = np.array([0] * nlat + [1], dtype=np.int) cm = legcompanion(cs) # Compute the eigenvalues of the companion matrix (the roots of the # Legendre polynomial) taking advantage of the fact that the matrix is # symmetric: roots = la.eigvalsh(cm) roots.sort() # Improve the roots by one application of Newton's method, using the # solved root as the initial guess: fx = legval(roots, cs) fpx = legval(roots, legder(cs)) roots -= fx / fpx # The roots should exhibit symmetry, but with a sign change, so make sure # this is the case: roots = (roots - roots[::-1]) / 2. # Compute the Gaussian weights for each interval: fm = legval(roots, cs[1:]) fm /= np.abs(fm).max() fpx /= np.abs(fpx).max() weights = 1. / (fm * fpx) # Weights should be symmetric and sum to two (unit weighting over the # interval [-1, 1]): weights = (weights + weights[::-1]) / 2. weights *= 2. / weights.sum() # Calculate the bounds from the weights, still on the interval [-1, 1]: bounds1d = np.empty([nlat + 1]) bounds1d[0] = -1 bounds1d[1:-1] = -1 + weights[:-1].cumsum() bounds1d[-1] = 1 # Convert the bounds to degrees of latitude on [-90, 90]: bounds1d = np.rad2deg(np.arcsin(bounds1d)) bounds2d = np.empty([nlat, 2]) bounds2d[:, 0] = bounds1d[:-1] bounds2d[:, 1] = bounds1d[1:] # Convert the roots from the interval [-1, 1] to latitude values on the # interval [-90, 90] degrees: latitudes = np.rad2deg(np.arcsin(roots)) return latitudes, bounds2d
def apply_H_legendre(self): '''This applies the Hamiltonian operator, utilizing a builtin capability of the numpy.polynomial.legendre module to get the second derivatives. Note that we have to "pad" the coefficients array with two zeros after taking the second derivative.''' #taking del^2 has never been easier! new_coefficients = L.legder(self.coefficients, 2) new_coefficients = list(new_coefficients) for i in range(2): new_coefficients.append(0) new_coefficients = np.array(new_coefficients) #what a pain! return (np.array(new_coefficients * (-self.c) + self.v * self.coefficients * self.period))
def evaluate_basis_derivative(self, x=None, i=0, k=0, output_array=None): if x is None: x = self.mesh(False, False) x = np.atleast_1d(x) v = self.evaluate_basis(x, i, output_array) if k > 0: D = np.zeros((self.N, self.N)) D[:-k, :] = leg.legder(np.eye(self.N), k) v = np.dot(v, D) return v
def test_legcubic_path(self): def asin(x): A = 2 w = pi / 4 return A * sin(w * x) def dasin(x): A = 2 w = pi / 4 return A * w * cos(w * x) def e(x): return exp(x) - 1 def de(x): return exp(x) p1 = array([asin(0), e(0)]) p2 = array([asin(1), e(1)]) dp1 = array([dasin(0), de(0)]) dp2 = array([dasin(1), de(1)]) c = mathtools.legcubic_path(p1, p2, dp1, dp2) legsol1 = legendre.legval(0, c) for i in range(len(p1)): self.assertAlmostEqual(legsol1[i], p1[i]) legsol2 = legendre.legval(1, c) for i in range(len(p2)): self.assertAlmostEqual(legsol2[i], p2[i]) legdsol1 = legendre.legval(0, legendre.legder(c)) for i in range(len(dp1)): self.assertAlmostEqual(legdsol1[i], dp1[i]) legdsol2 = legendre.legval(1, legendre.legder(c)) for i in range(len(dp2)): self.assertAlmostEqual(legdsol2[i], dp2[i]) self.assertEquals(legsol1.shape, p1.shape) self.assertEquals(legsol2.shape, p2.shape) self.assertEquals(legdsol1.shape, dp1.shape) self.assertEquals(legdsol2.shape, dp2.shape)
def evaluate_basis_derivative_all(self, x=None, k=0): if x is None: x = self.mesh(False, False) V = self.vandermonde(x) #assert self.N == V.shape[1] M = V.shape[1] if k > 0: D = np.zeros((M, M)) D[:-k, :] = leg.legder(np.eye(M), k) V = np.dot(V, D) return self._composite_basis(V)
def _compute_nodes(self): """Computes Gauss-Lobatto integration nodes. Calculates the Gauss-Lobatto integration nodes via a root calculation of derivatives of the legendre polynomials. Note that the precision of float 64 is not guarantied. """ roots = leg.legroots(leg.legder(np.array([0] * (self.num_nodes - 1) + [1], dtype=np.float64))) self._nodes = np.array(np.append([-1.0], np.append(roots, [1.0])), dtype=np.float64)
def legReconstructDerivative(freqs, locations, spectrum, numPts): """ :param freqs: :param locations: :param spectrum: :param numPts: :return: derivative of iFFT of the spectrum as an array with shape (Npts, Ncomponent) or (Ncomponent,) if 1-d """ deriv=leg.legder(spectrum, axis=0) return genericLegVal(locations, deriv)
def evaluate_basis_derivative_all(self, x=None, k=0, argument=0): if x is None: x = self.mesh(False, False) V = self.vandermonde(x) #assert self.N == V.shape[1] N, M = self.shape(False), self.shape(True) if k > 0: D = np.zeros((M, N)) D[:-k] = leg.legder(np.eye(M, N), k) V = np.dot(V, D) return self._composite_basis(V, argument=argument)
def director_field_vectorized(self, k, x, jac=False): """ Returns the value of the vector field for a nonlinear class at a given point. args: k (int) : indexes which nonlinear class x (numpy.array) : (2,N) kwargs: jac: If True then returns the Jacobian of the vector-field too. returns: out1: ndarray (2,N) out2: ndarray (2,2,N) if jac==True """ from numpy.polynomial.legendre import legval2d, legder theta = legval2d( x[0]/self.width, x[1]/self.height, self.theta_coeffs[k] ) out1 = np.array([np.cos(theta), np.sin(theta)]) if jac: dtheta_dx = legval2d( x[0]/self.width, x[1]/self.height, legder( self.theta_coeffs[k], axis=0) ) / self.width dtheta_dy = legval2d( x[0]/self.width, x[1]/self.height, legder( self.theta_coeffs[k], axis=1) ) / self.height N = x.shape[1] out2 = np.zeros((2,2,N)) out2[0,0,:] = -out1[1]*dtheta_dx out2[0,1,:] = -out1[1]*dtheta_dy out2[1,0,:] = out1[0]*dtheta_dx out2[1,1,:] = out1[0]*dtheta_dy return out1, out2 return out1
def GaussQuad(f, xi, xf, n, M): I = 0 c = np.append(np.zeros(M), 1) x = lg.legroots(c) w = 0 * x d = lg.legder(c) for i in range(len(x)): w[i] = 2. / ((1 - x[i]**2) * (lg.legval(x[i], d))**2) for i in range(M): I += w[i] * f(n, interval(x[i], xf, xi)) I *= 0.5 * (xf - xi) return I
def director_field(self, k, x, jac=False ): """ Returns the value of the vector field for a nonlinear class. args: x: ndarray (2,) k: int kwargs: jac: If True then returns the Jacobian of the vector-field too. returns: out1: ndarray (2,) out2: ndarray (2,2) if jac==True """ from numpy.polynomial.legendre import legval2d, legder theta = legval2d( x[0]/self.width, x[1]/self.height, self.theta_coeffs[k] ) out1 = np.array([np.cos(theta), np.sin(theta)]) if jac: dtheta_dx = legval2d( x[0]/self.width, x[1]/self.height, legder( self.theta_coeffs[k], axis=0) ) / self.width dtheta_dy = legval2d( x[0]/self.width, x[1]/self.height, legder( self.theta_coeffs[k], axis=1) ) / self.height out2 = np.zeros( (2,2) ) out2[0,0] = - out1[1]*dtheta_dx out2[0,1] = - out1[1]*dtheta_dy out2[1,0] = out1[0]*dtheta_dx out2[1,1] = out1[0]*dtheta_dy return out1, out2 return out1
def weights_roots(order, rules='Gauss-Lobatto'): c_leg = [1] if order == 0 else [i//order for i in xrange(order+1)] c_dleg = lgd.legder(c_leg) if rules == 'Gauss-Lobatto': xs = np.array( [-1] + list( lgd.legroots(c_dleg) ) + [1] ) ws = 2 / ( order * (order + 1) * (lgd.legval(xs, c_leg)**2) ) elif rules == 'Gauss-Legendre': xs = lgd.legroots(c_leg) ws = 2 / ( (1 - xs**2) * (lgd.legval(xs, c_dleg)**2) ) return xs, ws
def Hamiltonian_Legendre_polynomial(c, potential, domain, N): #potential is a constant in this case x = np.linspace(-domain / 2, domain / 2, N) delta_x = domain / (N - 1) #here, the normalized legendre polynomical has been used # for the nth polynomials, normalization constant is sqrt(2/(2n + 1)) #kinetic term K = np.zeros((N, N)) for ii in range(N): legen_left = np.zeros(N) legen_left[ii] = mt.sqrt((2 * ii + 1) / 2) for jj in range(N): deriva_array = np.zeros(N + 2) deriva_array[jj] = mt.sqrt((2 * jj + 1) / 2) legen_right_deriva = legen.legder(deriva_array, 2) #multiply them legen_multiply = legen.legmul(legen_left, legen_right_deriva) #integral legen_integral = legen.legint(legen_multiply) #calculate the matrix elements K[ii][jj] = legen.legval(domain / 2, legen_integral) - \ legen.legval(-domain / 2, legen_integral) #the S matrix, inside the [-1, 1] domain, the legendre ploynomial can be treatedas basis and satisfying <xi|xj> = delta ij, thus S matrix is a identity matrix S = np.zeros((N, N)) for ii in range(N): legen_left_S = np.zeros(N) legen_left_S[ii] = mt.sqrt((2 * ii + 1) / 2) legen_multiply_S = legen.legmul(legen_left_S, legen_left_S) legen_integral_S = legen.legint(legen_multiply_S) S[ii][ii] = legen.legval(domain / 2, legen_integral_S) - \ legen.legval(-domain / 2, legen_integral_S) K = K * -1 * c #because the potential is just a constant here, we can calculate the V matrix simply by multiply the matrix S a constant potential value V = potential * S ##divide the obtained Hamiltonian by the S matrix H = K + V return H
def jac_ode_function( xy, t, alpha, width, height, speed=1.0 ): """ returns velocity feild for input into odeint args: xy (np.ndarray) : shape = (2,) t (float): alpha: coefficients for angles returns: out (np.ndarray) : jacobian of velocity field, shape = (2,2) """ x = xy[0] y = xy[1] theta = legval2d( x / width, y / height, alpha ) theta_x = legval2d( x / width, y / height, legder( alpha, axis=0) ) / width theta_y = legval2d( x / width, y / height, legder( alpha, axis=1) ) / height out = np.zeros( (2,2) ) out[0,0] = - np.sin(theta)*theta_x out[0,1] = - np.sin(theta)*theta_y out[1,0] = np.cos(theta)*theta_x out[1,1] = np.cos(theta)*theta_y out *= speed return out
def jac_ode_function(xy, t, alpha, width, height, speed=1.0): """ returns velocity feild for input into odeint args: xy (np.ndarray) : shape = (2,) t (float): alpha: coefficients for angles returns: out (np.ndarray) : jacobian of velocity field, shape = (2,2) """ x = xy[0] y = xy[1] theta = legval2d(x / width, y / height, alpha) theta_x = legval2d(x / width, y / height, legder(alpha, axis=0)) / width theta_y = legval2d(x / width, y / height, legder(alpha, axis=1)) / height out = np.zeros((2, 2)) out[0, 0] = -np.sin(theta) * theta_x out[0, 1] = -np.sin(theta) * theta_y out[1, 0] = np.cos(theta) * theta_x out[1, 1] = np.cos(theta) * theta_y out *= speed return out
def test_legder(self) : # check exceptions assert_raises(ValueError, leg.legder, [0], .5) assert_raises(ValueError, leg.legder, [0], -1) # check that zeroth deriviative does nothing for i in range(5) : tgt = [0]*i + [1] res = leg.legder(tgt, m=0) assert_equal(trim(res), trim(tgt)) # check that derivation is the inverse of integration for i in range(5) : for j in range(2, 5) : tgt = [0]*i + [1] res = leg.legder(leg.legint(tgt, m=j), m=j) assert_almost_equal(trim(res), trim(tgt)) # check derivation with scaling for i in range(5) : for j in range(2, 5) : tgt = [0]*i + [1] res = leg.legder(leg.legint(tgt, m=j, scl=2), m=j, scl=.5) assert_almost_equal(trim(res), trim(tgt))
def test_legder(self) : # check exceptions assert_raises(ValueError, leg.legder, [0], .5) assert_raises(ValueError, leg.legder, [0], -1) # check that zeroth deriviative does nothing for i in range(5) : tgt = [0]*i + [1] res = leg.legder(tgt, m=0) assert_equal(trim(res), trim(tgt)) # check that derivation is the inverse of integration for i in range(5) : for j in range(2,5) : tgt = [0]*i + [1] res = leg.legder(leg.legint(tgt, m=j), m=j) assert_almost_equal(trim(res), trim(tgt)) # check derivation with scaling for i in range(5) : for j in range(2,5) : tgt = [0]*i + [1] res = leg.legder(leg.legint(tgt, m=j, scl=2), m=j, scl=.5) assert_almost_equal(trim(res), trim(tgt))
def gauss_lobatto_points(start, stop, num_points): r"""Get the node points for Gauss-Lobatto quadrature. Using :math:`n` points, this quadrature is accurate to degree :math:`2n - 3`. The node points are :math:`x_1 = -1`, :math:`x_n = 1` and the interior are :math:`n - 2` roots of :math:`P'_{n - 1}(x)`. Though we don't compute them here, the weights are :math:`w_1 = w_n = \frac{2}{n(n - 1)}` and for the interior points .. math:: w_j = \frac{2}{n(n - 1) \left[P_{n - 1}\left(x_j\right)\right]^2} This is in contrast to the scheme used in Gaussian quadrature, which use roots of :math:`P_n(x)` as nodes and use the weights .. math:: w_j = \frac{2}{\left(1 - x_j\right)^2 \left[P'_n\left(x_j\right)\right]^2} .. note:: This method is **not** generic enough to accommodate non-NumPy types as it relies on the :mod:`numpy.polynomial.legendre`. :type start: float :param start: The beginning of the interval. :type stop: float :param stop: The end of the interval. :type num_points: int :param num_points: The number of points to use. :rtype: :class:`numpy.ndarray` :returns: 1D array, the interior quadrature nodes. """ p_n_minus1 = [0] * (num_points - 1) + [1] inner_nodes = legendre.legroots(legendre.legder(p_n_minus1)) # Utilize symmetry about 0. inner_nodes = 0.5 * (inner_nodes - inner_nodes[::-1]) if start != -1.0 or stop != 1.0: # [-1, 1] --> [0, 2] --> [0, stop - start] --> [start, stop] inner_nodes = start + (inner_nodes + 1.0) * 0.5 * (stop - start) return np.hstack([[start], inner_nodes, [stop]])
def Legendre_polynomial_basis(c, potential, domain, N, wave_func): x = np.linspace(-domain / 2, domain / 2, N) #represent out wave function in the legendre polynomial basis wave_legen = legen.legfit(x, wave_func, N) #calculate H |bj>, where H = -c Lap + V #calculate -c Lap |bj> Hbj_first = -1 * c * legen.legder(wave_legen, 2) #calculate V|bj>, here, V is a constant Hbj_secod = potential * wave_legen Hbj = Hbj_first + Hbj_secod[0:N - 1] return Hbj
def get_vandermonde_basis_derivative(self, V, k=0): """Return k'th derivatives of basis as a Vandermonde matrix Parameters ---------- V : array of ndim = 2 Chebyshev Vandermonde matrix k : int k'th derivative """ assert self.N == V.shape[1] if k > 0: D = np.zeros((self.N, self.N)) D[:-k, :] = leg.legder(np.eye(self.N), k) V = np.dot(V, D) return self.get_vandermonde_basis(V)
def add_plot(X, lbl, clr, type='o'): Peq = pos_equilibrium(X) n = Peq.size for i in range(n): plt.plot(Peq[i, 0], 0, type, color=clr) c = [0] * (n + 2) c[n + 1] = 1 d = L.legder(c) P = L.leg2poly(d) P = mirror(P) Poly = np.poly1d(P) x = np.linspace(-1, 1, 100) y = Poly(x) plt.plot(x, y, label=lbl, color=clr)
def add_plot(X, lbl, clr, type='o'): Peq = Newton_Raphson(grad_E, Jacobian_E, X, 100, 1e-8) n = Peq.size for i in range(n): plt.plot(Peq[i, 0], 0, type, color=clr) c = [0] * (n + 2) c[n + 1] = 1 d = L.legder(c) P = L.leg2poly(d) P = mirror(P) Poly = np.poly1d(P) x = np.linspace(-1, 1, 100) y = Poly(x) plt.plot(x, y, label=lbl, color=clr)
def _getNodes(self): """ Copyright by Dieter Moser, 2014 Computes Gauss-Lobatto integration nodes. Calculates the Gauss-Lobatto integration nodes via a root calculation of derivatives of the legendre polynomials. Note that the precision of float 64 is not guarantied. """ M = self.num_nodes a = self.tleft b = self.tright roots = leg.legroots(leg.legder(np.array([0] * (M - 1) + [1], dtype=np.float64))) nodes = np.array(np.append([-1.0], np.append(roots, [1.0])), dtype=np.float64) nodes = (a * (1 - nodes) + b * (1 + nodes)) / 2 return nodes
def __accel__(t, vi, deg=[0]): """Equation for acceleration due to gravity. :t: current time :vi: current position and velocity vector :n: degrees of perturbation terms to use ([0] = 2-body) """ from numpy.polynomial.legendre import legval, legder # initialize solution vector v = np.zeros(len(vi)) # dr/dt = v v[:3] = vi[3:] # magnitude of position vector r = norm(vi[:3]) # sin(phi) = z/r sinphi = vi[2] / r xi = re / r # Common coefficients for Legendre polynomials and derivatives mult = [J[n] * xi**n if n in deg else 0 for n in xrange(max(deg) + 1)] # compute coefficients for Legendre polynomial evaluation cPn = (np.arange(max(deg) + 1) + 1) * mult # Legendre summation Pn = legval(sinphi, cPn) # Legendre derivative summation Pn_prime = legval(sinphi, legder(mult)) # common acceleration v[3:] = (mu / r**3) * (Pn + sinphi * Pn_prime) * vi[:3] # additive term for z-acceleration v[-1] -= (mu / r**3) * (r * Pn_prime) return v
def calculate_roots(deg): rez = [] for i in range(1, deg // 2 + deg % 2 + 1): x_0 = math.cos(math.pi * (4 * i - 1) / (4 * deg + 2)) x_k = x_0 coefs = np.zeros(i) coefs[i - 1] = 1 der_coefs = legndr.legder(coefs) x_k_1 = x_k - legndr.legval([x_k], coefs)[0] / legndr.legval( [x_k], der_coefs)[0] e = 2 / (deg * 10) while x_k_1 - x_k > e: temp = x_k_1 x_k_1 = x_k - legndr.legval([x_k], coefs)[0] / legndr.legval( [x_k], der_coefs)[0] x_k = temp rez.append(x_k) return rez
def __init__(self, n, k, a, m): self.k2 = 2 * k # Uniform grid points x = np.linspace(-1, 1, n) # Legendre Polynomials on grid self.V = legvander(x, m - 1) # Do QR factorization of Vandermonde for least squares self.Q, self.R = qr(self.V, mode='economic') I = np.eye(m) D = np.zeros((m, m)) D[:-self.k2, :] = legder(I, self.k2) # Legendre modal approximation of differential operator self.A = I - a * D # Store LU factors for repeated solves self.PLU = lu_factor(self.A[:-self.k2, self.k2:])
def weights(order): x = roots(order) w = np.empty(order) coef = [] for n in range(0, order+1): if(n == order): coef.append(1) else: coef.append(0) derivative_coefficients = leg.legder(coef) del coef[-1] del coef[-1] coef.append(1) for i in range(0, order): tmp = leg.Legendre(derivative_coefficients, domain=[-1, 1])(2*x[i] - 1) tmp2 = leg.Legendre(coef, domain=[-1, 1])(2.0*x[i] - 1) w[i] = 1/(order*tmp*tmp2) # Possibly some bug here, get a factor 2 different using mathematica return w
def get_basis(deg, dofset=None): # Legendre polynomials are used as the basis of polynomials. In the basis of # Legendre polynomials is row of eye polyset = np.eye(deg+1) if dofset is None: dofset = np.linspace(-1, 1, deg+1) # Reatange dofs to have external first dofset = np.r_[dofset[0], dofset[-1], dofset[1:-1]] # Compute the nodal matrix A = np.array([legval(dofset, base) for base in polyset]) # New coefficients B = np.linalg.inv(A) # Combine the basis according to new weights basis = [lambda x, c=c: legval(x, c) for c in B] # Check that the basis is nodal assert np.allclose(np.array([f(dofset) for f in basis]), polyset) # First deriv dbasis = [lambda x, c=legder(c): legval(x, c) for c in B] return basis, dbasis
def __init__(self,n,k,a,m): self.k2 = 2*k # Uniform grid points x = np.linspace(-1,1,n) # Legendre Polynomials on grid self.V = legvander(x,m-1) # Do QR factorization of Vandermonde for least squares self.Q,self.R = qr(self.V,mode='economic') I = np.eye(m) D = np.zeros((m,m)) D[:-self.k2,:] = legder(I,self.k2) # Legendre modal approximation of differential operator self.A = I-a*D # Store LU factors for repeated solves self.PLU = lu_factor(self.A[:-self.k2,self.k2:])
def legder(cs, m=1, scl=1) : from numpy.polynomial.legendre import legder return legder(cs, m, scl)
fl = lambdify(x, f, "numpy") ul = lambdify(x, u, "numpy") n = 32 domain = sys.argv[-1] if len(sys.argv) == 2 else "C1" # Chebyshev-Gauss nodes and weights points, w = leg.leggauss(n+1) # Chebyshev Vandermonde matrix V = leg.legvander(points, n) scl=1.0 # First derivative matrix zero padded to (n+1)x(n+1) D1 = np.zeros((n+1,n+1)) D1[:-1,:] = leg.legder(np.eye(n+1), 1, scl=scl) Vx = np.dot(V, D1) # Matrix of trial functions P = np.zeros((n+1,n+1)) P[:,0] = (V[:,0] - V[:,1])/2 P[:,1:-1] = V[:,:-2] - V[:,2:] P[:,-1] = (V[:,0] + V[:,1])/2 # Matrix of first derivatives of trial functions Px = np.zeros((n+1,n+1)) Px[:,0] = (Vx[:,0] - Vx[:,1])/2 Px[:,1:-1] = Vx[:,:-2] - Vx[:,2:] Px[:,-1] = (Vx[:,0] + Vx[:,1])/2
from scipy.interpolate import interp1d Nin = 10 # Number of data points in Nout = 50 # Number of points we want to project onto Nfine = Nin**2 # Number of points for plotting pretty Xin = np.linspace(-1,1,Nin) # The space of points Fin = np.cos(20*Xin)+np.sin(7*Xin) # Evaluate some fake data Xfine = np.linspace(-1,1,Nfine) # Linspace for plotting pretty Fspline = interp1d(Xin,Fin,kind='cubic') # A spline interpolation of the data Xout = np.linspace(-1,1,Nout-1) # Probably don't need this since we want to plot at the GLL nodes I = np.eye(Nout) # A hack for choosing the right polynomial orders zero = np.zeros(Nout-1) # Build our set of GLL nodes pts = legendre.legroots(legendre.legder(I[-1])) # GLL points Xi = [-1, list(pts), 1] Xi = np.hstack(Xi) #print "GLL Points:", Xi # Build the weight set weights = np.zeros([len(Xi)]) for i in range(len(Xi)-2): weights[i+1] = 2/((Nout)*(Nout-1)*(legendre.legval(Xi[i+1],I[-1]))**2) weights[0]=2.0/((Nout)*(Nout-1)) weights[-1]=weights[0] #print "GLL Weights:", weights # Calculate the norms norms = np.zeros(Nout)