I want to perform a mathematical integration in python in the following way:
[1] Solve an implicit equation with the help of scipy.optimize.fsolve to find the maximum position of the integrand
[2] Shift the integrand's maximum to zero and integrate from -10 to 10 with the help of scipy.integrate.quad
Since the integrand has one free parameter xi, I want to perform this with a range of xi values with the help of numpy, so I use numpy.vectorize.
Now there are two ways of vectorizing this alghorithm:
[A] vectorize [1] and [2] separately and give the result of vec_[1] to vec_[2] as input
[B] vectorize a function that performs [1] and [2] at once
I noticed that [A] is much faster than [B]. Here is the code:
from scipy import optimize, integrate
import numpy as np
from math import exp, sqrt, pi
import time
def integral_with_fsolve(xi):
xc = optimize.fsolve(lambda x: x+1./(1+exp(-x))-xi,0.)
def integrand(x,xi):
return exp(-(x-xi+xc)**2)/(2.*sqrt(2.*pi))/(1.+exp(x+xc))
integral = integrate.quad(integrand,-10.,10.,args=(xi,),epsabs=0.)
return integral[0]
def integral(xi,xc):
def integrand(x,xi):
return exp(-(x-xi+xc)**2)/(2.*sqrt(2.*pi))/(1.+exp(x+xc))
integral = integrate.quad(integrand,-10.,10.,args=(xi,),epsabs=0.)
return integral[0]
def fsolve(xi):
return optimize.fsolve(lambda x: x+1./(1+exp(-x))-xi,0.)
vec_integral_with_fsolve = np.vectorize(integral_with_fsolve)
vec_integral = np.vectorize(integral)
vec_fsolve = np.vectorize(fsolve)
xi = np.linspace(0.,2.,1000)
t0=time.time()
something = vec_integral_with_fsolve(xi)
dur=(time.time()-t0)
speed = xi.size/dur
print('Integrate and fsolve vectorized in one: speed = {} ints/sec'.format(speed))
t0=time.time()
xc = vec_fsolve(xi)
something = vec_integral(xi,xc)
dur=(time.time()-t0)
speed = xi.size/dur
print('Integrate and fsolve vectorized seperately: speed = {} ints/sec'.format(speed))
and the output is always something like
Integrate and fsolve vectorized in one: speed = 298.151473998 ints/sec
Integrate and fsolve vectorized seperately: speed = 2136.75134429 ints/sec
Since this is only a simplified version of my actual problem, I need to know why it behaves like this. Could someone please explain? Thanks!