嗨我想整合一个从0到几个不同上限(大约1000)的函数。我已经编写了一段代码来使用for循环并将每个值附加到空数组。然而,我意识到我可以通过做更小的积分然后将前一个积分结果添加到刚刚计算的结果来使代码更快。所以我会做相同数量的积分,但是在更小的间隔内,然后只需添加前一个积分就可以得到从0到上限的积分。现在是我的代码:
import numpy as np #importing all relevant modules and functions
from scipy.integrate import quad
import pylab as plt
import datetime
t0=datetime.datetime.now() #initial time
num=np.linspace(0,10,num=1000) #setting up array of values for t
Lt=np.array([]) #empty array that values for L(t) are appended to
def L(t): #defining function for L
return np.cos(2*np.pi*t)
for g in num: #setting up for loop to do integrals for L at the different values for t
Lval,x=quad(L,0,g) #using the quad function to get the values for L. quad takes the function, where to start the integral from, where to end the integration
Lv=np.append(Lv,[Lval]) #appending the different values for L at different values for t
我需要做哪些更改来进行我建议的优化技术?
答案 0 :(得分:5)
基本上,我们需要跟踪Lval
和g
的先前值。 0对于两者都是良好的初始值,因为我们想要通过向第一个积分添加0开始,并且0是间隔的开始。您可以使用以下命令替换for循环:
last, lastG = 0, 0
for g in num:
Lval,x = quad(L, lastG, g)
last, lastG = last + Lval, g
Lv=np.append(Lv,[last])
在我的测试中,这明显加快了。
@askewchan在评论中指出,这更快:
Lv = []
last, lastG = 0, 0
for g in num:
Lval,x = quad(L, lastG, g)
last, lastG = last + Lval, g
Lv.append(last)
Lv = np.array(Lv)
答案 1 :(得分:2)
使用此功能:
<强> scipy.integrate.cumtrapz 强>
我能够将时间缩短到机器精度以下(非常小)。
该功能以高效的方式完全满足您的要求。有关详细信息,请参阅文档:https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.integrate.cumtrapz.html
以下代码,首先再现您的版本然后我的:
# Module Declarations
import numpy as np
from scipy.integrate import quad
from scipy.integrate import cumtrapz
import time
# Initialise Time Array
num=np.linspace(0,10,num=1000)
# Your Method
t0 = time.time()
Lv=np.array([])
def L(t):
return np.cos(2*np.pi*t)
for g in num:
Lval,x=quad(L,0,g)
Lv=np.append(Lv,[Lval])
t1 = time.time()
print(t1-t0)
# My Method
t2 = time.time()
functionValues = L(num)
Lv_Version2 = cumtrapz(functionValues, num, initial=0)
t3 = time.time()
print(t3-t2)
始终如一地产生:
t1-t0 = O(0.1)秒
t3-t2 = 0秒