I have an application where the following function to evaluate an exponential-like series is called many times for different p
vectors (the last two inputs are fixed), and takes a good portion of the running time. I was wondering if anyone had suggestions for speeding up this function. Note that the number of terms in the series / length of p
is fixed.
We’ve played around with using static vectors without any noticeable speedup, but I can’t say that we used them optimally. I can see several more potential optimizations like not evaluating exponential terms when p[i]*t
is small enough, or pre-summing some of the coefficients to reduce the number of subtractions, but any other performance optimization suggestions would be very appreciated!
function expseries!(f, p, times, tswitch)
i = 1
@inbounds while times[i] <= tswitch
t = times[i]
f[i] = p[1] * (exp(p[2] * t)-1.0) +
p[3] * (exp(p[4] * t)-1.0) +
p[5] * (exp(p[6] * t)-1.0) +
p[7] * (exp(p[8] * t)-1.0) +
p[9] * t
i += 1
end
switchval = p[1] * (exp(p[2] * tswitch)-1.0) +
p[3] * (exp(p[4] * tswitch)-1.0) +
p[5] * (exp(p[6] * tswitch)-1.0) +
p[7] * (exp(p[8] * tswitch)-1.0) +
p[9] * tswitch
@inbounds while i <= length(times)
t = times[i] - tswitch
f[i] = p[10] * (exp(p[11] * t)-1.0) +
p[12] * (exp(p[13] * t)-1.0) +
p[14] * (exp(p[15] * t)-1.0) +
p[16] * (exp(p[17] * t)-1.0) +
p[18] * t + switchval
i += 1
end
nothing
end
# example, representative data
expdata = zeros(600)
times = collect(0.0:600.0)
tswitch = 150.0
p = [-0.0023646887665542005, -0.17971576983395993, -0.00013140346280833014,
0.022029709829507547, -0.01776402710248875, -0.06784184880837002,
-0.535131802358805, -0.03029362682095963, 8.469962666009867e-5,
0.000578370769602594, -0.17205707686147037, 0.19152866595531834,
-0.006165370666034151, -1.5806598078316747e-8, 0.025194265785163362,
0.06808509404148284, -0.01509240208654776, -0.00011611542785341768]
using Plots
expseries_general!(expdata, p, times, tswitch)
plot(times, expdata)
Note the times
vector and tswitch
are representative of common values we use for them.
edit: There are a ton of really great suggestions below, but it appears Discourse only allows choosing one “solution”. For that reason I’m not going to pick a particular one as there are a bunch that are really helpful. Thanks everyone who has responded – this has been a great resource for me!