Is it possible to find some selected elements of the inverse of a large sparse matrix without inverting it?
For example consider this Hermitian matrix (as a general case).
n1 = 20; n2 = 50;
n3 = n1 n2;
a1 = RandomComplex[{0. + 0. I, 1. + 1. I}, {n1, n1}];
a2 = ConjugateTranspose[a1];
a3 = RandomComplex[{0. + 0. I, 1. + 1. I}, {n1, n1}];
a3 = (a3 + ConjugateTranspose[a3])/2.;
a0 = SparseArray[{Band[{1, 1}, {n3, n3}] -> {a3},
Band[{1, n1 + 1}, {n3 - n1, n3}] -> {a1},
Band[{n1 + 1, 1}, {n3, n3 - n1}] -> {a2}}, {n3, n3}]
b0 = Inverse[a0]; // AbsoluteTiming
{0.240657, Null}
and I am interested only in a small portion of b0
say
b0[[(n2 - 1) n1 + 1 ;; n2 n1, 1 ;; n1]] // MatrixForm
In case of banded matrix, 'LinearSolve` works much faster.
f = LinearSolve[a0, SparseArray[{i_, i_} -> 1, {n3, n3}]]; // AbsoluteTiming
f[[(n2 - 1) n1 + 1 ;; n2 n1, 1 ;; n1]] // MatrixForm
{0.068483, Null}
The result is same (I didn't put it here). As you can see the execution is significantly faster. But f
is using same memory as b0
where the memory required to store a single block (a1
,a2
) is very little.
Map[ByteCount, {a1, a2, a0, b0, f, b0[[(n2 - 1) n1 + 1 ;; n2 n1, 1 ;; n1]]}]
%/Min[%] // N
{6776, 6776, 6165680, 16000152, 16000152, 6776}
{1., 1., 909.929, 2361.3, 2361.3, 1.}
Is there any way to reduce both time and memory in this case?