def leggauss(n): """ For Legendre-Gaussian quadrature. Parameters ---------- n : int Returns ------- roots : list of mpf weights : list of mpf """ assert n >= 2 roots = [] weights = [] for k in range(n, n // 2 - 1, -1): # Using Tricomi approximation to get high precision estimates of roots. roots.append(polish_root(n, tricomi_root(n, k))) weights.append( 2 / legendre(n - 1, roots[-1]) * (roots[-1]**2 - 1) / n**2 / (roots[-1] * legendre(n, roots[-1]) - legendre(n - 1, roots[-1]))) # roots are antisymmetric about 0 for k in range(n // 2 - 2, -1, -1): roots.append(-roots[k]) weights.append(weights[k]) return roots, weights
def make_legendre_p_vals(): from mpmath import legendre l = range(5) x = linspace('-0.99', '0.99', 67) l, x = zip(*outer(l, x)) p = [legendre(*vals) for vals in zip(l, x)] return make_special_vals('legendre_p_vals', ('l', l), ('x', x), ('p', p))
def make_legendre_p_vals(): from mpmath import legendre l = list(range(5)) x = linspace('-0.99', '0.99', 67) l, x = zip(*outer(l, x)) p = [legendre(*vals) for vals in zip(l, x)] return make_special_vals('legendre_p_vals', ('l', l), ('x', x), ('p', p))
def polish_root(n, approx_root, n_iters=None, tol=None): """Use Newton method to get close to root. """ if n_iters is None: tol = 10**(-mp.dps + 5) n_iters = mp.dps dx = 1. oldRoot = approx_root while abs(dx) > tol: newRoot = ( oldRoot - legendre(n, oldRoot) * (oldRoot**2 - 1) / n / (oldRoot * legendre(n, oldRoot) - legendre(n - 1, oldRoot))) dx = newRoot - oldRoot oldRoot = newRoot return newRoot else: oldRoot = approx_root for i in range(n_iters): newRoot = ( oldRoot - legendre(n, oldRoot) * (oldRoot**2 - 1) / n / (oldRoot * legendre(n, oldRoot) - legendre(n - 1, oldRoot))) oldRoot = newRoot return newRoot
def main(): print(__doc__) x = symbols('x') # a numpy array we can apply the ufuncs to grid = np.linspace(-1, 1, 1000) # set mpmath precision to 20 significant numbers for verification mpmath.mp.dps = 20 print("Compiling legendre ufuncs and checking results:") # Let's also plot the ufunc's we generate plot1 = Plot(visible=False) for n in range(6): # Setup the SymPy expression to ufuncify expr = legendre(n, x) print("The polynomial of degree %i is" % n) pprint(expr) # This is where the magic happens: binary_poly = ufuncify(x, expr) # It's now ready for use with numpy arrays polyvector = binary_poly(grid) # let's check the values against mpmath's legendre function maxdiff = 0 for j in range(len(grid)): precise_val = mpmath.legendre(n, grid[j]) diff = abs(polyvector[j] - precise_val) if diff > maxdiff: maxdiff = diff print("The largest error in applied ufunc was %e" % maxdiff) assert maxdiff < 1e-14 # We can also attach the autowrapped legendre polynomial to a sympy # function and plot values as they are calculated by the binary function g = implemented_function('g', binary_poly) plot1[n] = g(x), [200] print( "Here's a plot with values calculated by the wrapped binary functions") plot1.show()
def main(): print(__doc__) x = symbols('x') # a numpy array we can apply the ufuncs to grid = np.linspace(-1, 1, 1000) # set mpmath precision to 20 significant numbers for verification mpmath.mp.dps = 20 print("Compiling legendre ufuncs and checking results:") # Let's also plot the ufunc's we generate for n in range(6): # Setup the SymPy expression to ufuncify expr = legendre(n, x) print("The polynomial of degree %i is" % n) pprint(expr) # This is where the magic happens: binary_poly = ufuncify(x, expr) # It's now ready for use with numpy arrays polyvector = binary_poly(grid) # let's check the values against mpmath's legendre function maxdiff = 0 for j in range(len(grid)): precise_val = mpmath.legendre(n, grid[j]) diff = abs(polyvector[j] - precise_val) if diff > maxdiff: maxdiff = diff print("The largest error in applied ufunc was %e" % maxdiff) assert maxdiff < 1e-14 # We can also attach the autowrapped legendre polynomial to a sympy # function and plot values as they are calculated by the binary function plot1 = plt.pyplot.plot(grid, polyvector, hold=True) print("Here's a plot with values calculated by the wrapped binary functions") # plt.pyplot.show() pltshow(plt)
def eval(self, z): return mpmath.legendre(1, z)
def f81(x): # legendre_P3 return mpmath.legendre(3, x)
def f80(x): # legendre_P2 return mpmath.legendre(2, x)
def f79(x): # legendre_P1 return mpmath.legendre(1, x)
def func(channel): channell = [] for i in range(0,len(channel)): channell.append(float(mpmath.legendre(degree,channel[i]))) return numpy.asarray(channell)
def roots_legendre(n): """ Compute the roots of the Legendre polynomial, and quadrature weights. Warning: not tested beyond n=21. Examples -------- >>> import mpmath >>> mpmath.mp.dps = 40 >>> from mpsci.fun import roots_legendre >>> roots, weights = roots_legendre(7) >>> roots [mpf('-0.9491079123427585245261896840478512624007709'), mpf('-0.7415311855993944398638647732807884070741476'), mpf('-0.405845151377397166906606412076961463347382'), mpf('0.0'), mpf('0.405845151377397166906606412076961463347382'), mpf('0.7415311855993944398638647732807884070741476'), mpf('0.9491079123427585245261896840478512624007709')] >>> weights [mpf('0.1294849661688696932706114326790820183285874'), mpf('0.2797053914892766679014677714237795824869251'), mpf('0.3818300505051189449503697754889751338783651'), mpf('0.4179591836734693877551020408163265306122449'), mpf('0.3818300505051189449503697754889751338783651'), mpf('0.2797053914892766679014677714237795824869251'), mpf('0.1294849661688696932706114326790820183285874')] """ n = operator.index(n) if n < 1: raise ValueError('n must be a positive integer.') if n == 1: return [mpmath.mp.zero], [mpmath.mpf(2)] elif n == 2: x = 1 / mpmath.sqrt(3) w = mpmath.mp.one return [-x, x], [w, w] elif n == 3: x = mpmath.sqrt('0.6') wx = mpmath.mpf('5/9') w0 = mpmath.mpf('8/9') return [-x, mpmath.mp.zero, x], [wx, w0, wx] approx_roots = [_root_approx(n, k) for k in range(1, n // 2 + 1)] with mpmath.extradps(5): roots = [ mpmath.findroot(lambda x: mpmath.legendre(n, x), x0) for x0 in approx_roots ] derivs = [ mpmath.diff(lambda x: mpmath.legendre(n, x), root) for root in roots ] weights = [ 2 / ((1 - root**2) * deriv**2) for root, deriv in zip(roots, derivs) ] if n & 1: z = mpmath.mp.zero root0 = [z] deriv = mpmath.diff(lambda x: mpmath.legendre(n, x), z) weight0 = [2 / deriv**2] else: root0 = [] weight0 = [] return ([-r for r in roots] + root0 + roots[::-1], weights + weight0 + weights[::-1])
import sympy as sp sp.init_printing() #%% v = sp.symbols('v', real=True, positive=True) gamma = 1 / sp.sqrt(1 - v**2) #%% x = sp.sqrt(v**2 + 1 / gamma**2) sp.simplify(x) #%% from mpmath import legendre import numpy as np import matplotlib.pyplot as plt plt.style.use('seaborn') from mpmath import * f = lambda x: legendre(2, x) plot(f) nprint(polyroots(taylor(f, 0, 2)[::-1])) print(np.sqrt(1 / 3))
def leg_poly(value): """Legendre polynomial :math:`P_n(x)`.""" return mpmath.legendre(num_points - 1, value)