calculus and analysis - How to speed up the calculation of a multi-dimension matrix involving symbolic integral?
The following program succeeds in getting matrix CC, but it takes time badly, especially in the case varNumber
becomes larger just as the following varNumber = 35
. Who can speed up the process of calculation? Thanks!
ClearAll["Global`*"];
varNumber = 35; end = Infinity;
s1 = 112*^9; s2 = 25*^9; s3 = 15.1; s4 = 5.5*10^-9;
a[m_] := Exp[-x/2]*LaguerreL[m, x];
b[m_, i_, j_, l_] := Integrate[a[m]*x^i*D[a[l], {x, j}], {x, 0, end}];
d[m_, i_, j_, l_] :=
Integrate[
a[m]*x^i*D[
a[l], {x, j}]*(DiracDelta[x] -
DiracDelta[x - end]), {x, -Infinity, Infinity}];
c[1, 1][m_, l_] := s2*d[m, 0, 1, l] + s2*b[m, 0, 2, l];
c[1, 2][m_, l_] := 0;
c[1, 3][m_, l_] := 0;
c[2, 1][m_, l_] := 0;
c[2, 2][m_, l_] := s1*d[m, 0, 1, l] + s1*b[m, 0, 2, l];
c[2, 3][m_, l_] := s3*d[m, 0, 1, l] + s3*b[m, 0, 2, l];
c[3, 1][m_, l_] := 0;
c[3, 2][m_, l_] := s3*d[m, 0, 1, l] + s3*b[m, 0, 2, l];
c[3, 3][m_, l_] := -s4*d[m, 0, 1, l] - s4*b[m, 0, 2, l];
CC = ArrayFlatten@
Table[c[m, n][i, j], {m, 3}, {n, 3}, {i, 0, varNumber - 1}, {j, 0,
varNumber - 1}]; // AbsoluteTiming
{2283.69, Null}
Answer
Try this instead of your definitions of b
and d
:
b[m_, 0, 2, l_] /; l == m = 1/4;
b[m_, 0, 2, l_] /; l > m = l - m;
b[m_, 0, 2, l_] /; l < m = 0;
d[m_, 0, 1, l_] = -l - 1/2;
With these I can assemble CC
in 0.047589 seconds (varNumber = 35
).
For different values of $i$ and $j$, I find the fast definition
d[m_, i_, j_, l_] := If[i == 0, a[m]*D[a[l], {x, j}] /. x -> 0, 0];
following directly from the integral over Dirac $\delta$-functions. As for b[m,i,j,l]
I would recommend asking at math.SE to see if anyone knows a closed formula for these integrals.
More generally, in the absence of such formulas you can use classical memoization, which gains you a big factor because you don't keep re-calculating the same values. Alternatively, you can use persistent memoization that will remember values forever, even when the kernel is restarted:
cacheloc = PersistenceLocation["Local",
FileNameJoin[{$UserBaseDirectory, "caches", "bintegrals"}]];
end = Infinity;
a[m_] = Exp[-x/2]*LaguerreL[m, x];
b[m_Integer, i_Integer, j_Integer, l_Integer] := b[m, i, j, l] =
Once[Integrate[a[m]*x^i*D[a[l], {x, j}], {x, 0, end}], cacheloc];
Here I've used a combination of classical memoization and persistent storage, which complement each other: the former is very fast but impermanent, while the latter is a bit sluggish but permanent. Together, we get both advantages: the first lookup from permanent storage is still sluggish, but afterwards we get very fast lookup.
Comments
Post a Comment