2

目前,我正在尝试使用 Python 分析时间序列数据。作为这样做的指导方针,我将自己定位在一个 MATLAB 脚本上,它几乎可以完成我想做的所有事情。到目前为止它工作得很好,但现在我碰到了那个脚本中使用的勒让德多项式。

我尝试了它的NumPy 实现,但我找不到(或多或少)产生与MATLAB function 相同结果的方法

基本上,这就是我想知道的。如何让我的 Python 代码给出与 MATLAB 代码相同的结果?

作为一个小示范,

    k= [0 1 1;1 1 0 ;0 0 1]
    legendre(2,k)

给出:

ans(:,:,1) =

-0.5000    1.0000   -0.5000
0         0         0
3.0000         0    3.0000


ans(:,:,2) =

1.0000    1.0000   -0.5000
     0         0         0
     0         0    3.0000


ans(:,:,3) =

1.0000   -0.5000    1.0000
     0         0         0
     0    3.0000         0

而我的 Python 版本是这样的:我尝试的方式是这样的:

    legendre = np.polynomial.legendre.Legendre([0,1,2])
    legendre(k)

和产量:

   array([[-1.,  3.,  3.],
   [ 3.,  3., -1.],
   [-1., -1.,  3.]])

我看到了一些有点奇怪的东西,但不幸的是我不知道如何测试它们,因为这是我第一次听说像勒让德多项式这样的东西,而且 NumPy 的文档和维基百科都对理解没有很大帮助它。

4

6 回答 6

4

我也遇到了这个问题。以这个问题为起点,提出了以下问题。请注意:我正在使用 MATLAB 函数,如下所示:

legendre(10,linspace(-1,1,10))

我需要在 Python 中生成等价物。这是代码:

import numpy as np
from scipy import special as sp

def legendre(N,X) :
    matrixReturn = np.zeros((N+1,X.shape[0]))
    for i in enumerate(X) :
        currValues = sp.lpmn(N,N,i[1])
        matrixReturn[:,i[0]] = np.array([j[N] for j in currValues[0]])
    return matrixReturn

我对 Python 很陌生,所以我确信上述内容可以改进。

于 2015-12-21T03:00:21.880 回答
2

好的,我认为使用此模块复制这些结果将有困难,因为从名称判断只处理legendre多项式(这些是legendre方程的解,其中mu = 0,也称为0阶解)

我不知道matlab,但是查看文档,您的输入是计算legendre 函数的结果,最多指定程度的顺序。

在python中,你似乎在做的是创建第零一阶和二阶勒让德多项式的组合

0*l_0 + 1*l_1 + 2*l_2

您可以在指定的点评估 Legendre 多项式:

l0 = np.polynomial.legendre.Legendre([0,1])

你可以验证

l0(0.5) == 0.5

我希望这很有用 - 请随时提出更多问题

编辑:

def coefficients(order):
    for i in range(1, order):
         base = np.zeros(order)
         base[i] = 1
         yield base

def a(n, m):
    return 1.0*(2*n+1) / ((n*(n+1))**m)

def g(const_dist, m, order):
     legendres = [np.polynomial.legendre.Legendre(n) for n in coefficients(order)]
     terms = [a(n+1,m)*legendres[n](const_dist) for n,_ in enumerate(legendres)]
     return sum(terms)


>>> g(0.4, 4, 6)
0.073845698737654328

我希望这对你有用,如果我搞砸了,请告诉我

于 2014-11-21T13:37:28.497 回答
2

@user3684792 感谢您的代码,但这并不完全是需要的,例如cosdist通常是一个矩阵,所以这sum(terms)还不够(虽然很容易修复)。

根据您的评论和Legrande多项式的定义,我自己尝试过。我最终得到的是这段代码。我可以问问你对此的看法吗?

    def P(n,x):
        if n == 0:
            return  1
        elif n==1:
            return  x
        elif n>1:
            return  (2*n-1)/n * x * P(n-1,x) - (n-1)/n * P(n-2,x)

    #some example data
    order = 4
    cosdist= np.array(((0.4,0.1),(-0.2,0.3)))
    m = 3
    dim1_cosdist, dim2_cosdist = cosdist.shape

    Gf = np.zeros((order, dim1_cosdist, dim2_cosdist))
    for n in range(1,order):
        Gf[n] = 1.0*(2*n+1) / ((n*(n+1))**m) * P(n,cosdist) 

    G = np.sum(Gf,axis = 0)

如果 cosdist 只是一个整数,则此脚本会给出与您相同的结果。令我恼火的是,这些结果仍然与 Matlab 代码产生的结果有些不同,即结果数组甚至具有不同的维度。谢谢。编辑:偶然地,我morder. 现在应该是正确的

于 2014-11-25T22:34:46.570 回答
2

SciPy相关的勒让德多项式。它与 MATLAB 版本不同,但它应该提供您想要的大部分内容。

于 2015-03-14T06:24:32.697 回答
2

我遇到了同样的问题,并成功构建了以下内容:

from scipy import special

def legendre(n,X) :
res = []
for m in range(n+1):
    res.append(special.lpmv(m,n,X))
return res

对于我的应用程序,这非常有效——也许你们中的一些人也可以使用它。

于 2017-08-19T18:59:59.187 回答
2
import numpy as np
from scipy.special import lpmv

def legendre(deg,x):
    return np.asarray([lpmv(i,deg,x) for i in range(deg+1)])

x=np.array([[0,1,1],[1,1,0],[0,0,1]])
legendre(2,x)

它给了你想要的。

于 2021-09-24T12:48:21.687 回答