[英]python: integrating a piecewise function
我想要整合一个定义的函数,该函数乘以勒让德多项式。 不幸的是,我在文档中找不到如何使用x的第n个勒让德多项式。 我想在n = 1,..., 50
时整合x的每个勒让德多项式n = 1,..., 50
所以我设置了n = np.arange(1, 51, 1)
。
import numpy as np
import pylab
from scipy import integrate
n = np.arange(1, 51, 1)
def f(x):
if 0 <= x <= 1:
return 1
if -1 <= x <= 0:
return -1
我想我需要定义另一个函数让我们说u(x)
。
c = []
def u(x):
c.append((2. * n + 1) / 2. * integrate.quad(f(x) * insert Legendre polynomials here, -1., 1.))
return sum(c * Legendre poly, for nn in range(1, 51))
所以我会返回一些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中实现这样的方案,那么这是一个选项。
编辑2:
使用Saullo Castro的答案,我有:
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))
但是,如果我打印c
,则值是错误的。 值应为1.5, 0, -7/8, 0, ...
另外,当我绘制g
,我想做x = np.linspace(-1, 1, 500000)
所以情节很详细,但c
只有50.怎么能实现呢?
如果我正确理解你的问题,你想要计算f(x)* Ln(x)的积分,其中f(x)是你用python函数定义的分段函数。 我假设你对这个特定的步骤功能并不特别感兴趣。
您可以使用legval和系数参数的单位矩阵来获取勒让德多项式的值。
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)
c = 1.5,0,-8.75e-1,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])
这给了:
print c
#[0.0, 5.0, 6.9999999999999991, 4.5, ... , 62.975635570615466, 64.274102283412574, 77.143785770271251]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.