python - tutorial - the django project
¿Cómo hacer que mi integración con Python sea más rápida? (2)
Básicamente, necesitamos hacer un seguimiento de los valores previos de Lval
y g
. 0 es un buen valor inicial para ambos, ya que queremos comenzar agregando 0 a la primera integral, y 0 es el comienzo del intervalo. Puede reemplazar su bucle for con esto:
last, lastG = 0, 0
for g in num:
Lval,x = quad(L, lastG, g)
last, lastG = last + Lval, g
Lv=np.append(Lv,[last])
En mi prueba, esto fue notablemente más rápido.
Como señala @askewchan en los comentarios, esto es aún más rápido:
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)
Hola, quiero integrar una función de 0 a varios límites superiores diferentes (alrededor de 1000). He escrito un fragmento de código para hacer esto usando un ciclo for y anexando cada valor a un conjunto vacío. Sin embargo, me doy cuenta de que podría hacer que el código sea más rápido al hacer integrales más pequeñas y luego agregar el resultado integral anterior al que acaba de calcular. Así que estaría haciendo la misma cantidad de integrales, pero en un intervalo más pequeño, y luego solo agregué la integral anterior para obtener la integral desde 0 hasta ese límite superior. Aquí está mi código en este momento:
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
¿Qué cambios debo hacer para hacer la técnica de optimización que he sugerido?
Usando esta función:
scipy.integrate.cumtrapz
Pude reducir el tiempo a una precisión inferior a la de la máquina (muy pequeña).
La función hace exactamente lo que está pidiendo de una manera altamente eficiente. Consulte los documentos para obtener más información: https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.integrate.cumtrapz.html
El siguiente código, que reproduce primero tu versión y luego la mía:
# 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)
Que consistentemente cede:
t1-t0 = O (0.1) segundos
t3-t2 = 0 segundos