3
$\begingroup$

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.

$\endgroup$
10
  • 2
    $\begingroup$ (a) People cringe because of this. (b) Consider parallelization, i.e. sol=ParallelTable[t/.FindRoot[SOME REALLY COMPLICATED FUNCTION OF t AND x[[j]],{t,t0}],{j,Length[x]}]. (c) Consider Compile. $\endgroup$
    – yohbs
    May 23, 2017 at 15:47
  • 2
    $\begingroup$ Best bet would be to focus on different settings for FindRoot that might improve its performance. That is almost certainly where the bottleneck lies. $\endgroup$ May 23, 2017 at 16:03
  • $\begingroup$ If the solutions working through the x vector are not far off from each other, use the last t as the start point for the next FindRoot iteration. $\endgroup$
    – MikeY
    May 23, 2017 at 16:25
  • 1
    $\begingroup$ 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 the COMPLICATED FUNCTION and not FindRoot, so if the bottleneck is in FindRoot I wouldn't bother. Second, not all mathematica's commands are compilable so this might not work for you. $\endgroup$
    – yohbs
    May 23, 2017 at 18:29
  • 2
    $\begingroup$ If you can take derivatives of f, you could recast the problem as an ODE, and then the output of NDSolve will give you an interpolating function that can be used on your vector. $\endgroup$
    – Carl Woll
    May 23, 2017 at 19:33

0

Browse other questions tagged or ask your own question.