Python相当于MATLAB的Legendre函数

时间:2014-11-21 12:16:49

标签: python matlab numpy polynomials

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

我尝试了NumPy implementation,但我找不到(或多或少)产生与the 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 个答案:

答案 0 :(得分:1)

好吧,我认为你将无法使用这个模块复制这些结果,因为通过名称来判断只处理legendre多项式(这些是图例中mu = 0的解决方案,也称为0阶解决方案)

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

在python中,你似乎正在做的是创建零一阶和二阶Legende多项式的组合

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

我希望这对你有用,如果我弄乱了,请告诉我

答案 1 :(得分:1)

@ user3684792感谢代码,但这并不是所需要的,例如cosdist通常是一个矩阵,因此sum(terms)是不够的(尽管很容易修复)。

根据您对Legrande多项式的注释和this定义,我自己尝试了。我最终得到的是这段代码。我可以问一下你的意见吗?

    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混为一谈。现在它应该是正确的

答案 2 :(得分:1)

SciPyassociated Legendre polynomials。它与MATLAB版本不同,但它应该提供您想要的大部分内容。

答案 3 :(得分:1)

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

from scipy import special

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

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