Scipy:高效生成一系列积分(积分函数)

cqc*_*991 6 python recursion numpy scipy

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

在此输入图像描述

也就是说,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')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

问题

在我上面给出的示例代码中,对于每个点,集成都是从头开始完成的。在我的真实代码中,它f(x)非常复杂,并且是多重集成,因此运行时间太慢(Scipy:在对整个表面进行集成时加速集成?)。

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

我的想法:

该点的积分值Phi(20)是从 计算的Phi(19),并且Phi(19)是从Phi(18)等等。所以当我们得到时Phi(20),实际上我们也得到了 的系列(-20,-19,-18,-17 ... 18,19,20)。只是我们没有保存该值。

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

小智 3

人们可以通过仅在短时间间隔(连续的 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)
Run Code Online (Sandbox Code Playgroud)

以下pieces是短时间间隔内的积分,将其求和以生成 y 值。正如所写,此代码输出一个函数,该函数在积分范围(-20)的开头处为 0。当然,可以减去对应于 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)
Run Code Online (Sandbox Code Playgroud)

输出与第一个版本基本相同(计算误差很小),但代码较少。使用的原因lambda y,x: f(x)是 的第一个参数odeint必须是一个带有两个参数的函数,即方程 y' = f(y, x) 的右侧。