[英]Scipy analytically integrate piecewise function
scipy中是否存在分段函數的分析積分方法? 例如,我有:
xrange_one, xrange_two = np.arange(0,4), np.arange(3,7)
part_one = lambda x: x + 3
part_two = lambda x: -2*x + 2
我想整合這個分段函數的第一個時刻:
func_one = lambda x: x * (x + 3)
func_two = lambda x: x * (-2*x + 2)
是否有一種方法可以使用scipy integrate.quad或其他一些分析集成函數來執行以下操作:
total = integrate.quad(func_one, 0, 3, func_two, 3, 6)
我不想單獨整合這兩件。
Scipy不會為您執行分析集成,因為它是為解決數值問題而制作的。 另一方面,Sympy可以完全處理簡單的符號問題:
>>> import sympy as sym
>>> x = sym.symbols('x')
>>> f = sym.Piecewise((x*(x+3),x<3), (x*(-2*x+2),True))
>>> sym.integrate(f,(x,0,6))
-153/2
相比
>>> import scipy.integrate as integrate
>>> integrate.quad(lambda x:x*(x+3),0,3)[0] + integrate.quad(lambda x:x*(-2*x+2),3,6)[0]
-76.5
>>> -153/2.
-76.5
您還可以先定義原始的分段函數,然后將其與符號x
相乘,然后分析地集成此新函數。
另一種可能更接近你的問題精神的替代方案可能是以數字方式定義分段函數,並最終使用scipy。 這仍然會為您節省一些工作,但不會嚴格分析:
>>> f = lambda x: x*(x+3) if x<3 else x*(-2*x+2)
>>> integrate.quad(f,0,6)[0]
-76.5
使用此方法的最完整設置:
>>> f = lambda x: x+3 if x<3 else -2*x+2
>>> xf = lambda x: x*f(x)
>>> first_mom = integrate.quad(xf,0,6)[0]
>>> print(first_mom)
-76.5
首先,我們定義f
的分段lambda,然后是第一個矩的被積函數,乘以x
。 然后我們進行整合。
請注意,許多人不贊成將lambda與變量綁定。 如果你想正確地做這個,你應該為你的分段函數定義一個命名函數,並且只在集成中使用lambda(否則你不會使用那個被積函數):
import scipy.integrate as integrate
def f(x):
return x+3 if x<3 else -2*x+2
first_mom = integrate.quad(lambda x: x*f(x),0,6)[0]
在使用numpy
poly
函數后,我想出了:
integrate.quad(lambda x:np.piecewise(x, [x < 3, x >= 3],
[lambda x: np.polyval([1,3,0],x),
lambda x: np.polyval([-2,2,0],x)]),
0,6)
評估為:
(-76.5, 1.3489209749195652e-12)
有一個polyint
可以進行多項式積分
In [1523]: np.polyint([1,3,0])
Out[1523]: array([ 0.33333333, 1.5 , 0. , 0. ])
In [1524]: np.polyint([-2,2,0])
Out[1524]: array([-0.66666667, 1. , 0. , 0. ])
那是
x*(x+3) => x**2 + 3*x => np.poly1d([1,3,0]) => 1/3 x**3 + 3/2 x**2
因此, analytical
解是這兩個polyint
對象的適當終點差異:
In [1619]: np.diff(np.polyval(np.polyint([1,3,0]),[0,3])) +
np.diff(np.polyval(np.polyint([-2,2,0]),[3,6]))
Out[1619]: array([-76.5])
In [1621]: [np.polyval(np.polyint([1,3,0]),[0,3]),
np.polyval(np.polyint([-2,2,0]),[3,6])]
Out[1621]: [array([ 0. , 22.5]), array([ -9., -108.])]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.