Haskell 共轭梯度法的收敛性

Haskell 共轭梯度法的收敛性,haskell,matrix,linear-algebra,sparse-matrix,Haskell,Matrix,Linear Algebra,Sparse Matrix,我在Haskell中编写了求解矩阵的Gauss-Seidel和共轭梯度迭代算法(但这个问题与语言中的方法无关)。我的理解是,这两种算法应该具有相似的收敛特性,并且CG方法在大多数情况下应该更快。我已经对对称正定矩阵进行了很多测试,但我几乎无法得到CG alg。收敛,而GS几乎总是这样。我找不到任何带有右手边向量的对称正定矩阵用于在线测试,所以我一直在任意创建我自己的RHS(也许这是问题的一部分?)。如果我使用(转置A)*A代替Ax=b中的A,我可以使CG方法收敛,这只是迫使矩阵对称。我在这里包括

我在Haskell中编写了求解矩阵的Gauss-Seidel和共轭梯度迭代算法(但这个问题与语言中的方法无关)。我的理解是,这两种算法应该具有相似的收敛特性,并且CG方法在大多数情况下应该更快。我已经对对称正定矩阵进行了很多测试,但我几乎无法得到CG alg。收敛,而GS几乎总是这样。我找不到任何带有右手边向量的对称正定矩阵用于在线测试,所以我一直在任意创建我自己的RHS(也许这是问题的一部分?)。如果我使用(转置A)*A代替Ax=b中的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 
conjGrad::(浮动a,命令a,显示a)=>a->SpMCR a->SpVCR a->SpVCR a->(SpVCR a,Int)
conjGrad tol mA b x0=回路x0 r0 r0 rs0 1
式中,r0=b-(mulMV mA x0)
rs0=点r0 r0
回路x r p rs i
|(varLog“残数=”$sqrt rs')a->SpVCR a->SpVCR a
(*)s v=fmap(s*)v
编辑:果然,我没有解释MM文件格式只包含对称矩阵的下对角线这一事实。谢谢现在算法收敛了,但似乎需要更多的迭代。我的理解是,当使用精确算法时,CG应该总是以少于矩阵顺序的迭代次数收敛。使用浮点运算(Double)会产生如此大的差异吗(1.5-2 x矩阵顺序是合理收敛所需的迭代次数)


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

您可以通过使用带有浮动的精确库来回答第二个问题,例如CReal from here:或者摆脱日志记录(我认为这就是引入浮动约束的原因),只使用Data.Ratio中的有理数


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

“我可以让CG方法收敛,如果我……这只是强迫矩阵对称。
A
不是已经对称了吗?我想是的,这是我困惑的一部分。这是矩阵。我只是注意到它不是对角占优的。我认为这是高斯-赛德尔收敛的要求,但不是CG。也许这就是问题所在。如果是这样,那么CG似乎只适用于一类非常特殊的矩阵。CG需要对称正定(spd)矩阵才能收敛。Gauss-Seidel只保证对对角占优矩阵和spd矩阵收敛。你确定你正确阅读了矩阵吗?在提供下载的文件中,只指定了主对角线上或下方的非零条目,您可能忘记了在读取时使其对称。读入后检查是否转置A==A。谢谢,我没有想到要尝试。