基于Givens矩阵的QR矩阵分解
QR分解是一种将矩阵分解为正交矩阵和上三角矩阵的方法。在QR分解中,正交矩阵Q的转置是它的逆矩阵,因此QR分解可以用于求解线性方程组、最小二乘问题等。
二阶Givens矩阵
一般地,二阶Givens矩阵记为下列形式:
其中
下面开始介绍基于Givens矩阵的QR分解算法。Givens矩阵是一种旋转矩阵,可以将一个向量旋转到另一个向量的方向。在QR分解中,我们使用Givens矩阵将矩阵的列向量逐个旋转,使得矩阵变为上三角矩阵。
QR分解的详细步骤如下:
对矩阵A的第一列进行Givens变换,使得A的第一列的下面的元素都变为0。这样得到一个新的矩阵A1和一个Givens矩阵G1。
对矩阵A1的第二列进行Givens变换,使得A1的第二列的下面的元素都变为0。这样得到一个新的矩阵A2和一个Givens矩阵G2。
重复步骤2,直到所有的列都被处理完毕。这样得到一个上三角矩阵R和一个正交矩阵Q,满足A=QR。
大致如下:
![](/assets/blank.gif)
下面是基于Givens矩阵的QR分解的C和Python代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>#define N 3 // 指定矩阵阶数void print_matrix(double **M) {for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {printf("%f ", M[i][j]);}printf("\n");}
}// 矩阵乘法
double **matrix_multiply(double **A, double **B) {int i, j, k;double **C = (double **)malloc(sizeof(double *) * N);for (i = 0; i < N; i++) {C[i] = (double *)malloc(sizeof(double) * N);}for (i = 0; i < N; i++) {for (j = 0; j < N; j++) {C[i][j] = 0;for (k = 0; k < N; k++) {C[i][j] += A[i][k] * B[k][j];}}}return C;
}// 单位矩阵
double **identity_matrix() {int i, j;double **I = (double **)malloc(sizeof(double *) * N);for (i = 0; i < N; i++) {I[i] = (double *)malloc(sizeof(double) * N);for (j = 0; j < N; j++) {if (i == j) {I[i][j] = 1;} else {I[i][j] = 0;}}}return I;
}// 矩阵的转置
double **transpose_matrix(double **A) {int i, j;double **AT = (double **)malloc(sizeof(double *) * N);for (i = 0; i < N; i++) {AT[i] = (double *)malloc(sizeof(double) * N);for (j = 0; j < N; j++) {AT[i][j] = A[j][i];}}return AT;
}// Givens变换c和s
double *givens_rotation(double a, double b) {double c, s;double *cs = (double *)malloc(sizeof(double) * 2);if (b == 0) {c = 1;s = 0;} else if (fabs(b) > fabs(a)) {double r = a / b;s = 1 / sqrt(1 + r * r);c = s * r;} else {double r = b / a;c = 1 / sqrt(1 + r * r);s = c * r;}cs[0] = c;cs[1] = s;return cs;
}double **qr_givens(double A[][N], double **Q) {double **Q_ = identity_matrix();Q = Q_;double **R = (double **)malloc(sizeof(double *) * N);for (int i = 0; i < N; i++) {R[i] = (double *)malloc(sizeof(double) * N);}for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {R[i][j] = A[i][j];}}for (int j = 0; j < N; j++) {for (int i = N - 1; i > j; i--) {double **G = identity_matrix();double *cs = givens_rotation(R[i - 1][j], R[i][j]);double c = cs[0];double s = cs[1];G[i - 1][i - 1] = c;G[i - 1][i] = s;G[i][i - 1] = -s;G[i][i] = c;double **R_ = matrix_multiply(G, R);R = R_;double **GT = transpose_matrix(G);double **Q_ = matrix_multiply(Q, GT);Q = Q_;}}return R;
}int main() {double A[N][N] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};double **Q = (double **)malloc(sizeof(double *) * N);for (int i = 0; i < N; i++) {Q[i] = (double *)malloc(sizeof(double) * N);}double **R = qr_givens(A, Q);print_matrix(R);return 0;
}
import numpy as npdef givens_rotation(a, b): # 定义一个Givens旋转函数,a和b是两个数if b == 0: # 如果b为0return 1, 0 # 返回1和0elif abs(b) > abs(a): # 如果b的绝对值大于a的绝对值r = a / b # r等于a除以bs = 1 / np.sqrt(1 + r ** 2) # s等于1除以根号下1加r的平方c = s * r # c等于s乘以relse: # 否则r = b / a # r等于b除以ac = 1 / np.sqrt(1 + r ** 2) # c等于1除以根号下1加r的平方s = c * r # s等于c乘以rreturn c, s # 返回c和sdef qr_givens(A): # 定义一个QR分解函数,A是一个矩阵m, n = A.shape # m和n分别等于A的行数和列数Q = np.identity(m) # Q等于m阶单位矩阵R = A.copy() # R等于A的副本for j in range(n): # 对于j在0到n-1的范围内(从第一列到第n列)for i in range(m - 1, j, -1): # 对于m-1到j+1的范围内(从最后一行到第j行)G = np.identity(m) # G等于m阶单位矩阵c, s = givens_rotation(R[i - 1, j], R[i, j]) # c和s等于Givens旋转函数的返回值G[i - 1:i + 1, i - 1:i + 1] = [[c, s], [-s, c]] # G的第i-1到i行,第i-1到i列等于[[c, s], [-s, c]]R = np.dot(G, R) # R等于G和R的矩阵乘积Q = np.dot(Q, G.T) # Q等于Q和G的转置矩阵的矩阵乘积return Q, R # 返回Q和RA = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) # A等于一个3行3列的矩阵
Q, R = qr_givens(A) # Q和R等于QR分解函数的返回值
print("Q:\n", Q) # 输出Q
基于Givens矩阵的QR矩阵分解相关推荐
- 基于Givens变换的QR分解
01.function [Q,R]=qrgv(A)02.% 基于Givens变换,将方阵A分解为A=QR,其中Q为正交矩阵,R为上三角阵03.%04.% 参数说明05.% A:需要进行QR分解的方阵0 ...
- [矩阵的QR分解系列四] QR(正交三角)分解
QR分解 简介 QR分解 定义 存在和唯一性 存在性证明 唯一性证明 分解方法 施密特(Schmidt)方法 吉文斯(Givens)方法 豪斯霍尔德(Householder)方法 例子 施密特(Sch ...
- 矩阵的QR分解以及在最小二乘法中的应用
一.最小二乘法 最小二乘法是一种数学优化方法,通过最小化误差的平方和来拟合数据点. 以线性回归模型为例,如果我们用最小二乘法来求解线性回归的系数,可得: err(yi−y^)=1n∑i=1n( ...
- [矩阵的QR分解系列一] 施密特(Schmidt)正交规范化
施密特正交规范化 简介 规范化步骤 例子 引用 之前介绍的矩阵的三角分解系列介绍了利用矩阵初等变换解决了矩阵三角化问题以及具体的三角分解.但是以初等变换工具的三角分解方法并不能消除病态线性方程组不稳定 ...
- 矩阵的QR分解c语言编程,[矩阵的QR分解系列五] Eigen中的QR分解
之前介绍的矩阵的三角分解系列介绍了利用矩阵初等变换解决了矩阵三角化问题以及具体的三角分解.但是以初等变换工具的三角分解方法并不能消除病态线性方程组不稳定问题,而且有时候对于可逆矩阵有可能也不存在三角分 ...
- ciaodvd数据集的简单介绍_基于注意力机制的规范化矩阵分解推荐算法
随着互联网技术的发展以及智能手机的普及, 信息超载问题也亟待解决.推荐系统[作为解决信息超载问题的有效工具, 已被成功应用于各个领域, 包括电子商务.电影.音乐和基于位置的服务等[.推荐系统通过分析用 ...
- AI笔记: 数学基础之正交矩阵与矩阵的QR分解
正交矩阵 若n阶方阵A满足ATA=EA^TA = EATA=E, 则称A为正交矩阵, 简称正交阵 (复数域上称为酉矩阵) A是正交阵的充要条件:A的列(行)向量都是单位向量,且两两正交. 若A为正交矩 ...
- 几种矩阵分解算法: LU分解,Cholesky分解,QR分解,SVD分解,Jordan分解
目录 1.LU分解 2. LDLT分解法 3. Cholesky分解的形式 4. QR分解 5.SVD分解 5.1 SVD与广义逆矩阵 6. Jordan 分解 参考文章: ---------我只是搬 ...
- 线性代数(15)——矩阵的QR分解
矩阵QR分解 矩阵的QR分解 概述 演示分析 实现QR分解 矩阵的QR分解和LU分解的目的都是为了便于矩阵计算. 矩阵的QR分解 概述 A = Q R A=QR A=QR这一过程将矩阵分解为 Q Q ...
最新文章
- 这道算法题太简单?你忽略了时间复杂度的要求!
- Bootstrap 简洁、直观、强悍、移动设备优先的前端开发框架,让web开发更迅速、简单。...
- 【研究院】浅析小米与它的AI生态
- c语言的转义字符要求,C语言…转义字符的使用
- linux编译动态库之-fPIC
- bootstrap-表格-普通表格
- Sigma Grid 2.4 探究 1
- python运行不了程序代码_Python源码分析2 - 一个简单的Python程序的执行
- oracle 收集统计信息会锁表吗,统计信息锁住导致收集统计信息失败引起sql执行异常...
- 【LeetCode 剑指offer刷题】树题19:8 二叉树中序遍历的下一个结点
- 迅雷高速通道破解教程
- 《滕王阁序》古文鉴赏
- 关于idea中提交svn时一直显示performing VCS refresh
- iPhone的备忘录如何进行撤销?
- 【小说】玻璃碎片-第二章
- unity【KeyCode 键码】查询表
- ERP与电子商务整合乃大势所趋
- 鸿蒙系统应用开发初体验(一)
- Maven - 6、生命周期和插件详解
- POJ 1700 经典过河问题(贪心)