简体   繁体   中英

Laguerre polynomials in python using scipy, lack of convergence?

The laguerre polynomials don't seem to be converging at some orders as can be demonstrated by running the following code.

import numpy as np
from sympy import mpmath as mp
from scipy.special import genlaguerre as genlag
from sympy.mpmath import laguerre as genlag2
from matplotlib import pyplot as plt

def laguerre(x, r_ord, phi_ord, useArbitraryPrecision=False):
    if (r_ord < 30 and phi_ord < 30) and not useArbitraryPrecision:
        polyCoef = genlag(r_ord, phi_ord)
        out = np.polyval(polyCoef, x)
    else:
        fun = lambda arg: genlag2(r_ord, phi_ord, arg)
        fun2 = np.frompyfunc(genlag2, 3, 1)
        # fun2 = np.vectorize(fun)
        out = fun2(r_ord, phi_ord, x)
    return out

r_ord = 29
phi_ord = 29
f = lambda x, useArb : mp.log10(laguerre(x, 29, 29, useArb))
mp.plot(lambda y : f(y, True) - f(y, False), [0, 200], points = 1e3)
plt.show()

I was wondering if anyone knew what is going on or of any accuracy limitations of the scipy function? Do you recommend I simply use the mpmath function? At first I thought it might be that after a certain order it doesn't work but for (100, 100) it seems to be working just fine.

by running

mp.plot([lambda y : f(y, True), lambda y: f(y, False)], [0, 200], points = 1e3)

you get the following image where the discrepancy becomes pretty clear.

在此处输入图片说明

Any help appreciated.

Let me know if anything needs clarification.

Using polyval with high-order polynomials (about n > 20 ) is in general a bad idea, because evaluating polynomial using the coefficients (in power basis) will start giving large errors in floating point at high orders. The warning in the Scipy documentation tries to tell you that.

You should use scipy.special.eval_genlaguerre(r_ord, phi_ord, float(x)) instead of genlaguerre + polyval ; it uses a stabler numerical algorithm for evaluating the polynomial.

Instead of using scipy.special.eval_genlaguerre to evaluate a high-degree polynomial as pv suggested, you can also use numpy.polynomial.Laguerre as explained in the NumPy documentation .

Unfortunately, it doesn't seem to provide a function for generalized Laguerre polynomials.

import numpy as np
from numpy.polynomial import Laguerre
p = Laguerre([1, -2, 1])
x = np.arange(5)
p(x)

NumPy output: 0, 0.5, 2, 4.5, 8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM