I have a really big vector (nearly 30,000 elements) called x and am trying to numerically find the root of a function where one of the parameters successively takes each value stored in the vector. At the moment, I'm using a For
loop (I know a lot of people here cringe at the very mention of For
loops for some reason; sorry):
For[j=1,j<=Length[x],j++,
f = SOME REALLY COMPLICATED FUNCTION OF t AND x[[j]];
sol[[j]]=t/.FindRoot[f,{t,t0}];
Clear[t];
];
Print[sol];
I'm wondering whether there's a more efficient way of doing this (I'm talking code-wise, not things like some simple approximation to f which gives an acceptably small error). Currently, my code takes just over 5 minutes to run (I've got a few more operations before and after the numerical bit, but they don't take long, so perhaps the numerical bit takes 4-5 minutes). I've tried setting it up as a vector operation (see code below), but after about 10 minutes of evaluation I quit the kernel because it was clear to me that that wasn't going to be more efficient than the For
loop. Here's my vector-operation code:
f = SOME REALLY COMPLICATED FUNCTION OF t AND x;
sol=t/.FindRoot[f,{t,t0}]
Print[sol];
Thanks in advance.
sol=ParallelTable[t/.FindRoot[SOME REALLY COMPLICATED FUNCTION OF t AND x[[j]],{t,t0}],{j,Length[x]}]
. (c) ConsiderCompile
. $\endgroup$FindRoot
that might improve its performance. That is almost certainly where the bottleneck lies. $\endgroup$x
vector are not far off from each other, use the lastt
as the start point for the nextFindRoot
iteration. $\endgroup$Compile
(link) does, as its name suggests, compilation. It takes a series of mathematica commands and compiles them to machine language which is more efficient in terms of running time. Two things: If this will do anything, it will probably mainly accelerate theCOMPLICATED FUNCTION
and notFindRoot
, so if the bottleneck is inFindRoot
I wouldn't bother. Second, not all mathematica's commands are compilable so this might not work for you. $\endgroup$f
, you could recast the problem as an ODE, and then the output ofNDSolve
will give you an interpolating function that can be used on your vector. $\endgroup$