python:集成分段函数

python:集成分段函数,python,numpy,scipy,numerical-integration,Python,Numpy,Scipy,Numerical Integration,我想分段积分一个定义好的函数,它乘以勒让德多项式。 不幸的是,我找不到如何使用x的第n个勒让德多项式。当n=1,…,50时,我想积分x的每个勒让德多项式,所以我设置了n=np.arange(1,51,1) 然后我会返回一些u(x),前50项通过勒让德多项式展开分段函数 编辑1: 如果不能做到这一点,我可以用罗德里格斯公式来计算第n个勒让德多项式。然而,当我在Python中寻找计算n阶导数时,却找不到任何有用的东西 P_n(x) = \frac{1}{2^n n!}\frac{d^n}{dx^n}

我想分段积分一个定义好的函数,它乘以勒让德多项式。 不幸的是,我找不到如何使用x的第n个勒让德多项式。当
n=1,…,50
时,我想积分x的每个勒让德多项式,所以我设置了
n=np.arange(1,51,1)

然后我会返回一些
u(x)
,前50项通过勒让德多项式展开分段函数

编辑1:

如果不能做到这一点,我可以用罗德里格斯公式来计算第n个勒让德多项式。然而,当我在Python中寻找计算n阶导数时,却找不到任何有用的东西

P_n(x) = \frac{1}{2^n n!}\frac{d^n}{dx^n}(x^2 - 1)^n
因此,如果有人知道如何在Python中实现这样的方案,那么这是一个选项

P_n(x) = \frac{1}{2^n n!}\frac{d^n}{dx^n}(x^2 - 1)^n
编辑2:

根据萨洛·卡斯特罗的回答,我有:

import numpy as np
from scipy.integrate import quad

def f(x, coef):
    global p
    p = np.polynomial.legendre.Legendre(coef=coef)
    if 0 <= x <= 1:
        return 1*p(x)
    if -1 <= x <= 0:
        return -1*p(x)

c = []
for n in range(1, 51):
    c.append((2. * n + 1.) / 2. * quad(f, -1, 1, args=range(1,n+1))[0])

def g(x)
    return sum(c * p(x) for n in range(1, 51))
将numpy导入为np
从scipy.integrate导入四元组
定义f(x,coef):
全局p
p=np.多项式.勒让德.勒让德(coef=coef)

如果0如果我正确理解了你的问题,你想计算f(x)*Ln(x)的积分,其中f(x)是一个分段函数,你用python函数定义。我假设你对这个特殊的阶跃函数不感兴趣

可以使用系数参数的单位矩阵获得勒让德多项式的值

import numpy as np
import matplotlib

x = np.linspace(-1, 1, 201)

L = np.polynomial.legendre.legval(x, np.identity(50))

plt.plot(x, L.T)

然后,可以使用正交进行积分。使用高斯-勒让德求积可能更有效,因为勒让德多项式的积分对于Ln(x)是精确的,其中n小于求积大小

import numpy as np    
from numpy.polynomial.legendre import leggauss, legval

def f(x):
    if 0 <= x <= 1:
        return 1
    if -1 <= x <= 0:
        return -1

# of course you could write a vectorized version of
# this particular f(x), but I assume you have a more
# general piecewise function
f = np.vectorize(f)

deg = 100
x, w = leggauss(deg) # len(x) == 100

L = np.polynomial.legendre.legval(x, np.identity(deg))
# Sum L(xi)*f(xi)*wi
integral = (L*(f(x)*w)[None,:]).sum(axis=1)

c = (np.arange(1,51) + 0.5) * integral[1:51]

x_fine = np.linspace(-1, 1, 2001) # 2001 points
Lfine = np.polynomial.legendre.legval(x_fine, np.identity(51))

# sum_1_50 of c(n) * Ln(x_fine)
cLn_sum = (c[:,None] * Lfine[1:51,:]).sum(axis=0)
将numpy导入为np
从numpy.polynomy.legendre导入leggauss,legval
def f(x):

如果0您可以进行如下集成:

import numpy as np
from scipy.integrate import quad

def f(x, coef):
    n = coef[-1]
    p = (2*n+1)/2.*np.polynomial.legendre.Legendre(coef=coef)
    if 0 <= x <= 1:
        return 1*p(x)
    if -1 <= x <= 0:
        return -1*p(x)

c = []
for n in range(1, 51):
    c.append(quad(f, -1, 1, args=range(1,n+1))[0])

有些东西没写出来。第一个系数应该是
1.5
,但这会打印
0,5,7,4.5,…
,而且,由于我忘了输入(2.*n+1.)/2,您会得到一些稍微不同的结果。在我的第一篇帖子中整合了前面的内容。所以我有
c.append((2.*n+1.)/2.*quad(f,-1,1,args=range(1,n+1))[0])
这是积分
n
?如果是这样,那就是问题所在。我需要集成
x
实际上,它是将
x
-1
集成到
+1
。(参见这里的
quad
文档)[被积函数在我的答案中是错误的,现在我修正了它,它给出了
c
的预期结果……如何绘制
sum(范围(1,51)内n的c*p(x))
其中
p(x)
是勒让德多项式还是n阶?L的行包含L(x)从第一行的L0开始。你求和并绘制它们。我遇到的问题是我们没有一个n来求和,所以我怎么能求和?我真的不理解“我们没有一个n来求和”。L的第n行代表Ln(x)的值,其中每列对应于不同的x值。即,L[n,I]==Ln(x[I]).我修改了答案,以显示如何用numpy计算这个和。你也可以只写一个循环。在这一点上,我对你要完成的工作有点困惑,但我希望这能回答你的问题。当然,你可以用更细的x间距重新计算L。有两种方法。你可以增加I的度数积分,这将增加正交点。你也可以用更细的间距重新计算L,这是我在上面做的。我没有检查积分是否收敛,所以你可能想增加deg,看看是否有任何变化。
import numpy as np
from scipy.integrate import quad

def f(x, coef):
    n = coef[-1]
    p = (2*n+1)/2.*np.polynomial.legendre.Legendre(coef=coef)
    if 0 <= x <= 1:
        return 1*p(x)
    if -1 <= x <= 0:
        return -1*p(x)

c = []
for n in range(1, 51):
    c.append(quad(f, -1, 1, args=range(1,n+1))[0])
print c
#[0.0, 5.0, 6.9999999999999991, 4.5, ... , 62.975635570615466, 64.274102283412574, 77.143785770271251]