我必须在MATLAB中求一个线性方程组A*x=B
,其中A
是对称的,其元素取决于索引的差异:Aij=f(i-j)
。
我使用迭代求解器,因为A
的大小是40000x40000。迭代求解器需要确定产品A*x
,其中x
是测试解决方案。对此产品的评估结果证明是卷积,因此可以通过快速傅里叶变换(cputime~ Nlog(N)
而不是N^2
)来完成。我对这个问题有以下问题:
是这个卷积循环吗?因为如果它是循环的,我认为我必须使用新矩阵的特定索引来获取fft。是对的吗?
我发现很难为fft编写例程,因为我无法理解我应该使用的索引。是否有任何现成的例程我可以用fft直接评估产品A*x
而不是卷积?实际上,矩阵A由3×3块构成并且是对称的。产品A*x
的现成例程对我来说是最好的解决方案。
提前谢谢你,
帕诺斯
答案 0 :(得分:4)
非常好又有趣的问题! :)
对于某些特殊的矩阵结构,Ax = b
问题可以很快得到解决。
循环矩阵。
对应于循环卷积的矩阵Ax = h*x
(* - 是卷积符号)被对角化
傅里叶域,可以通过以下方法解决:
x = ifft(fft(b)./fft(h));
三角形和带状。
解决了三角矩阵和对角占优势的带状矩阵 通过稀疏LU分解有效:
[L,U] = lu(sparse(A)); x = U\(L\b);
泊松问题。
如果A是拉普拉斯算子的有限差分近似,则问题可以通过多重网格方法有效地解决(例如,网络搜索“matlab multigrid”)。
答案 1 :(得分:1)
有趣的问题!
除非您施加其他条件,否则卷积在您的情况下不是循环的。例如,A(1,3)
应该等于A(2,1)
等等。
您可以使用conv
(仅保留带有选项valid
的非零填充部分),这可能也是N * log(N)。例如,让
A = [a b c d
e a b c
f e a b
g f e a];
然后A*x
与
conv(fliplr([g f e a b c d]),x,'valid').'
或者更一般地说,A*x
与
conv(fliplr([A(end,1:end-1) A(1,:)]),x,'valid').'
答案 2 :(得分:0)
我想对Pio_Koon的答案添加一些评论。
首先,我不建议遵循三角形和带状矩阵的建议。在大型稀疏矩阵上调用Matlab的lu()
过程所花费的时间大大超过了将线性系统解析为x=U\(L\b)
所获得的任何好处。
其次,在 Poisson问题中,您最终会得到一个循环矩阵,因此您可以使用所描述的FFT来解决它。在这种特定情况下,卷积模板h
是拉普拉斯算子,即h=[0 -0.25 0; -0.25 1 -0.25; 0 -0.25 0]
。