预条件共轭梯度下降法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

相关文章

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

浅谈MySQL的容量规划

《浅谈MySQL的容量规划》进行MySQL的容量规划是确保数据库能够在当前和未来的负载下顺利运行的重要步骤,容量规划包括评估当前资源使用情况、预测未来增长、调整配置和硬件资源等,感兴趣的可以了解一下... 目录一、评估当前资源使用情况1.1 磁盘空间使用1.2 内存使用1.3 CPU使用1.4 网络带宽二、

浅谈mysql的not exists走不走索引

《浅谈mysql的notexists走不走索引》在MySQL中,​NOTEXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引,下面就来介绍一下mysql的notexists走不走索... 在mysql中,​NOT EXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引。以下

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