Ax = b 的迭代解法 —— 共轭梯度 (算法步骤)

线性方程组 Ax =b 除了高斯消元法以外,还有其它的迭代解法,这里我们说的是共轭梯度法。

 

 

这里只针对 A 满足 对称 ( [公式] ), 正定(即 [公式] ),并且是实系数的,那么我们可以用 梯度下降 和 共轭梯度 来解线性方程组 :

[公式]

 

 

 

 

向量 [公式] 和 [公式] 是共轭的 (相对于A )如果满足:

 

 

 

 

 

 

 

下图两两向量都是针对所在梯度处的矩阵‘共轭’的:

 

 

 

 

 

 

 

把梯度变换一下,就可以看出‘共轭’其实也就是某种正交:

 

 

 

 

=============================================

 

共轭梯度法解:

[公式]

 

 

算法步骤:(from wiki)

 

 

 ---------------------------------------------

 

 

python代码:(源于:Baselines:https://github.com/openai/baselines(强化学习算法))

 

复制代码
import numpy as np
"""共轭梯度下降"""
def cg(f_Ax, b, cg_iters=10, callback=None, verbose=False, residual_tol=1e-10):
    """
    Demmel p 312
    """
    p = b.copy()
    r = b.copy()
    x = np.zeros_like(b)
    rdotr = r.dot(r)

    fmtstr =  "%10i %10.3g %10.3g"
    titlestr =  "%10s %10s %10s"
    if verbose: print(titlestr % ("iter", "residual norm", "soln norm"))

    for i in range(cg_iters):
        if callback is not None:
            callback(x)
        if verbose: print(fmtstr % (i, rdotr, np.linalg.norm(x)))
        z = f_Ax(p)
        v = rdotr / p.dot(z)
        x += v*p
        r -= v*z
        newrdotr = r.dot(r)
        mu = newrdotr/rdotr
        p = r + mu*p

        rdotr = newrdotr
        if rdotr < residual_tol:
            break

    if callback is not None:
        callback(x)
    if verbose: print(fmtstr % (i+1, rdotr, np.linalg.norm(x)))  # pylint: disable=W0631
    return x
复制代码

 

 

 

测试代码:

复制代码
import numpy as np
from gg import cg  #导入 共轭梯度函数 cg


"""
A = np.array([[1.0, 0.0, 0.0],
              [0.0, 1.0, 0.0],
              [0.0, 0.0, 1.0]])
"""
A = np.random.rand(3, 3)  # 保证子行列式均为正
A = np.dot(A.T, A)  # 生成对称矩阵


def f_Ax(p):
    """f_Ax: 输入变量p为列向量,返回变量为矩阵A矩阵乘以向量p"""
    return np.dot(A, p)


x = np.random.rand(3)
b = np.dot(A, x)
print("matrix: \n", A)
print("x: \n", x)
print("b: \n", b)
print("...........................")


print("显示计算过程:")
result = cg(f_Ax, b, verbose=True)
print("matrix A 的特征值:")
print(np.linalg.eig(A)[0])
print("实际x:")
print(x)
print("求得x:")
print(result)
复制代码

 

 

 

结果:

复制代码
matrix: 
 [[1.33507088 0.69389736 0.579944  ]
 [0.69389736 0.76303172 0.47845562]
 [0.579944   0.47845562 0.41679907]]
x: 
 [0.40139385 0.12481318 0.38628268]
b: 
 [0.84651911 0.55858167 0.45350579]
...........................
显示计算过程:
      iter residual norm  soln norm
         0       1.23          0
         1   0.000553      0.523
         2   0.000169      0.535
         3   4.11e-28      0.571
matrix A 的特征值:
[2.12734118 0.31861571 0.06894478]
实际x:
[0.40139385 0.12481318 0.38628268]
求得x:
[0.40139385 0.12481318 0.38628268]
复制代码

 

 

 

 

=============================================

 

 

 

参考:

https://flat2010.github.io/2018/10/26/%E5%85%B1%E8%BD%AD%E6%A2%AF%E5%BA%A6%E6%B3%95%E9%80%9A%E4%BF%97%E8%AE%B2%E4%B9%89/

 

图来源:

https://flat2010.github.io/2018/10/26/%E5%85%B1%E8%BD%AD%E6%A2%AF%E5%BA%A6%E6%B3%95%E9%80%9A%E4%BF%97%E8%AE%B2%E4%B9%89/

 

 

 

 

------------------------------------------------------------------------------

 

posted on   Angry_Panda  阅读(2257)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
历史上的今天:
2019-03-28 【转载】 【caffe转向pytorch】caffe的BN层+scale层=pytorch的BN层
2019-03-28 【转载】 OpenCV ——双线性插值(Bilinear interpolation)
2018-03-28 Failed to resolve: com.android.support:appcompat-v7:27.+ 报错解决方法

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示