计算矩阵的逆源码(使用伴随矩阵,3×3的矩阵)

目的:最近写C++代码,遇到求矩阵的逆。Eigen库有方法计算。但是因为再求导过程中,需要求逆的具体方式。因此自己实现了求矩阵的逆。具体代码如下,对于公式部分后续再补,更新。

//更新公式部分
维基百科的定义:
在线性代数中,一个方形矩阵的伴随矩阵(英语:adjugate matrix)是一个类似于逆矩阵的概念。如果矩阵可逆,那么它的逆矩阵和它的伴随矩阵之间只差一个系数。然而,伴随矩阵对不可逆的矩阵也有定义,并且不需要用到除法。
假设 A \bm{A} A的伴随矩阵记作 a d j ( A ) adj(\bm{A}) adj(A)或者 A ∗ \bm{A}^* A
因为在项目中通常需要 3 × 3 3\times 3 3×3的矩阵,它可以定义为:
A = [ a 11 a 12 a 13 a 21 a 22 a 23 a 31 a 32 a 33 ] \bm{A}=\begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} A= a11a21a31a12a22a32a13a23a33

它的伴随矩阵是:

a d j ( A ) = [ + ∣ a 22 a 23 a 32 a 33 ∣ − ∣ a 12 a 13 a 32 a 33 ∣ + ∣ a 12 a 13 a 22 a 23 ∣ − ∣ a 21 a 23 a 31 a 33 ∣ + ∣ a 11 a 13 a 31 a 33 ∣ − ∣ a 11 a 13 a 21 a 23 ∣ + ∣ a 21 a 22 a 31 a 32 ∣ − ∣ a 11 a 12 a 31 a 32 ∣ + ∣ a 11 a 12 a 21 a 22 ∣ ] adj(\bm{A})=\begin{bmatrix} +\begin{vmatrix} a_{22} & a_{23} \\ a_{32} & a_{33} \end{vmatrix} & -\begin{vmatrix} a_{12} & a_{13} \\ a_{32} & a_{33} \end{vmatrix} & +\begin{vmatrix} a_{12} & a_{13} \\ a_{22} & a_{23} \end{vmatrix} \\ \\ -\begin{vmatrix} a_{21} & a_{23} \\ a_{31} & a_{33} \end{vmatrix} & +\begin{vmatrix} a_{11} & a_{13} \\ a_{31} & a_{33} \end{vmatrix} & -\begin{vmatrix} a_{11} & a_{13} \\ a_{21} & a_{23} \end{vmatrix} \\ \\ +\begin{vmatrix} a_{21} & a_{22} \\ a_{31} & a_{32} \end{vmatrix} & -\begin{vmatrix} a_{11} & a_{12} \\ a_{31} & a_{32} \end{vmatrix} & +\begin{vmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{vmatrix} \end{bmatrix} adj(A)= + a22a32a23a33 a21a31a23a33 + a21a31a22a32 a12a32a13a33 + a11a31a13a33 a11a31a12a32 + a12a22a13a23 a11a21a13a23 + a11a21a12a22

其中
∣ a i m a i n a j m a j n ∣ = d e t [ a i m a i n a j m a j n ] = d e t ∣ a i m a i n a j m a j n ∣ \begin{vmatrix} a_{im} & a_{in} \\ a_{jm} & a_{jn} \end{vmatrix} =det \begin{bmatrix} a_{im} & a_{in} \\ a_{jm} & a_{jn} \end{bmatrix}=det \begin{vmatrix} a_{im} & a_{in} \\ a_{jm} & a_{jn} \end{vmatrix} aimajmainajn =det[aimajmainajn]=det aimajmainajn

从上面公式可以看出,伴随矩阵是余因子矩阵的转置。

伴随矩阵可以用来计算矩阵的逆:
A − 1 = a d j ( A ) d e t ( A ) = A ∗ ∣ A ∣ \bm{A}^{-1}=\cfrac{adj(\bm{A})}{det(\bm{A})}=\cfrac{\bm{A}^*}{|\bm{A}|} A1=det(A)adj(A)=AA
其中 A ∗ \bm{A}^* A为伴随矩阵; ∣ A ∣ |\bm{A}| A为矩阵的行列式。

其中行列式计算可以参考我的blog
https://blog.csdn.net/weixin_43851636/article/details/125999210?spm=1001.2014.3001.5502

下面是通过伴随矩阵计算矩阵的逆的C++代码,它和Eigen库中的求逆一样。

c++代码

#include<Eigen/Eigen>
#include<iostream>
#include<vector>
#include<string>

/*
m=[n1,
   n2,
   n3]
*/
Eigen::Matrix3f ConstructMatrix3fFromVectors(Eigen::Vector3f& n1, Eigen::Vector3f& n2, Eigen::Vector3f& n3)
{
    Eigen::Matrix3f m;
    m.block<1, 3>(0, 0) = n1;
    m.block<1, 3>(1, 0) = n2;
    m.block<1, 3>(2, 0) = n3;
    return m;
}

Eigen::Matrix3f ConstructAdjugateMatrix3f(Eigen::Matrix3f& m)
{
    Eigen::Matrix3f adju_m;
    adju_m(0, 0) = m(1, 1)*m(2, 2) - m(2, 1)*m(1, 2);
    adju_m(0, 1) = -(m(0, 1)*m(2, 2) - m(2, 1)*m(0, 2));
    adju_m(0, 2) = m(0, 1)*m(1, 2) - m(1, 1)*m(0, 2);
    adju_m(1, 0) = -(m(1, 0)*m(2, 2) - m(2, 0)*m(1, 2));
    adju_m(1, 1) = m(0, 0)*m(2, 2) - m(2, 0)*m(0, 2);
    adju_m(1, 2) = -(m(0, 0)*m(1, 2) - m(1, 0)*m(0, 2));
    adju_m(2, 0) = m(1, 0)*m(2, 1) - m(2, 0)*m(1, 1);
    adju_m(2, 1) = -(m(0, 0)*m(2, 1) - m(2, 0)*m(0, 1));
    adju_m(2, 2) = m(0, 0)*m(1, 1) - m(1, 0)*m(0, 1);
    return adju_m;
}

Eigen::Vector3f ComputeKVector(Eigen::Matrix3f& adjm, Eigen::Vector3f& b)
{
    Eigen::Vector3f k;
    k = adjm*b;
    return k;
}

//test adjugate matrix

int main(int argc, char** argv)
{
    Eigen::Vector3f n1 = Eigen::Vector3f(1, 2, 3);
    Eigen::Vector3f n2 = Eigen::Vector3f(2, 1, 3);
    Eigen::Vector3f n3 = Eigen::Vector3f(2, 2, 1);
    Eigen::Matrix3f m = ConstructMatrix3fFromVectors(n1, n2, n3);
    Eigen::Matrix3f m_i = m.inverse();
    std::cerr << "m_i: \n" << m_i << std::endl;
    Eigen::Matrix3f adju_m = ConstructAdjugateMatrix3f(m);
    float det = m.determinant();
    Eigen::Matrix3f m_i_my = adju_m/det;
    std::cerr << "m_i_my: \n" << m_i_my << std::endl;

    std::cerr<<"end test..."<<std::endl;
    return 0;
}

运行的结果如下:它和eigen计算一样的。
在这里插入图片描述

贴上维基百科的超链接为:
https://zh.m.wikipedia.org/zh-sg/%E4%BC%B4%E9%9A%8F%E7%9F%A9%E9%98%B5

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值