2017-05-01 20 views
2

我有在python函数极限的每个元素的功能(使用SciPy的和numpy的也)定义为整合与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]) 

但是通过迭代循环,我想知道是否有更快,efficien (更简单)的方式来做到这一点与每个numpy元素。

+0

我记得很久以前用np.vectorize方法解决这个问题。我不记得我是如何做到的......但当时它似乎是一种通用的解决方案,并为我工作。任何人都可以在类似的方向上解决它? –

+0

'np.vectorize'只是在函数调用中包装迭代。它不会加速你的代码。 – hpaulj

+0

我用它在numpy数组上工作......不是为了加速 –

回答

1

经过修补与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方法。

我希望这可以帮助某个地方的人......感谢所有的投入。

0

它绝对可以更有效地完成。到底是什么,你所得到的是一系列的计算:

  1. 从0整合LCDMf到1
  2. 整合从0到LCDMf 2.
  3. 整合从0到LCDMf 3

所以,你可以做的第一件事就是改变它整合不同的子区间,然后总结他们(毕竟,还有什么是整合!):

  1. 诠释egrate LCDMf从0到1
  2. 从1整合LCDMf〜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()来获得最终结果。您需要在循环中调用的唯一功能是集成器本身。

+0

可能是我没有完全按照你的解决方案。 0到1,0等到2是一个例子。它不一定总是等距或整数。所以,说z = [0.1,0.15,0.367,0.265 ...]然后会发生什么? –

+0

那么你说'z = np.arange(0,100)'但如果你有其他的'z',那么就先对它进行排序,我的解决方案应该仍然有效 - 只需从0积分到最小的'z'值,然后从那'z'到下一个最小的'z'等。 –

4

您可以将该问题更改为ODE。

enter image description here

odeint功能可随后被用于计算对F(z)一系列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 
+0

有趣的解决方法。但是对于初始条件必须有一个“0”值的东西是一种限制,对我来说似乎并不普遍。说,如果我想要将z从0.1变化到0.5,例如 –

+0

@RohinKumar你可以总是[prepend](http://stackoverflow.com/questions/36998260/prepend-element-to-numpy-array)一个0。 – kennytm