Can someone please tell me how can I learn to systematically optimize my Mathematica
code to be faster? I have seen a blog about the same but have no idea where to begin and how to implement this.
For example :- The following code takes more than 24 hours to run (actually it's still running, expected 30+ hours)
Ef[a_] := Pi^2*(a + 2)^2;
Eb[a_] := Pi^2*(a + 1)^2;
f[n_, x_] := Sqrt[2/((n + 2)^2 - 1)]*((n + 2)*Cos[Pi*(n + 2)*x] - Cot[Pi*x]*Sin[(n + 2)*Pi*x]);
b[n_, x_] := Sqrt[2]*Sin[(n + 1)*Pi*x];
xf[m_, n_] := If[Mod[m - n, 2] == 0, 0, Integrate[f[n, x]*f[m, x]*x, {x, 0, 1},
Assumptions -> {Element[n, Integers], Element[m, Integers]}]];
xb[m_, n_] := Integrate[b[n, x]*b[m, x]*x, {x, 0, 1}, Assumptions -> {Element[n, Integers], Element[m, Integers]}];
xt[m_, n_] := If[m == 0 || n == 0, xb[m, n], (1/2)*(xb[m, n] + xf[m - 1, n - 1])];
Z[T_] := Sum[E^(-(Eb[i]/T)), {i, 0, 10}];
y1[m_, t_] := -Sum[(Eb[k] - Eb[m])*xt[m, k]*xt[k, m]*Cos[(Eb[k] - Eb[m])*t], {k, 0, 10}];
Y1[T_, t_] := (-(1/Z[T]))*Sum[Sum[(Eb[k] - Eb[m])*xt[m, k]*xt[k, m]*Cos[(Eb[k] - Eb[m])*t], {k, 0, 10}]/E^(Eb[m]/T),
{m, 0, 10}];
file = OpenAppend["susypotwell_Y1T0.1.dat"];
Table[Export[file, {{t, Y1[0.1, t]}}, "TSV"], {t, -1., 1., 0.01}]
Close[file]
file = OpenAppend["susypotwell_Y1T1.dat"];
Table[Export[file, {{t, Y1[1, t]}}, "TSV"], {t, -1., 1., 0.01}]
Close[file]
file = OpenAppend["susypotwell_Y1T10.dat"];
Table[Export[file, {{t, Y1[10, t]}}, "TSV"], {t, -1., 1., 0.01}]
Close[file]
One way to do this could be to evaluate Y1[T,t]
and define a new function using the output which would then be used in the Export
expressions instead of Y1
. Please note that here I am exporting data to plot because Mathematica
does not automatically save data of plots if it needs to be modified later on. If Plot
can somehow do this faster then I have no problem with it as well and I will just use this or similar to save the plot data inside notebook for later manipulations.
Furthermore, if say, one has optimized their code as much as it can be and it is still taking 24+ hours or something like that then what are the options they have?
Apologies for such a broad question. Even quick tips and suggestions would help a lot.
Edit :-
Step-1 : Use #-&
notation for pure functions. (source)
Integrate
andSum
once instead of recalculating it every time might be the most significant change you could make. $\endgroup$