简体   繁体   English

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

[英]Orthogonality issue in scipy's legendre polynomials

I recently stumbled upon a curious issue concerning the scipy.special.legendre() ( scipy documentation ). 我最近偶然发现了一个与scipy.special.legendre()scipy文档 )有关的奇怪问题。 The legendre polynomials should be pairwise orthogonal. 勒让德多项式应成对正交。 However, when I calculate them over a range x=[-1,1] and build the scalar product of two polynomials of different degree I don't always get zero or values close to zero. 但是,当我在x=[-1,1]范围内计算它们并建立两个不同度数的多项式的标量积时,我并不总是得到零或接近零的值。 Do I misinterpret the functions behaviour? 我会误解功能行为吗? In the following I have written a short example, which produces the scalar product of certain pairs of legendre polynomials: 在下面的代码中,我写了一个简短的示例,该示例产生了某些勒让德多项式对的标量积:

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()

The plot of the single polynomials actually looks fine: 单个多项式的图实际上看起来不错: 勒让德多项式从0到5

But if I calculate the scalar products manually – multiply two legendre polynomials of different degree elementwise and sum them up (the 500 is for normalization)... 但是,如果我手动计算标量积,则将两个不同度数的勒让德多项式相乘并求和(500用于归一化)...

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

... I get the following values as output: ...我得到以下值作为输出:

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

The scalar product of the first polynomial with itself is (as to be expected) equal one, and half of the other results are almost zero, but there are some values in the order of 10e-3 and I have no idea why. 第一个多项式与其自身的标量积(可以预期)等于1,其他结果的一半几乎为零,但是有些值在10e-3 ,我不知道为什么。 I also tried the scipy.special.eval_legendre(n, x) function – same result :-\\ 我也尝试了scipy.special.eval_legendre(n, x)函数–同样的结果:-\\

Is this a bug in the scipy.special.legendre() function? 这是scipy.special.legendre()函数中的错误吗? Or do I do something wrong? 还是我做错了什么? I am looking for constructive responds :-) 我正在寻找建设性的回应:-)

cheers, Markus 干杯,马库斯

As others have commented, you're going to get some error, since you're performing an in-exact integral. 正如其他人所评论的那样,由于要执行不精确的积分,因此您将得到一些错误。

But you can reduce the error by doing the integral as best you can. 但是您可以通过尽力而为来减少误差。 In your case, you can still improve your sampling points to make the integral more exact. 在您的情况下,您仍然可以改善采样点以使积分更精确。 When sampling, use the "midpoint" of the intervals instead of the edges: 采样时,请使用间隔的“中点”而不是边缘:

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

This gives quite a lot of improvement! 这带来了很大的改进! If I use the old sampling method: 如果我使用旧的采样方法:

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)

This gives: 这给出:

[[  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]]

Error terms are ~10^-3. 错误项为〜10 ^ -3。

But using the "midpoint sampling scheme", I get: 但是使用“中点采样方案”,我得到:

[[  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]]

Errors are now ~10^-5 or even 10^-6, which is much better! 现在的错误是〜10 ^ -5甚至10 ^ -6,这要好得多!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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