I want to tridagonalize a sparse matrix using the Lanczos algorithm.
I am working with a very large sparse matrix and I need some speed. In the following for example H=SparseArray[#->RandomComplex[{-1-I,1+I}]&/@RandomInteger[{1,1000000},{5000000,2}]]// (# + #\[ConjugateTranspose])/2 &;
is my sparse matrix. I cannot use Compail as my code include a sparse array. Is there any way to speed up the code?
abGenerator[niter_] :=
Module[{ket0, ket1, ketm, ketk, alist, blist},
ket0 =Normalize@RandomComplex[{-1-I,1+I},Length@H];
alist = Table[0, niter];
blist = Table[0, niter];
ketk = H.ket0;
alist[[1]] = ket0\[Conjugate].ketk;
ket1 = ketk - alist[[1]] ket0;
blist[[1]] = Norm@ket1;
ket1 = ket1/blist[[1]];
Do[
ketm = ket0;
ket0 = ket1;
ketk = H.ket0;
alist[[i]] = ket0\[Conjugate].ketk;
ket1 = ketk - alist[[i]] ket0 - blist[[i - 1]]\[Conjugate] ketm;
blist[[i]] = Norm@ket1;
ket1 = ket1/blist[[i]];, {i, 2, niter}];
{alist,
blist}]
abGenerator[100]//AbsoluteTiming
For me, this takes around 16.28 seconds! Note that I don't need this code for diagonalization and I need it for other purposes!
Update:
For confirmation consider the following matrix,
H = SparseArray[# -> RandomComplex[{-1 - I, 1 + I}] & /@
RandomInteger[{1, 10000}, {50000,
2}]] // (# + #\[ConjugateTranspose])/2 &;
Now I can find its eigenvalue using Eigenvalue
Eigenvalues[H, 3, Method -> "Arnoldi"]
Which for me it gives [each run is different because the H is different!]
{-2.7889, 2.78153, 2.76776}
However, I can get the same result if I reconstruct the three-diagonal matrix and get its eigenvalue!
Eigenvalues[
abGenerator[100] //
DiagonalMatrix[SparseArray@#[[1]]] +
DiagonalMatrix[SparseArray@#[[2, 1 ;; -2]], 1] +
DiagonalMatrix[SparseArray@#[[2, 1 ;; -2]]\[Conjugate], -1] &, 3]
which gives,
{-2.7889, 2.78153, 2.76776}