I am new to Mathematica and I encountered a speed problem.
I want to do tons of integrations of multiplications of two eigenfunctions (or matrix elements in physical terms). The speed now is quite unsatisfying.
As I only require numerical results, I would like to know how to speed up this process. The most efficient way I could think of is to get the discretized eigenfunctions. But I would also like to know how and at which stage discretization of the eigenfunctions could speed up the whole calculation most.
For example, the problem is
{eige, eigv}=NDEigensystem[SomeSystem];
result[[i,j]]=NIntegrate[eigv[[i]] eigv[[j]]];
Here i and j are different solutions corresponding to eige[[i]] and eige[[j]] respectively.
The stages I could think of are:
- When solving the differential eigensystem using
NDEigensystem, (get discretizedeigvatNDEigensystem) - When solved, transform the eigenfunction of the form
InterpolatingFunctioninto discrete ones, (discretize theeigvwhich is now inInterpolatingFunctionbeforeNIntegrationand then integrate by dot product.) - When using
NIntegration.
And, I would be very thankful if you could also teach me how to do it in these ways.
A specific example is below:
num = 10;
AbsoluteTiming[{eige, eigv} = NDEigensystem[-Laplacian[u[x], {x}], u[x], {x, 0, \[Pi]}, num];]
AbsoluteTiming[Sum[NIntegrate[eigv[[i]] x eigv[[j]], {x, 0, \[Pi]}], {i, 1,num}, {j, 1, num}]]
When num is as large as 100, the result is super slow.
Editted
After some efforts trying to understand the stages taken by NDEigensystem, I give up letting the function itself output discretized data. Although it seems this function contains a normalization process (or stage) after interpolation stage, I do not think I could realize arbitrary integration as fast as the internal function do. I found we can discretize the solution by hand. See below
Clear[x, u];
num = 40;
delta = 0.01;
{eige, eigv} = NDEigensystem[-Laplacian[u[x], {x}], u[x], {x, 0, \[Pi]}, num];
Sum[NIntegrate[eigv[[i]] x eigv[[j]], {x} \[Element] (eigv[[1]] /. x -> "ElementMesh")], {i, 1, num}, {j, 1, num}] // Timing
Sum[NIntegrate[eigv[[i]] x eigv[[j]], {x, 0, \[Pi]}], {i, 1, num}, {j, 1, num}] // Timing
AbsoluteTiming[
xRange = Range[0, \[Pi], delta];
eigvv = Table[eigv, {x, xRange}];
Print[Dimensions[eigvv], Dimensions[xRange]];
Sum[eigvv[[All, i]].(eigvv[[All, j]] xRange) delta, {i, 1, num}, {j, 1, num}]]
(*
{30.5625, 61.5422}
some warnings
{41.1875, 61.5243}
{315,40}{315}
{0.158992, 61.8818}
*)
The improvement is almost two orders.
xin theNIntegrateof your specific example? – Chris K Feb 08 '18 at 16:40xis an example, and you can even generalize to any functionf[x]to insert between eigenfunctions and also the eigenfunction could be a vector itself. – Xiaoyu Liu Feb 08 '18 at 16:44Sum[NIntegrate[eigv[[i]] x eigv[[j]], x \[Element] eigv[[2]]["ElementMesh"]], {i, 1, num}, {j, 1, num}]. Besides, it seems that from theFullForm, eigenfunctions are already discretized. – Xiaoyu Liu Feb 08 '18 at 17:10