I have to solve in MATLAB a linear system of equations A*x=B
where A
is symmetric and its elements depend on the difference of the indices: Aij=f(i-j)
.
I use iterative solvers because the size of A
is say 40000x40000. The iterative solvers require to determine the product A*x
where x
is the test solution. The evaluation of this product turns out to be a convolution and therefore can be done dy means of fast fourier transforms (cputime ~ Nlog(N)
instead of N^2
). I have the following questions to this problem:
is this convolution circular? Because if it is circular I think that I have to use a specific indexing for the new matrices to take the fft. Is that right?
I find difficult to program the routine for the fft because I cannot understand the indexing I should use. Is there any ready routine which I can use to evaluate by fft directly the product A*x
and not the convolution? Actually, the matrix A is constructed of 3x3 blocks and is symmetric. A ready routine for the product A*x
would be the best solution for me.
Thank you in advance,
Panos
Very good and interesting question! :)
For certain special matrix structures, the Ax = b
problem can be solved very quickly.
Circulant matrices.
Matrices corresponding to cyclic convolution Ax = h*x
(* - is convolution symbol) are diagonalized in
the Fourier domain, and can be solved by:
x = ifft(fft(b)./fft(h));
Triangular and banded.
Triangular matrices and diagonally-dominant banded matrices are solved efficiently by sparse LU factorization:
[L,U] = lu(sparse(A)); x = U\(L\b);
Poisson problem.
If A is a finite difference approximation of the Laplacian, the problem is efficiently solved by multigrid methods (e.g., web search for "matlab multigrid").
Interesting question!
The convolution is not circular in your case, unless you impose additional conditions. For example, A(1,3)
should equal A(2,1)
, etc.
You could do it with conv
(retaining only the non-zero-padded part with option valid
), which probably is also N*log(N). For example, let
A = [a b c d
e a b c
f e a b
g f e a];
Then A*x
is the same as
conv(fliplr([g f e a b c d]),x,'valid').'
Or more generally, A*x
is the same as
conv(fliplr([A(end,1:end-1) A(1,:)]),x,'valid').'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With