scipy的legendre多项式中的正交性问题

时间:2016-09-16 18:19:04

标签: python scipy polynomials orthogonal

我最近偶然发现了一个关于scipy.special.legendre()scipy documentation)的奇怪问题。 legendre多项式应该是成对正交的。但是,当我在范围x=[-1,1]上计算它们并构建两个不同程度的多项式的标量乘积时,我不会总是得到零或接近零的值。我是否误解了函数行为? 在下面我写了一个简短的例子,它产生某些legendre多项式对的标量积:

from __future__ import print_function, division
import numpy as np 
from scipy import special
import matplotlib.pyplot as plt

# create range for evaluation
x = np.linspace(-1,1, 500)

degrees = 6
lp_array = np.empty((degrees, len(x)))

for n in np.arange(degrees):
    LP = special.legendre(n)(x)
    # alternatively:
    # LP = special.eval_legendre(n, x)
    lp_array[n, ] = LP
    plt.plot(x, LP, label=r"$P_{}(x)$".format(n))

plt.grid()
plt.gca().set_ylim([-1.1, 1.1])
plt.legend(fontsize=9, loc="lower right")
plt.show()

单个多项式的图实际上看起来很好: Legendre polynomials from degree 0 to 5

但如果我手动计算标量乘积 - 将两个不同度数的legendre多项式乘以元素并求它们(500用于归一化)......

for i in range(degrees):
    print("0vs{}: {:+.6e}".format(i, sum(lp_array[0]*lp_array[i])/500))

...我得到以下值作为输出:

0vs0: +1.000000e+00
0vs1: -5.906386e-17
0vs2: +2.004008e-03
0vs3: -9.903189e-17
0vs4: +2.013360e-03
0vs5: -1.367795e-16

第一个多项式与其自身的标量乘积(预期)等于1,其他结果的一半几乎为零,但有一些值为10e-3,我没有想法为什么。我也尝试了scipy.special.eval_legendre(n, x)函数 - 结果相同: - \

这是scipy.special.legendre()函数中的错误吗?或者我做错了什么?我正在寻找建设性的回应: - )

欢呼声, 马库斯

1 个答案:

答案 0 :(得分:0)

正如其他人所评论的那样,您将会出现一些错误,因为您正在执行不完整的积分。

但是你可以尽可能地通过积分来减少误差。在您的情况下,您仍然可以改善采样点,使积分更精确。采样时,使用" midpoint"间隔而不是边缘:

x = np.linspace(-1, 1, nx, endpoint=False)
x += 1 / nx   # I'm adding half a sampling interval
              # Equivalent to x += (x[1] - x[0]) / 2

这提供了很多改进!如果我使用旧的抽样方法:

nx = 500
x = np.linspace(-1, 1, nx)

degrees = 7
lp_array = np.empty((degrees, len(x)))

for n in np.arange(degrees):
    LP = special.eval_legendre(n, x)
    lp_array[n, :] = LP

np.set_printoptions(linewidth=120, precision=1)
prod = np.dot(lp_array, lp_array.T) / x.size
print(prod)

这给出了:

[[  1.0e+00  -5.7e-17   2.0e-03  -8.5e-17   2.0e-03  -1.5e-16   2.0e-03]
 [ -5.7e-17   3.3e-01  -4.3e-17   2.0e-03  -1.0e-16   2.0e-03  -1.1e-16]
 [  2.0e-03  -4.3e-17   2.0e-01  -1.3e-16   2.0e-03  -1.0e-16   2.0e-03]
 [ -8.5e-17   2.0e-03  -1.3e-16   1.4e-01  -1.2e-16   2.0e-03  -1.0e-16]
 [  2.0e-03  -1.0e-16   2.0e-03  -1.2e-16   1.1e-01  -9.6e-17   2.0e-03]
 [ -1.5e-16   2.0e-03  -1.0e-16   2.0e-03  -9.6e-17   9.3e-02  -1.1e-16]
 [  2.0e-03  -1.1e-16   2.0e-03  -1.0e-16   2.0e-03  -1.1e-16   7.9e-02]]

错误条件是~10 ^ -3。

但是使用"中点采样方案",我得到:

[[  1.0e+00  -2.8e-17  -2.0e-06  -3.6e-18  -6.7e-06  -8.2e-17  -1.4e-05]
 [ -2.8e-17   3.3e-01  -2.8e-17  -4.7e-06  -2.7e-17  -1.1e-05  -4.1e-17]
 [ -2.0e-06  -2.8e-17   2.0e-01  -5.7e-17  -8.7e-06  -2.3e-17  -1.6e-05]
 [ -3.6e-18  -4.7e-06  -5.7e-17   1.4e-01  -2.1e-17  -1.4e-05  -5.3e-18]
 [ -6.7e-06  -2.7e-17  -8.7e-06  -2.1e-17   1.1e-01   1.1e-17  -2.1e-05]
 [ -8.2e-17  -1.1e-05  -2.3e-17  -1.4e-05   1.1e-17   9.1e-02   7.1e-18]
 [ -1.4e-05  -4.1e-17  -1.6e-05  -5.3e-18  -2.1e-05   7.1e-18   7.7e-02]]

错误现在是~10 ^ -5甚至10 ^ -6,这要好得多!