亲爱的Matlab用户,
在我的图像处理算法实现中,我必须解决A * x = b形式的大型线性系统,其中:
拉普拉斯矩阵L在算法的连续运行之间不会改变;我可以在预处理中构造这个矩阵,并可能计算它的分解。对角矩阵D和右侧矢量b在算法的每次运行时都会改变。
我试图找出在运行时解决系统的最快方法;我不介意花时间进行预处理(例如,计算L的因子分解)。
我最初的想法是预先计算L的Cholesky因子分解,然后使用来自D的值(使用cholupdate进行排名-1更新)在运行时更新因子分解,并快速解决返回替换的问题。不幸的是,Cholesky分解并不像原始L矩阵那样稀疏,只是从磁盘加载它已经需要5.48秒;作为比较,用反斜杠直接解决系统需要8.30秒。
考虑到我的矩阵的形状,是否有任何其他方法可以建议在运行时加速求解,无论预处理时间需要多长时间?
提前感谢您的帮助!
答案 0 :(得分:2)
假设您正在使用网格(因为您提到图像 - 虽然这不能保证),您对速度比精度更感兴趣(因为5s看起来已经太慢了100万个未知数),我看到几个选项
首先,忘记Cholesky(+重新排序)等确切方法。即使它们允许存储因子分解并将其重用于多个rhs,您可能需要存储在您的情况下看起来难以处理的巨大矩阵(我希望您使用反向Cuthill McKee或其他任何东西重新排序行/列)否则 - 这会使因子分解很多)。
根据你的边界条件,我会首先尝试使用FFT解决泊松问题的Matlab poisolv
,如果你想要Dirichlet边界条件而不是周期条件,可能会重新注入。它非常快,但可能不适合你的问题(你提到拉丁语矩阵的25 nnz +同一性:为什么?它是一个高阶拉普拉斯矩阵,在这种情况下你可能比我假设更精确的精度?或者它实际上是一个与你描述的问题不同的问题?)。
然后,您可以尝试快速处理图像和平滑问题的多重网格解算器。您可以对每个迭代和多重网格的每个级别使用简单的松弛方法,或使用更高级的方法(例如,预处理的共轭梯度par级别)。 或者,您可以在没有多重网格的情况下执行更简单的预处理共轭梯度(甚至是SSOR),如果您只对近似解决方案感兴趣,则可以在完全收敛之前停止迭代。
我对迭代求解器的论证是:
当然,你可以预先计算,存储和保持因子分解的直接求解器也是有意义的(虽然如果你的矩阵是常数我不理解你的等级1更新的论点),因为只有后置替换仍然是在运行时完成。但是考虑到这忽略了问题的结构(常规网格,可能对有限精度结果的兴趣等),我会选择为这些情况设计的方法,如类似傅立叶的方法或多重网格。这两种方法都可以在GPU上实现,以获得更快的结果(回想一下,GPU非常适合处理图像/纹理!)。
最后,您可以从scicomp.stackexchange获得有趣的答案,这些答案更适合于数值分析。