I know that this is a "beginner question", and, in fact, I am. I want to improve my code, as it takes really too much time to run. I have already read some other discussions, like here, but I am struggling in translating the simplifications with Table or Do into my example.

The For cycle I want to improve is the following:

zh = 0.4;
list = {};

For[i = 1, i < 10000, i++, 
    With[{zg = -0.6, dh = i*10^-2}, 
         nsol = Block[{eps = $MachineEpsilon}, 
         NDSolve[{phi''[x] + 2*phi'[x]/x + (2*(zg + zh*Exp[-zh*x/dh])/x + 1)*phi[x] == 0, phi[eps] == 1, phi'[eps] == -(zg + zh)}, phi, {x, eps, 20000}, 
                 WorkingPrecision->MachinePrecision, AccuracyGoal->15, PrecisionGoal->8, MaxSteps->Infinity]]];  
    AppendTo[list, 1/Evaluate[(15000*phi[15000])^2 + ((15000-Pi/2)*phi[15000-Pi/2])^2 /. nsol[[1]]]];]

Clearly, this code, written in this way, is highly inefficient. Also, I need to do more of these, with different values for zg inside With, and make some plots out of the lists.

Anyone that can help me with this noob question? Thanks a lot!

  • $\begingroup$ Eliminate the AppendTo inside the loop and use Sow and Reap instead. $\endgroup$ Oct 21, 2020 at 16:12
  • $\begingroup$ Can you provide me with an example? $\endgroup$
    – Lele
    Oct 21, 2020 at 16:17
  • $\begingroup$ You should take a look at this, if you haven't yet: mathematica.stackexchange.com/q/134609/12 The documentation of Sow and Reap has several relevant examples. $\endgroup$
    – Szabolcs
    Oct 21, 2020 at 16:43
  • 2
    $\begingroup$ Actually I don't see any need for Sow/Reap here. Just use Table. $\endgroup$
    – Szabolcs
    Oct 21, 2020 at 16:49
  • 1
    $\begingroup$ I don't see why Table wouldn't work—what exactly have you tried? Also, the code you posted here doesn't run (which is why I can't directly give you the Table translation). Please show a complete, minimal, working example. $\endgroup$
    – Szabolcs
    Oct 21, 2020 at 18:58

1 Answer 1


Here is an example that uses Table (well, ParallelTable) instead of For. I've also used ParametricNDSolveValue instead of With, mostly to simplify the Table.

phifunc = ParametricNDSolveValue[
  {\[Phi]''[x] + 2 \[Phi]'[x]/x + (2 (zg + zh Exp[-zh x/dh])/x + 1) \[Phi][x] == 0
   , \[Phi][$MachineEpsilon] == 1
   , \[Phi]'[$MachineEpsilon] == -(zg + zh)
  , 1/((15000 \[Phi][15000])^2 + ((15000 - \[Pi]/2) \[Phi][
         15000 - \[Pi]/2])^2)
  , {x, $MachineEpsilon, 20000}
  , {dh \[Element] Reals, zg \[Element] Reals, zh \[Element] Reals}
list = ParallelTable[phifunc[i 10^-2, -0.6, 0.4], {i, 1, 10000}]

As far as timing goes, it still seems to take a very long time to run 10000 evaluations, so another answer might provide a faster method. I vaguely recall a way to functionalize calls to NDSolve in a way that stores calculations for faster repeated calls, but I can't find the link.

  • $\begingroup$ Thank you @Josh Bishop, this looks better! It still takes a lot of time, though.. $\endgroup$
    – Lele
    Oct 22, 2020 at 10:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.