将函数与 numpy 数组的每个元素集成为集成限制

Integrate a function with each element of numpy arrays as limit of integration

我在 python 中有一个函数(也使用 scipy 和 numpy)定义为

import numpy as np
from scipy import integrate
LCDMf = lambda x: 1.0/np.sqrt(0.3*(1+x)**3+0.7)

我想将它从 0 整合到一个 numpy 数组中的每个元素说 z = np.arange(0,100)

我知道我可以为每个迭代的元素编写一个循环

an=integrate.quad(LCDMf,0,z[i])

但是,我想知道是否有更快、更有效(更简单)的方法来处理每个 numpy 元素。

绝对可以更高效地完成。最后得到的是一系列的计算:

  1. 将 LCDMf 从 0 积分到 1。
  2. 将 LCDMf 从 0 积分到 2。
  3. 将 LCDMf 从 0 积分到 3。

因此,您要做的第一件事就是将其更改为对不同的子区间进行积分,然后对它们求和(毕竟,还有什么是积分!):

  1. 将 LCDMf 从 0 积分到 1。
  2. 将 LCDMf 从 1 集成到 2,添加步骤 1 的结果。
  3. 将 LCDMf 从 2 集成到 3,添加步骤 2 的结果。

接下来您可以深入了解 LCDMf,它是这样定义的:

1.0/np.sqrt(0.3*(1+x)**3+0.7)

您可以使用 NumPy 广播立即在多个点评估此功能:

dx = 0.0001
x = np.arange(0, 100, dx)
y = LCDMf(x)

那应该相当快,并且在曲线上给你一百万个点。现在您可以使用 scipy.integrate.trapz() 或相关函数之一集成它。使用已经计算出的 y 和 dx 调用它,使用上面的工作流程,您在其中整合每个间隔,然后使用 cumsum() 获得最终结果。您需要在循环中调用的唯一函数就是积分器本身。

您可以将问题改写为 ODE。

然后可以使用 odeint 函数为一系列 z.

计算 F(z)
>>> scipy.integrate.odeint(lambda y, t: LCDMf(t), 0, [0, 1, 2, 5, 8])
array([[ 0.        ],    # integrate until z = 0 (must exist, to provide initial value)
       [ 0.77142712],    # integrate until z = 1
       [ 1.20947123],    # integrate until z = 2
       [ 1.81550912],    # integrate until z = 5
       [ 2.0881925 ]])   # integrate until z = 8

在修改 np.vectorize 之后,我找到了以下解决方案。简单 - 优雅且有效!

import numpy as np
from scipy import integrate
LCDMf = lambda x: 1.0/math.sqrt(0.3*(1+x)**3+0.7)
np.vectorize(LCDMf)

def LCDMfint(z):
    return integrate.quad(LCDMf, 0, z)

LCDMfint=np.vectorize(LCDMfint)
z=np.arange(0,100)

an=LCDMfint(z)
print an[0]

此方法适用于未排序的浮点数组或我们抛给它的任何东西,并且不像 odeint 方法那样有任何初始条件。

我希望这也能对某个地方的人有所帮助...感谢大家的投入。