共轭梯度法的收敛性



我已经在Haskell中编写了求解矩阵的Gauss-Seidel和共轭梯度迭代算法(但这个问题与方法有关,而与语言无关)。我的理解是,这两种算法都应该具有相似的收敛特性,并且CG方法在大多数情况下应该更快。我对对称正定矩阵进行了许多测试http://math.nist.gov/MatrixMarket/而我几乎永远都无法得到CG代数。收敛,而GS几乎总是这样。为了在线测试,我找不到任何带有右手边向量的对称正定矩阵,所以我一直在任意创建自己的RHS(也许这是问题的一部分?)。如果在Ax=b中使用(转置A)*A而不是A,我可以使CG方法收敛,这只是迫使矩阵对称。我在这里包含了CG代码。它显然不会按原样编译。如果有人需要它的功能来帮助,我会把它全部张贴出来。它对来自(伪代码和示例)的简单示例(类似问题)起到了正确的作用。关于共轭梯度与高斯-塞德尔收敛准则,我有什么遗漏吗?有人能为我指明正确的方向吗?谢谢

conjGrad :: (Floating a, Ord a, Show a) => a -> SpMCR a -> SpVCR a -> SpVCR a -> (SpVCR a, Int)
conjGrad tol mA b x0 = loop x0 r0 r0 rs0 1
where r0  = b - (mulMV mA x0)        
rs0 = dot r0 r0
loop x r p rs i
| (varLog "residual = " $ sqrt rs') < tol = (x',i)          
| otherwise                               = loop x' r' p' rs' (i+1)
where mAp = mulMV mA p
alpha = rs / (dot p mAp)
x' = x + (alpha .* p)
r' = r - (alpha .* mAp)
rs' = dot r' r'
beta = rs' / rs
p'  = r' + (beta .* p)

(.*) :: (Num a) => a -> SpVCR a -> SpVCR a
(.*) s v = fmap (s *) v 

编辑:果不其然,我没有解释MM文件格式只包括对称矩阵的下对角线这一事实。谢谢现在,该算法收敛了,但似乎需要比它应该需要的更多的迭代。我的理解是,当使用精确算术时,CG应该总是以小于矩阵顺序的迭代次数收敛。使用浮点(Double)的事实会产生如此大的差异吗(1.5-2倍的矩阵顺序是合理收敛所需的迭代)?

后续:对于任何可能偶然发现这一点的人来说,我的大部分问题都与我用于测试的矩阵有关。他们似乎不太适合使用CG算法进行求解。在某些情况下,简单的预处理有帮助。

您可以从这里使用带有浮动的精确库(如CReal)来回答第二个问题:http://hackage.haskell.org/package/numbers或者取消日志记录(我认为这就是引入浮动约束的原因),只使用Data中的推理。比率

这当然会非常缓慢。但它应该让你研究浮点近似对收敛的影响。

相关内容

  • 没有找到相关文章

最新更新