Недавно я наткнулся на любопытную проблему, касающуюся scipy.special.legendre()
(scipy документацию). Полиномы Лежандра должны быть попарно ортогональны. Однако, когда я вычисляю их в диапазоне x=[-1,1]
и строю скалярное произведение двух полиномов разной степени, я не всегда получаю нуль или значения, близкие к нулю. Я неправильно истолковываю поведение функций? Далее я написал короткий пример, который производит скалярное произведение некоторых пар полиномов Лежандра:
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()
График отдельных полиномов на самом деле выглядит нормально:
Но если я вычисляю скалярные произведения вручную — умножаю два полинома Лежандра разной степени поэлементно и суммирую их (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
Скалярное произведение первого полинома на себя (как и следовало ожидать) равно единице, а половина других результатов почти равна нулю, но есть некоторые значения порядка 10e-3
, и я понятия не имею, почему. Я также попробовал функцию scipy.special.eval_legendre(n, x)
- тот же результат :-\
Это ошибка в функции scipy.special.legendre()
? Или я что-то не так делаю? Жду конструктивных ответов :-)
привет, Маркус
10^{-3} ~ 1/500
- это порядок величины ошибки, которую вы ожидаете с 500 баллами. - person pv.   schedule 16.09.2016scipy.integrate.quad
. Например.quad(lambda x: special.legendre(0)(x)*special.legendre(2)(x), a=-1, b=1)
- person Warren Weckesser   schedule 16.09.2016scipy.special.legendre
, чтобы привести к правильным ортогональным многочленам. Однако это приводит к различным значениям дисперсии при вычислении ковариационной матрицы в зависимости от того, сколько полиномов Лежандра я принимаю во внимание. Есть ли способ справиться с этой проблемой? - person Markus   schedule 16.09.2016S' = P.dot(S_emp).dot(P.T)
сP = inv(np.dot(G, G.T)).dot(G.T)
и сG
, содержащим полиномы Лежандра по столбцам. Для согласованного умножения матрицG
должно иметь длину100
, поэтому должны быть и полиномы Лежандра. - person Markus   schedule 16.09.2016