I have a numerical routine that I need to run to solve a certain equation, which contains a few nested four loops. I initially wrote this routine into Python, using numba.jit to achieve an acceptable performance. For large system sizes however, this method becomes quite slow, so I have been rewriting the routine into Fortran hoping to achieve a speed-up. However I have found that my Fortran version is much slower than the first version in Python, by a factor of 2-3.
I believe the bottleneck is a linear interpolation function that is called at each innermost loop. In the Python implementation I use numpy.interp, which seems to be pretty fast when combined with numba.jit. In Fortran I wrote my own interpolation function, which reads,
complex*16 function interp(x_dat, y_dat, N_dat, x)
implicit none
integer, intent(in) :: N_dat
real*8, dimension(N_dat), intent(in) :: x_dat
complex*16, dimension(N_dat), intent(in) :: y_dat
real*8, intent(in) :: x
complex*16 :: y, y1, y2
integer :: i, i1, i2, im
if(x <= x_dat(1)) then
y = y_dat(1)
else if(x >= x_dat(N_dat)) then
y = y_dat(N_dat)
else
im = MINLOC(DABS(x_dat - x), DIM=1)
if(x_dat(im) >=x ) then
i1 = im
i2 = im - 1
else
i1 = im + 1
i2 = im
end if
y1 = y_dat(i1)
y2 = y_dat(i2)
y = y1 + (x-x_dat(i1))*(y2 - y1)/(x_dat(i2) - x_dat(i1))
end if
interp = y
return
end function interp
Note that I need to interpolate complex data. If my diagnostics are correct this function is much slower than numpy.interp, which, since the interpolation has to be called in each loop, greatly reduces the speed of the whole program.
Does anyone know if there is a way to achieve Numpy like interpolation speeds in Fortran? Or if my interpolation function as shown above here is somehow horribly inefficient? I don't have much experience coding Fortran yet.
Thanks!