5
$\begingroup$

This code for the first five iterations the speed is okay, but after that the speed is very slow, I cannot understand what is wrong with this? Would you please help me fix it?

Clear[A, r, x, s, e]
s := 0.3405
e := 1.6539*10^-21
u[0] := 0.
u[1] := 0.1

A[r_] := A[r] = 
  Piecewise[{{r - 2.5 s - 48*e *s^12*r^-13 + 24*e*s^6*r^-7, 
     r > 2.5 s}, {-48*e*s^12*r^-13 + 24*e*s^6*r^-7, 
     s <= r <= 2.5 s}, {r - s - 
      24*e*s^-1, r < s}}]
For[i = 2, i < 101, 
 i++, { u[i_] := 
   x /. FindRoot[
     u[i - 1] + 
       1/(i^2 (u[i - 1] - u[i - 2])^2) (u[i - 1] - u[i - 2]) - 
       0.9 A[x] == x , {x, 1.}]; Print[u[i]]}]
$\endgroup$
  • $\begingroup$ How slow? How many minutes/seconds? $\endgroup$ – JonyD Apr 12 at 8:28
12
$\begingroup$

I recommend you learn the distinction between immediate (=) and delayed (:=) assignments. They make the difference between slow and fast code here. Start with this tutorial or this book chapter, then look at memoization.

s = 0.3405;
e = 1.6539*10^-21;
u[0] = 0.;
u[1] = 0.1;

A[r_] = Piecewise[{{r - 2.5 s - 48*e*s^12*r^-13 + 24*e*s^6*r^-7, r > 2.5 s},
                   {-48*e*s^12*r^-13 + 24*e*s^6*r^-7, s <= r <= 2.5 s},
                   {r - s - 24*e*s^-1, r < s}}];

u[i_] := u[i] = x /. FindRoot[
  u[i - 1] + 1/(i^2 (u[i - 1] - u[i - 2])^2) (u[i - 1] - u[i - 2]) - 0.9 A[x] == x, {x, 1.}]

Array[u, 100]

{0.1, 1.77164, 1.37065, 1.04259, 0.887781, 0.708344, 0.59461, 0.457228, 0.367364, 0.296071, 0.256104, 0.20463, 0.208487, 1.20917, 1.04197, 0.939331, 0.879865, 0.827963, 0.774591, 0.72775, 0.67934, 0.63666, 0.592369, 0.553172, 0.512352, 0.476112, 0.438261, 0.404563, 0.369277, 0.339073, 0.321616, 0.301118, 0.296195, 0.224688, 0.273538, 0.31357, 0.33593, 0.366902, 0.38813, 0.417572, 0.437777, 0.465834, 0.48511, 0.511907, 0.530336, 0.55598, 0.573633, 0.598219, 0.615159, 0.638772, 0.655054, 0.677768, 0.693441, 0.715321, 0.73043, 0.751535, 0.766118, 0.786503, 0.800596, 0.820306, 0.833941, 0.852182, 0.85901, 0.874152, 0.871531, 0.78396, 0.781416, 0.696402, 0.693931, 0.611329, 0.608927, 0.528603, 0.526267, 0.448099, 0.445825, 0.369701, 0.367485, 0.315658, 0.325798, 0.341207, 0.351098, 0.366134, 0.375788, 0.390468, 0.399897, 0.414237, 0.42345, 0.437466, 0.446473, 0.46018, 0.46899, 0.4824, 0.491022, 0.504149, 0.51259, 0.525444, 0.533712, 0.546306, 0.554408, 0.56675}

(takes about 1.3 seconds)

Alternatively, use

Table[u[i], {i, 1, 100}]

(same result). Your combination of For and Print shows the results but doesn't let you keep using them for more calculations.

$\endgroup$
  • $\begingroup$ thank you very much. I really appreciate it. $\endgroup$ – morapi Apr 12 at 6:35
  • 1
    $\begingroup$ delayed assignments definitely sound slower than immediate, even if I have never worked with Mathematica $\endgroup$ – Roland Apr 12 at 10:07
  • 2
    $\begingroup$ @Roland it's not just that one is necessarily faster or slower than the other, it's more that they are completely different things with very different applications. For some reason this point is often overlooked by beginners in Mathematica. $\endgroup$ – Roman Apr 12 at 10:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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