将函数与 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 元素。
绝对可以更高效地完成。最后得到的是一系列的计算:
- 将 LCDMf 从 0 积分到 1。
- 将 LCDMf 从 0 积分到 2。
- 将 LCDMf 从 0 积分到 3。
因此,您要做的第一件事就是将其更改为对不同的子区间进行积分,然后对它们求和(毕竟,还有什么是积分!):
- 将 LCDMf 从 0 积分到 1。
- 将 LCDMf 从 1 集成到 2,添加步骤 1 的结果。
- 将 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 方法那样有任何初始条件。
我希望这也能对某个地方的人有所帮助...感谢大家的投入。
我在 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 元素。
绝对可以更高效地完成。最后得到的是一系列的计算:
- 将 LCDMf 从 0 积分到 1。
- 将 LCDMf 从 0 积分到 2。
- 将 LCDMf 从 0 积分到 3。
因此,您要做的第一件事就是将其更改为对不同的子区间进行积分,然后对它们求和(毕竟,还有什么是积分!):
- 将 LCDMf 从 0 积分到 1。
- 将 LCDMf 从 1 集成到 2,添加步骤 1 的结果。
- 将 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 方法那样有任何初始条件。
我希望这也能对某个地方的人有所帮助...感谢大家的投入。