Scipy:有效地生成一系列集成(积分函数)

时间:2016-02-06 03:08:21

标签: python numpy recursion scipy

我有一个函数,我想得到它的积分函数,如下所示:

enter image description here

也就是说,我需要在x获取值,而不是在multiple points点获取单个积分值。

例如:

假设我希望范围为(-20,20)

def f(x):
    return x**2

x_vals  = np.arange(-20, 21, 1)
y_vals =[integrate.nquad(f, [[0, x_val]]) for x_val in x_vals ]

plt.plot(x_vals, y_vals,'-', color = 'r')

enter image description here

问题

在上面给出的示例代码中,对于每个点,集成是从头开始。在我的实际代码中,f(x)非常复杂,而且是多重集成,因此运行时间太慢(Scipy: speed up integration when doing it for the whole surface?)。

我想知道在给定范围内是否有任何有效生成Phi(x)的方法。

我虽然:

Phi(20)的积分值来自Phi(19)Phi(19)来自Phi(18),依此类推。因此,当我们得到Phi(20)时,实际上我们也得到(-20,-19,-18,-17 ... 18,19,20)系列。除了我们没有保存价值。

所以我在想,是否可以为集成函数创建保存点,因此当它通过save point时,该值将被保存并继续到下一点。因此,通过20的单个流程,我们也可以获得(-20,-19,-18,-17 ... 18,19,20)

的值

1 个答案:

答案 0 :(得分:2)

一个可以通过仅在短间隔(在连续的x值之间)进行积分然后获取结果的累积和来实现您概述的策略。像这样:

import numpy as np
import scipy.integrate as si
def f(x):
    return x**2
x_vals = np.arange(-20, 21, 1)
pieces = [si.quad(f, x_vals[i], x_vals[i+1])[0] for i in range(len(x_vals)-1)]
y_vals = np.cumsum([0] + pieces)

这里pieces是短时间间隔内的积分,它们被求和以产生y值。如上所述,该代码输出一个函数,该函数在积分范围的开始处为0,即-20。当然,可以减去对应于x = 0的y值,以便具有与图上相同的归一化。

也就是说,分裂和总和过程是不必要的。当你找到f的不定积分时,你实际上是在解微分方程F'= f。 SciPy有一个内置的方法,odeint。只需使用它:

import numpy as np
import scipy.integrate as si
def f(x):
    return x**2
x_vals = np.arange(-20, 21, 1)
y_vals = si.odeint(lambda y,x: f(x), 0, x_vals)

输出与第一个版本相同(在微小的计算错误中),代码更少。使用lambda y,x: f(x)的原因是odeint的第一个参数必须是带有两个参数的函数,方程y'的右边是f(y,x)。