简体   繁体   English

Python等同于MATLAB的Legendre函数

[英]Python equivalent of MATLAB's Legendre function

Currently, I am trying to analyze time series data with Python. 目前,我正在尝试使用Python分析时间序列数据。 As a guideline for doing so, I oriented myself on a MATLAB script that does pretty much everything I'd like to do. 作为这样做的指导,我将自己定位于MATLAB脚本,该脚本几乎可以完成我想做的所有事情。 So far it worked fine, but now I bumped into this Legendre polynomial that was used in that script. 到目前为止,它运行良好,但现在我碰到了该脚本中使用的Legendre多项式。

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的文档和Wikipedia都不对理解有很大帮助它。

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. 我需要用Python生成等效的代码。 Here's the code: 这是代码:

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的新手,因此我确信上面的内容可以得到改善。

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) 好的,我想您将很难使用此模块来复制这些结果,因为按名称判断仅处理勒让德多项式(这些是Legendre方程的解,其中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,但是在查看文档时,您的输入正在计算的Legendre函数的结果达到指定程度的顺序。

In python, what you seem to be doing is creating a composition of the zeroeth first and second order legendre polynomials 在python中,您似乎正在做的是创建零位一阶和二阶Legendre多项式的组合

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: 您可以在指定的点评估Legendre多项式:

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 我希望这对您有用,如果我搞砸了,请告诉我

@user3684792 Thanks for the code, but this is not exactly what is needed, eg cosdist is normally a matrix, so that sum(terms) would not suffice (easy fix though). @ user3684792感谢您提供的代码,但这并不是完全需要的,例如cosdist通常是一个矩阵,因此sum(terms)不足以满足(尽管很容易解决)。

Based on your comment and this definition of Legrande polynomials, I tried it myself. 基于您的评论和这个 Legrande多项式的定义,我没有尝试过自己。 What I ended up with is this code. 我最终得到的是这段代码。 May I ask for your opinion about it? 请问您对此有何看法?

    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. 如果cosdist只是一个整数,则此脚本给出的结果与您的结果相同。 What irritates me, is that these results are still somewhat different than those resulting from the Matlab code, ie the resulting array has even different dimensions. 令我感到恼火的是,这些结果仍然与Matlab代码产生的结果有些不同,即所得数组甚至具有不同的尺寸。 Thanks. 谢谢。 Edit: By accident, I confused m with order . 编辑:偶然地,我将morder混淆了。 Now it should be correct 现在应该是正确的

SciPy has the associated Legendre polynomials . SciPy具有关联的Legendre多项式 It isn't the same as the MATLAB version, but it should provide most of what you want. 它与MATLAB版本不同,但是应该提供您想要的大部分内容。

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. 对于我的应用程序,这非常有效-也许有些人也可以使用它。

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

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