Python等价于MATLAB的勒让德函数。

时间:2022-06-09 21:21:48

Currently, I am trying to analyze time series data with Python. As a guideline for doing so, I oriented myself on a MATLAB script that does pretty much everything I'd like to do. So far it worked fine, but now I bumped into this Legendre polynomial that was used in that script.

目前,我正在尝试用Python来分析时间序列数据。作为这样做的指导方针,我以一个MATLAB脚本为导向,这个脚本几乎完成了我想做的所有事情。到目前为止,它运行良好,但现在我遇到了这个脚本中使用的勒让德多项式。

I tried the NumPy implementation of it, but I couldn't find a way that (more or less) yielded the same results as the MATLAB function.

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

Basically, this is what I'd like to know. How can I make my Python code give the same results as the MATLAB code?

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

As a small demonstration,

作为一个小的演示,

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

gives:

给:

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

Whereas my Python version of it goes like this: the way I tried it goes like so:

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

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

And yields:

和收益率:

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

I see a few things that are a bit weird, but unfortunately I have no clue about how to test for them, because this is the first time I heard of such a thing like Legendre polynomial and neither NumPy's documentation nor Wikipedia are a big help understanding it.

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

5 个解决方案

#1


3  

I just ran into this problem as well. Used this question as a starting point and came up with the following. Please note: I'm using the MATLAB function like so:

我也遇到了这个问题。用这个问题作为出发点,并提出以下几点。请注意:我使用的是MATLAB函数:

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

And I needed to generate the equivalent in Python. Here's the code:

我需要在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

I'm very new to Python, so I'm sure the above could be improved.

我对Python非常熟悉,所以我相信上面的内容可以改进。

#2


1  

Ok, well I think you will have trouble replicating these reslults using this module, as judging by the name only deals with the legendre polynomials (These are the solutions to the legendre equation where mu = 0, otherwise known as order 0 solutions)

好的,我认为你会很难用这个模块来复制这些reslults,根据这个名字来判断,只处理勒让德多项式(这些是让勒让德方程的解,在这里,mu = 0,也就是0阶解)

I don't know matlab, but looking at the documentation, your input is calculating the results of the legendre functions of up to the order of the degree specified.

我不知道matlab,但是看一下文档,你的输入是计算出了勒让德函数的结果,达到了指定的程度。

In python, what you seem to be doing is creating a composition of the zeroeth first and second order legendre polynomials

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

0*l_0 + 1*l_1 + 2*l_2

0*l_0 + 1*l_1 + 2*l_2。

you can evaluate the legendre polynomials at the points specified:

你可以在指定的点上计算勒让德多项式:

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

and you can verify that

你可以验证一下。

l0(0.5) == 0.5

I hope this is useful - feel free to ask more questions

我希望这是有用的-可以*的问更多的问题。

Edit:

编辑:

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

I hope this works for you, let me know if I have messed something up

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

#3


1  

@user3684792 Thanks for the code, but this is not exactly what is needed, e.g. cosdist is normally a matrix, so that sum(terms) would not suffice (easy fix though).

@user3684792谢谢你的代码,但这并不是我们需要的,例如cosdist通常是一个矩阵,所以这个和(terms)是不够的(虽然很简单)。

Based on your comment and this definition of Legrande polynomials, I tried it myself. What I ended up with is this code. May I ask for your opinion about it?

根据你的评论和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)

In case of cosdist is just an integer, this script gives the same results as yours. What irritates me, is that these results are still somewhat different than those resulting from the Matlab code, i.e. the resulting array has even different dimensions. Thanks. Edit: By accident, I confused m with order. Now it should be correct

如果cosdist只是一个整数,这个脚本给出的结果与您的相同。令我恼火的是,这些结果与Matlab代码产生的结果仍然有些不同,即结果数组的维度甚至是不同的。谢谢。编辑:偶然地,我把m和顺序弄混了。现在它应该是正确的。

#4


1  

SciPy has the associated Legendre polynomials. It isn't the same as the MATLAB version, but it should provide most of what you want.

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

#5


1  

I had the same problem and was successful with building the following:

我遇到了同样的问题,并成功地建立了以下几点:

from scipy import special

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

For my applications this works very well - maybe some of you can use this too.

对于我的应用程序来说,这很好——也许你们中的一些人也可以使用它。

#1


3  

I just ran into this problem as well. Used this question as a starting point and came up with the following. Please note: I'm using the MATLAB function like so:

我也遇到了这个问题。用这个问题作为出发点,并提出以下几点。请注意:我使用的是MATLAB函数:

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

And I needed to generate the equivalent in Python. Here's the code:

我需要在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

I'm very new to Python, so I'm sure the above could be improved.

我对Python非常熟悉,所以我相信上面的内容可以改进。

#2


1  

Ok, well I think you will have trouble replicating these reslults using this module, as judging by the name only deals with the legendre polynomials (These are the solutions to the legendre equation where mu = 0, otherwise known as order 0 solutions)

好的,我认为你会很难用这个模块来复制这些reslults,根据这个名字来判断,只处理勒让德多项式(这些是让勒让德方程的解,在这里,mu = 0,也就是0阶解)

I don't know matlab, but looking at the documentation, your input is calculating the results of the legendre functions of up to the order of the degree specified.

我不知道matlab,但是看一下文档,你的输入是计算出了勒让德函数的结果,达到了指定的程度。

In python, what you seem to be doing is creating a composition of the zeroeth first and second order legendre polynomials

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

0*l_0 + 1*l_1 + 2*l_2

0*l_0 + 1*l_1 + 2*l_2。

you can evaluate the legendre polynomials at the points specified:

你可以在指定的点上计算勒让德多项式:

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

and you can verify that

你可以验证一下。

l0(0.5) == 0.5

I hope this is useful - feel free to ask more questions

我希望这是有用的-可以*的问更多的问题。

Edit:

编辑:

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

I hope this works for you, let me know if I have messed something up

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

#3


1  

@user3684792 Thanks for the code, but this is not exactly what is needed, e.g. cosdist is normally a matrix, so that sum(terms) would not suffice (easy fix though).

@user3684792谢谢你的代码,但这并不是我们需要的,例如cosdist通常是一个矩阵,所以这个和(terms)是不够的(虽然很简单)。

Based on your comment and this definition of Legrande polynomials, I tried it myself. What I ended up with is this code. May I ask for your opinion about it?

根据你的评论和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)

In case of cosdist is just an integer, this script gives the same results as yours. What irritates me, is that these results are still somewhat different than those resulting from the Matlab code, i.e. the resulting array has even different dimensions. Thanks. Edit: By accident, I confused m with order. Now it should be correct

如果cosdist只是一个整数,这个脚本给出的结果与您的相同。令我恼火的是,这些结果与Matlab代码产生的结果仍然有些不同,即结果数组的维度甚至是不同的。谢谢。编辑:偶然地,我把m和顺序弄混了。现在它应该是正确的。

#4


1  

SciPy has the associated Legendre polynomials. It isn't the same as the MATLAB version, but it should provide most of what you want.

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

#5


1  

I had the same problem and was successful with building the following:

我遇到了同样的问题,并成功地建立了以下几点:

from scipy import special

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

For my applications this works very well - maybe some of you can use this too.

对于我的应用程序来说,这很好——也许你们中的一些人也可以使用它。