Laguerre polynomials in python using scipy, lack of convergence?

痞子三分冷 提交于 2019-12-11 22:21:05

问题


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.


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/26478362/laguerre-polynomials-in-python-using-scipy-lack-of-convergence

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!