【问题标题】:How to make my python integration faster?如何让我的 python 集成更快?
【发布时间】:2013-12-27 09:00:17
【问题描述】:

您好,我想将一个函数从 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

我需要进行哪些更改才能执行我建议的优化技术?

【问题讨论】:

标签: python optimization for-loop scipy physics


【解决方案1】:

基本上,我们需要跟踪Lvalg 的先前值。 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 在 cmets 中指出的那样,这甚至更快:

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)

【讨论】:

  • 不错的技巧,比 明显 更快 :P 顺便说一句,您可以从 Lv = [] 开始将速度再提高 25% 左右,最后循环Lv.append(last),循环之后Lv = np.array(Lv)
  • Lv1 未初始化。
  • @WarrenWeckesser:糟糕,Lv1 应该是 Lv。我已经编辑了答案。
  • 这很好用,但 Scipy 有一个内置函数(见下文),它通常优于任何原生 Python 实现。
【解决方案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 秒

【讨论】:

    猜你喜欢
    • 2021-05-11
    • 2017-07-11
    • 2019-03-09
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2020-03-21
    相关资源
    最近更新 更多