Scipy分析地整合分段函数

时间:2016-08-13 20:27:20

标签: python python-2.7 scipy integration

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)

我不想单独整合这两件作品。

2 个答案:

答案 0 :(得分:4)

Scipy不会为您执行分析集成,因为它是为解决数值问题而制作的。另一方面,Sympy可以完全处理简单的符号问题:

if (err) {
  reject(err);
} else {
  resolve(res.body);
}

比较

>>> 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 相乘,然后以分析方式集成此新函数。​​

另一种可能更接近你的问题精神的替代方案可能是以数字方式定义分段函数,并最终使用scipy。这仍然会为你节省一些工作,但不会严格分析:

x

采用这种方法的最完整设置:

>>> 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 定义分段lambda,然后是第一时刻的积分,将其与f相乘。然后我们进行整合。

请注意,许多人不赞成将lambda与变量绑定。如果你想正确地做这件事,你应该为你的分段函数定义一个命名函数,并且只在集成中使用lambda(否则你不会使用那个被积函数):

x

答案 1 :(得分:1)

使用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.])]