预条件共轭梯度下降法PCG浅谈

2024-03-18 12:10

本文主要是介绍预条件共轭梯度下降法PCG浅谈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

共轭梯度法是一种求解SPD系统线性方程组的迭代方法。它本来是一种直接法,但是通过迭代法求解后,配合复杂的预条件方法,反而更受欢迎。

我们将求解

转化为求解phi(x) 的最小值

注意:A的SPD性质确保了它的唯一性。

线性搜索法

将线性求解的问题转化为求最小值的问题后,我们尝试用线性求解的方式。我们首先选择一个初始位置,不同的方法会选择不同的方向和step length。

其中,local gradient经过计算就是,这个也会被称为系统残差。

对应的步长如下

 但是我们认为最速梯度下降法zigzag的路线并不能真正最快的找到最优解,因此想到了利用历史梯度的先验信息去解决这个问题。

共轭梯度下降法

共轭梯度法利用N个相互独立并且共轭的向量,我们可以把从初值得到方程解。

 但是,如何得到这n个共轭梯度呢?

思路一:采用特征向量,但是,特征向量的求解也需要大量计算。

思路二:Gram-Schmidt orthogonalization process, 它需要存储所有的方向。

思路三: 我们想要借助之前的方向和当前的最速梯度。

 

终止条件:当误差小于一个域值的时候,就应该停止搜索。 

预条件

共轭梯度法很好,因为它快,而且容易实现,但是,它的运算复杂度存在很大的随机性,需要的迭代数存在很大的不确定性。

我们想找到一个矩阵和A相乘来让求解具备更好的条件,但是预条件矩阵的求得并不容易。。。

代码实现

代码实现参考了贺博在手写VIO代码中的PCG策略,但是。。。目前我的实现还是存在求解不收敛的情况。欢迎大家指正。

def PCG(A, b,showplot = False):matA= np.array(A)vecb = np.array(b).reshape(-1,1)maxIter = np.shape(vecb)[0]varNum = np.shape(A)[1]x = np.zeros_like(b)r0 = vecberror_hist =[]if (np.linalg.norm(r0)<1e-6):return x# calculate preconditionM_inv_diag = (1.0/np.diag(matA)).reshape(-1,1);for num in M_inv_diag:if (np.isinf(num)):num = 0#print("M_inv_diag ",M_inv_diag)z0 = np.multiply(M_inv_diag , r0)#取得第一个基底,计算基底权重 alpha,并更新 xp = z0w = A @ pr0z0 = r0.T@z0#print("r0z0 ",r0z0)alpha = r0z0/(p.T@w)# print("alpha ",alpha)# print("p ",p)x += alpha *pr1 = r0 - alpha * w#设定迭代终止的阈值threshold = 1e-6 * np.linalg.norm(r0)i = 0while(np.linalg.norm(r1)>threshold and i < maxIter):error_hist.append(float(np.linalg.norm(r1))/varNum)i+= 1z1 = np.multiply(M_inv_diag,r1)r1z1 = r1.T@z1beta = r1z1/r0z0z0 =z1r0z0 = r1z1r0 = r1p = beta * p +z1w = A @ palpha = r1z1/(p.T@w)x += alpha * pr1 -= alpha*wprint("error list",error_hist)plt.plot(error_hist)return xdef testPCG(rows,cols):if(rows<cols):print("nullspace exists")returnA = np.random.rand(rows,cols)x = np.random.rand(cols,1)*10b = A@xprint("A: ",A)print("x: ",x)print("b: ",b)res = PCG(A,b, True)print("res ",res)return testPCG(5,5)

参考资料:

共轭梯度简明文档:https://folk.idi.ntnu.no/elster/tdt24/tdt24-f09/cg.pdf
PCG 伪代码参考文档:https://www.cse.psu.edu/~b58/cse456/lecture20.pdf

这篇关于预条件共轭梯度下降法PCG浅谈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/822289

相关文章

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

浅谈Redis Key 命名规范文档

《浅谈RedisKey命名规范文档》本文介绍了Redis键名命名规范,包括命名格式、具体规范、数据类型扩展命名、时间敏感型键名、规范总结以及实际应用示例,感兴趣的可以了解一下... 目录1. 命名格式格式模板:示例:2. 具体规范2.1 小写命名2.2 使用冒号分隔层级2.3 标识符命名3. 数据类型扩展命

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用

pytorch自动求梯度autograd的实现

《pytorch自动求梯度autograd的实现》autograd是一个自动微分引擎,它可以自动计算张量的梯度,本文主要介绍了pytorch自动求梯度autograd的实现,具有一定的参考价值,感兴趣... autograd是pytorch构建神经网络的核心。在 PyTorch 中,结合以下代码例子,当你

SpringBoot条件注解核心作用与使用场景详解

《SpringBoot条件注解核心作用与使用场景详解》SpringBoot的条件注解为开发者提供了强大的动态配置能力,理解其原理和适用场景是构建灵活、可扩展应用的关键,本文将系统梳理所有常用的条件注... 目录引言一、条件注解的核心机制二、SpringBoot内置条件注解详解1、@ConditionalOn

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

SpringIntegration消息路由之Router的条件路由与过滤功能

《SpringIntegration消息路由之Router的条件路由与过滤功能》本文详细介绍了Router的基础概念、条件路由实现、基于消息头的路由、动态路由与路由表、消息过滤与选择性路由以及错误处理... 目录引言一、Router基础概念二、条件路由实现三、基于消息头的路由四、动态路由与路由表五、消息过滤

浅谈mysql的sql_mode可能会限制你的查询

《浅谈mysql的sql_mode可能会限制你的查询》本文主要介绍了浅谈mysql的sql_mode可能会限制你的查询,这个问题主要说明的是,我们写的sql查询语句违背了聚合函数groupby的规则... 目录场景:问题描述原因分析:解决方案:第一种:修改后,只有当前生效,若是mysql服务重启,就会失效;

Nginx中location实现多条件匹配的方法详解

《Nginx中location实现多条件匹配的方法详解》在Nginx中,location指令用于匹配请求的URI,虽然location本身是基于单一匹配规则的,但可以通过多种方式实现多个条件的匹配逻辑... 目录1. 概述2. 实现多条件匹配的方式2.1 使用多个 location 块2.2 使用正则表达式