基于Givens矩阵的QR矩阵分解

这篇具有很好参考价值的文章主要介绍了基于Givens矩阵的QR矩阵分解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

QR分解是一种将矩阵分解为正交矩阵和上三角矩阵的方法。在QR分解中,正交矩阵Q的转置是它的逆矩阵,因此QR分解可以用于求解线性方程组、最小二乘问题等。

二阶Givens矩阵qr分解 givens,python,c语言,矩阵,算法,Powered by 金山文档

一般地,二阶Givens矩阵记为下列形式:

qr分解 givens,python,c语言,矩阵,算法,Powered by 金山文档其中qr分解 givens,python,c语言,矩阵,算法,Powered by 金山文档

下面开始介绍基于Givens矩阵的QR分解算法。Givens矩阵是一种旋转矩阵,可以将一个向量旋转到另一个向量的方向。在QR分解中,我们使用Givens矩阵将矩阵的列向量逐个旋转,使得矩阵变为上三角矩阵。

QR分解的详细步骤如下:

  1. 对矩阵A的第一列进行Givens变换,使得A的第一列的下面的元素都变为0。这样得到一个新的矩阵A1和一个Givens矩阵G1。

  1. 对矩阵A1的第二列进行Givens变换,使得A1的第二列的下面的元素都变为0。这样得到一个新的矩阵A2和一个Givens矩阵G2。

  1. 重复步骤2,直到所有的列都被处理完毕。这样得到一个上三角矩阵R和一个正交矩阵Q,满足A=QR。

大致如下:

qr分解 givens,python,c语言,矩阵,算法,Powered by 金山文档

下面是基于Givens矩阵的QR分解的C和Python代码:文章来源地址https://www.toymoban.com/news/detail-531329.html

#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 np


def givens_rotation(a, b):  # 定义一个Givens旋转函数,a和b是两个数
    if b == 0:  # 如果b为0
        return 1, 0  # 返回1和0
    elif abs(b) > abs(a):  # 如果b的绝对值大于a的绝对值
        r = a / b  # r等于a除以b
        s = 1 / np.sqrt(1 + r ** 2)  # s等于1除以根号下1加r的平方
        c = s * r  # c等于s乘以r
    else:  # 否则
        r = b / a  # r等于b除以a
        c = 1 / np.sqrt(1 + r ** 2)  # c等于1除以根号下1加r的平方
        s = c * r  # s等于c乘以r
    return c, s  # 返回c和s


def 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和R


A = 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矩阵分解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 最优化方法实验三--矩阵QR分解

    1.熟练掌握 QR 分解 Gram–Schmidt方法; 2.掌握 Householder 方 法 ; 3. 能够判断 矩阵是否可逆 ,并 求出其逆矩阵 。 1 .1向量投影 向量的投影包含了两层意思:①正交关系:矢量与投影的差称为误差,误差和投影正交;②最短距离:投影空间中所有矢量中,与原矢量距离最近的,

    2024年02月22日
    浏览(47)
  • 理顺 QR 分解算法

    咱们网站的这个公式编辑器,估计是后台生成图片后贴回来的,固定分辨率而且分辨率不高。  还不如先离线 latex 生成 pdf 后再截图上来 When A and b are known, to solver the minimization of , where . The reduction of A to various canonical form via orthogonal transformations should use Householder reflections and

    2024年01月25日
    浏览(32)
  • 自相关算法,协方差算法,后向加窗算法,前向加窗算法以及QR分解法的理论介绍与matlab仿真分析

    目录 1.自相关算法 2.协方差算法 3.后向加窗算法 4.前向加窗算法 5.QR分解法        自相关算法是一种在信号处理中用来描述信号特性的算法,它主要用于估计一个信号的功率谱。对于一个离散信号x[n],其自相关函数定义为: Rxx[n] = E[x[n+m]*x[m]]       其中E[]表示期望。可以看

    2024年04月09日
    浏览(50)
  • 4.6 QR分解二:Householder变换

      Householder反射是这样子的(图片来自瑞典皇家理工学院):   图中u是长度为1的向量。x是任意向量,H是u的Householder reflector。可见无论x是什么向量, H x Hx H x 始终除于和u正交的平面上。H和u的关系是: H = I − 2 u u ∗ H=I-2uu^* H = I − 2 u u ∗    u ∗ u^* u ∗ 是u的共轭转置

    2024年02月02日
    浏览(33)
  • QR分解的三种方法和实现过程

    在解最小二乘问题 m i n ∣ ∣ A x − b ∣ ∣ min||Ax-b|| min ∣∣ A x − b ∣∣ 时,将其转化成 A T A x = A T b A^{T}Ax=A^{T}b A T A x = A T b 之后该问题就是一个求解线性方程组的问题。最简单的求解线性方程组方法是高斯消去,但是有时高斯消去会增大方程的条件数,这时我们可以用正交

    2024年02月07日
    浏览(34)
  • Matlab中求解线性方程组——高斯消元法、LU分解法、QR分解法、SVD分解法、迭代法等

    MATLAB迭代的三种方式以及相关案例举例 MATLAB矩阵的分解函数与案例举例 MATLAB当中线性方程组、不定方程组、奇异方程组、超定方程组的介绍 MATLAB语句实现方阵性质的验证 MATLAB绘图函数的相关介绍——海底测量、二维与三维图形绘制 MATLAB求函数极限的简单介绍 文章目录 前言

    2024年02月08日
    浏览(66)
  • 基于Yolov5的二维码QR码识别

    目录 1.QR code介绍  1.1 通过split_train_val.py得到trainval.txt、val.txt、test.txt   1.2 通过voc_label.py得到适合yolov5训练需要的  2.基于yolov5的QR码检测 2.1配置 QR.yaml 2.2 修改yolov5s_QR.yaml 2.3 训练QR码检测模型 3.性能评价 4.QR码识别 4.1 转成onnx模型 4.2 基于opencv的QR码识别 4.3 基于zbar的QR码识

    2024年02月07日
    浏览(39)
  • 使用vue-qr,报错in ./node_modules/vue-qr/dist/vue-qr.js

    找到node_modules— vue-qr/dist/vue-qr.js 文件,搜…e,将…去掉,然后重新运行项目。

    2024年02月03日
    浏览(44)
  • Python实现PC摄像头扫描二维码,让你的电脑变身QR码识读器!

    目录 简介: 源代码: 源代码说明: 效果如下所示: 使用PC摄像机扫描二维码可以有很多应用场景,例如: 支付宝、微信支付等移动支付方式需要使用二维码进行支付,PC摄像机可以扫描这些支付二维码,从而实现PC端支付功能; 在生产制造过程中,可以使用二维码来管理产

    2024年02月03日
    浏览(40)
  • BUUCTF qr 1

    BUUCTF:https://buuoj.cn/challenges 题目描述: 这是一个二维码,谁用谁知道! 密文: 下载附件,得到一张二维码图片。 解题思路: 1、这是一道签到题,扫描二维码得到flag。 flag:

    2024年02月08日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包