简单的线性代数与几何

这篇具有很好参考价值的文章主要介绍了简单的线性代数与几何。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简单的线性代数与几何

最后编辑于 2024-01-04

本文中所有作为下标的代数均为正整数

向量 Vector

存储

向量是表示方向的量, 在不同维度的下向量的数据长度有所不同;
记录时以轴的顺序记录在不同轴上的坐标 : { x(第0轴的坐标) , y(第1轴的坐标), z(第2轴的坐标)…}
代码中使用数值的指针并携带长度属性代替大部分的向量参数, 例 :

    // 向量模长
    var mag(Idx_VM length, var*& vec);

向量的基本运算

模 mag
  • 向量的模(mag)是指向量的坐标到原点的距离, 用勾股定理即可求;
  • 2D向量(x,y) 的模(mag) : $$ mag=\sqrt{x2+y2} $
  • n维度向量 v = ( v 0 , v 1 , v 2 , . . . , v n − 1 ) v=(v_0,v_1,v_2,...,v_{n-1}) v=(v0,v1,v2,...,vn1) 的模(mag) :
    m a g = ∣ v ∣ = ∑ i = 0 n − 1 v i 2 mag=|v|=\sqrt{\sum_{i=0}^{n-1}{{v_i}^2}} mag=v=i=0n1vi2
  • var mag(Idx_VM length, var*& vec){
        var rtn_squares=0;
        for(Idx_VM i=0; i<length; ++i) rtn_squares+=vec[i]*vec[i];
        return sqrt(rtn_squares);
    }
    
向量加减 sum / dif
  • 向量加减在几何上表示原向量正向或反向平移偏移量后得到新向量, 在运算时只需要将所有对应维度的值相加或相减
  • 原向量:( v 0 = ( v 0 0 , v 0 1 , v 0 2 , . . . , v 0 n − 1 ) v_0=(v_{0_0} , v_{0_1} , v_{0_2} , ... , v_{0_{n-1}}) v0=(v00,v01,v02,...,v0n1) )
    偏移量:( v 1 = ( v 1 0 , v 1 1 , v 1 2 , . . . , v 1 n − 1 ) v_1=(v_{1_0} , v_{1_1} , v_{1_2} , ... , v_{1_{n-1}}) v1=(v10,v11,v12,...,v1n1) )
    新向量:
    F s u m ( v 0 , v 1 ) = v 0 + v 1 = ( v 0 0 + v 1 0 , v 0 1 + v 1 1 , v 0 2 + v 1 2 , . . . , v 0 n − 1 + v 1 n − 1 ) F_{sum}(v_0,v_1)=v_0+v_1=(v_{0_0}+v_{1_0}, v_{0_1}+v_{1_1}, v_{0_2}+v_{1_2}, ... , v_{0_{n-1}}+v_{1_{n-1}}) Fsum(v0,v1)=v0+v1=(v00+v10,v01+v11,v02+v12,...,v0n1+v1n1)
    F d i f ( v 0 , v 1 ) = v 0 − v 1 = ( v 0 0 − v 1 0 , v 0 1 − v 1 1 , v 0 2 − v 1 2 , . . . , v 0 n − 1 − v 1 n − 1 ) F_{dif}(v_0,v_1)=v_0-v_1=(v_{0_0}-v_{1_0}, v_{0_1}-v_{1_1}, v_{0_2}-v_{1_2}, ... , v_{0_{n-1}}-v_{1_{n-1}}) Fdif(v0,v1)=v0v1=(v00v10,v01v11,v02v12,...,v0n1v1n1)
  • void sum(var*& out, Idx_VM length, var*& vec_0, var*& vec_1){
        for(Idx_VM i=0; i<length; ++i) out[i]=vec_0[i]+vec_1[i];
    }
    void dif(var*& out, Idx_VM length, var*& vec_0, var*& vec_1){
        for(Idx_VM i=0; i<length; ++i) out[i]=vec_0[i]-vec_1[i];
    }
    
向量乘标量 np
  • 向量乘标量在几何上表示多个相同的向量相加, 在运算时只需要将所有维度的值乘以标量
  • 原向量: ( v = ( v 0 0 , v 0 1 , v 0 2 , . . . , v 0 n − 1 ) v=(v_{0_0} , v_{0_1} , v_{0_2} , ... , v_{0_n-1}) v=(v00,v01,v02,...,v0n1) ) 乘以标量 ( k k k )
    新向量:
    F n p ( k , v ) = k v = ( k v 0 0 , k v 0 1 , k v 0 2 , . . . , k v 0 n − 1 ) F_{np}(k,v)=kv=(kv_{0_0} , kv_{0_1} , kv_{0_2} , ... , kv_{0_n-1}) Fnp(k,v)=kv=(kv00,kv01,kv02,...,kv0n1)
  •   void np(var*& vec, Idx_VM length, var k){
          for(Idx_VM i=0; i<length; ++i) vec[i]*=k;
      }
    
向量点积 dot
  • 向量点积计算时需要将两个向量所有对应维度相乘后再相加
  • 向量0:( v 0 = ( v 0 0 , v 0 1 , v 0 2 , . . . , v 0 n − 1 ) v_0=(v_{0_0} , v_{0_1} , v_{0_2} , ... , v_{0_n-1}) v0=(v00,v01,v02,...,v0n1) )
    向量1:( v 1 = ( v 1 0 , v 1 1 , v 1 2 , . . . , v 1 n − 1 ) v_1=(v_{1_0} , v_{1_1} , v_{1_2} , ... , v_{1_n-1}) v1=(v10,v11,v12,...,v1n1) )
    向量点积 :
    F d o t ( v 0 , v 1 ) = v 0 ⋅ v 1 = ∑ i = 0 n − 1 v 0 i v 1 i F_{dot}(v_0,v_1)=v_0·v_1=\sum_{i=0}^{n-1}{v_{0_i}v_{1_i}} Fdot(v0,v1)=v0v1=i=0n1v0iv1i
  • 向量点积的几何应用 :
    • 点积可以表示点在另一个点上的投影系数(t)与模的乘积 : d o t = t 1 ∣ v 1 ∣ dot=t_1|v_1| dot=t1v1 ;
    • 由此可以用于计算点( v 0 v_0 v0 )在另一个点( v 1 v_1 v1 )上的投影的坐标( v v v ) :
      F p r o j e c t i o n ′ p o i n t ( v 0 , v 1 ) = ( v 0 ⋅ v 1 ) ∣ v 1 ∣ F_{projection'point}(v_0,v_1)=\frac{(v_0·v_1)}{|v_1|} Fprojectionpoint(v0,v1)=v1(v0v1)
    • 使用点积计算两个向量夹角的cos值
      F c o s Θ ( v 0 , v 1 ) = ( v 0 ⋅ v 1 ) ∣ v 0 ∣ ∣ v 1 ∣ F_{cosΘ}(v_0,v_1)=\frac{(v_0·v_1)}{|v_0||v_1|} FcosΘ(v0,v1)=v0∣∣v1(v0v1)
向量叉积 cross
  • 向量叉积仅适用于2D或3D中
  • 几何意义和公式
    • 叉积表示一个向量以某方向旋转到另一个向量时的旋转轴

    • 当叉积为0时, 表示两个向量处于同一直线上

    • 2D 叉积, 旋转轴总是在一个虚构的z轴上, 所以直接可以使用一个标量表示, 以叉积的正负表示旋转方向;
      起始向量(叉积左向量) ( v 0 v_0 v0 ), 终点向量(叉积右向量) { v 1 v_1 v1 }
      F c r o s s ( v 0 , v 1 ) = v 0 × v 1 = v 0 x v 1 y − v 0 y v 1 x F_{cross}(v_0,v_1)=v_0×v_1=v_{0_x}v_{1_y}-v_{0_y}v_{1_x} Fcross(v0,v1)=v0×v1=v0xv1yv0yv1x

      +y
      ^ 
      |*v_0 {1,2}
      |
      |     *v_1 {2,1}
      +------------> +x
      
      此处有两点处于坐标系中, 其中x在水平方向的右方向, y在垂直方向的上方向, 虚拟的z在注视内容时的前方向; 
      v_0={1,2}, v_1={2,1}; cross=1*1-2*2=-3;
      此时叉积值为负数, v_0->v_1为顺时针
      
    • 3D 叉积, 叉积为一个新的向量, 表示旋转时的旋转轴
      起始向量(叉积左向量) ( v 0 v_0 v0 ), 终点向量(叉积右向量) { v 1 v_1 v1 }
      F c r o s s ( v 0 , v 1 ) = v 0 × v 1 = ( v 0 y v 1 z − v 0 z v 1 y v 0 z v 1 x − v 0 x v 1 z v 0 x v 1 y − v 0 y v 1 x ) F_{cross}(v_0,v_1)=v_0×v_1=\begin{pmatrix} v_{0_y}v_{1_z} - v_{0_z}v_{1_y} \\ v_{0_z}v_{1_x} - v_{0_x}v_{1_z} \\ v_{0_x}v_{1_y} - v_{0_y}v_{1_x} \\ \end{pmatrix} Fcross(v0,v1)=v0×v1= v0yv1zv0zv1yv0zv1xv0xv1zv0xv1yv0yv1x

矩阵 Matrix

存储

代码中使用数值的指针并携带宽高属性代替大部分的矩阵参数, 例 :

    // 设置单位矩阵
    var*& setup_Matrix__Identity(var*& out, Idx_VM width, Idx_VM height);
  • 下标位置
    • 本文中, 矩阵下标通常以水平坐标 (u) 和垂直坐标 (v) 表示 ( M u , v M_{u,v} Mu,v ) , 本文中所有下标均以0为起点;
      如此矩阵M中0列2行的值 M 0 , 2 M_{0,2} M0,2 = 6
      M = ( M 0 , 0 , M 1 , 0 , M 2 , 0 M 0 , 1 , M 1 , 1 , M 2 , 1 M 0 , 2 , M 1 , 2 , M 2 , 2 ) = ( 0 , 1 , 2 3 , 4 , 5 6 , 7 , 8 ) M= \begin{pmatrix} M_{0,0}, M_{1,0}, M_{2,0}\\ M_{0,1}, M_{1,1}, M_{2,1}\\ M_{0,2}, M_{1,2}, M_{2,2}\\ \end{pmatrix} = \begin{pmatrix} 0,1,2\\ 3,4,5\\ 6,7,8\\ \end{pmatrix} M= M0,0,M1,0,M2,0M0,1,M1,1,M2,1M0,2,M1,2,M2,2 = 0,1,23,4,56,7,8

    • 物理数据下标计算, 需要宽度参数(w), 水平坐标(u), 垂直坐标(v) : $$ F_i(w,u,v)=v*w+u $

    • 对角线位置, 水平坐标与垂直坐标相同的位置 $$ M_{i,i} $文章来源地址https://www.toymoban.com/news/detail-787097.html

部分特殊的矩阵

  • 方阵
    • 宽度和高度相同的矩阵
  • 零矩阵
    • 特征为 矩阵中所有数值均为0
  • 单位矩阵
    • 特征为 矩阵中除了对角线上的数值为1 ( M i , i = 1 M_{i,i} = 1 Mi,i=1 ), 其他数值均为0
  • 正交矩阵
    • 特征为 对角线位置的值为 1, 且除了对角线位置以外的值都满足 $$ M_{u,v} = -M_{v,u} $
  • 上/下 三角矩阵
    • 特征为对角线上方或下方所有值为0
      ( v ∈ [ 0 , u ) ) & ( M u , v = 0 ) (v\in[0,u))\&(M_{u,v}=0) (v[0,u))&(Mu,v=0)
      ( v ∈ ( u , w ] ) & ( M u , v = 0 ) (v\in(u,w])\&(M_{u,v}=0) (v(u,w])&(Mu,v=0)

矩阵部分计算

矩阵乘法
  • 矩阵乘法需要左矩阵的宽度与右矩阵的高度相同, 新矩阵的宽为右矩阵的宽, 高为左矩阵的高
  • 进行矩阵乘法时有顺序要求, 而且不满足乘法交换律;
  • 执行乘法时为左行乘右列, 新矩阵的每个值都是左矩阵的对应行与右矩阵的对应列的点积
  • A=左矩阵, B=右矩阵; l=左矩阵宽度=右矩阵高度; h=左矩阵高度, w=右矩阵宽度; F g e t R o w ( M , v ) F_{getRow}(M,v) FgetRow​(M,v) 和 F g e t C o l ( M , u ) F_{getCol}(M,u) FgetCol​(M,u) 分别为取矩阵行与取矩阵列 $$ F_{Multiplication}(A,B)= \begin{pmatrix} A_{0,0},A_{1,0}, \dots ,A_{l-1,0} \ A_{0,1},A_{1,1}, \dots ,A_{l-1,1} \ \vdots\ A_{0,h-1},A_{1,h-1}, \dots ,A_{l-1,h-1} \ \end{pmatrix} \begin{pmatrix} B_{0,0},B_{1,0}, \dots ,B_{w-1,0} \ B_{0,1},B_{1,1}, \dots ,B_{w-1,1} \ \vdots\ B_{0,l-1},B_{1,l-1}, \dots ,B_{w-1,l-1} \ \end{pmatrix}\ \quad\

    \begin{pmatrix}
    F_{getrow}(A,0)·F_{getCol}(B,0), F_{getrow}(A,0)·F_{getCol}(B,1), \dots ,F_{getrow}(A,0)·F_{getCol}(B,w-1)\
    F_{getrow}(A,1)·F_{getCol}(B,0), F_{getrow}(A,1)·F_{getCol}(B,1), \dots ,F_{getrow}(A,1)·F_{getCol}(B,w-1)\
    \vdots\
    F_{getrow}(A,h-1)·F_{getCol}(B,0), F_{getrow}(A,h-1)·F_{getCol}(B,1), \dots ,F_{getrow}(A,h-1)·F_{getCol}(B,w-1)\
    \end{pmatrix}
    $$
矩阵转置
  • 矩阵转置就是把矩阵的水平方向和垂直方向交换, 新矩阵的高度为原矩阵的宽度, 新矩阵的宽度为原矩阵的高度
    F t r a n s p o s i t i o n ( M ) = M t = ( M 0 , 0 , M 1 , 0 , … , M w − 1 , 0 M 0 , 1 , M 1 , 1 , … , M w − 1 , 1 ⋮ M 0 , h − 1 , M 1 , h − 1 , … , M w − 1 , h − 1 ) t = ( M 0 , 0 , M 0 , 1 , … , M 0 , h − 1 M 1 , 0 , M 1 , 1 , … , M 1 , h − 1 ⋮ M w − 1 , 0 , M w − 1 , 1 , … , M w − 1 , h − 1 ) F_{transposition}(M)=M^t= \begin{pmatrix} M_{0,0},M_{1,0}, \dots ,M_{w-1,0} \\ M_{0,1},M_{1,1}, \dots ,M_{w-1,1} \\ \vdots\\ M_{0,h-1},M_{1,h-1}, \dots ,M_{w-1,h-1} \\ \end{pmatrix}^t= \begin{pmatrix} M_{0,0},M_{0,1}, \dots ,M_{0,h-1} \\ M_{1,0},M_{1,1}, \dots ,M_{1,h-1} \\ \vdots\\ M_{w-1,0},M_{w-1,1}, \dots ,M_{w-1,h-1} \\ \end{pmatrix} Ftransposition(M)=Mt= M0,0,M1,0,,Mw1,0M0,1,M1,1,,Mw1,1M0,h1,M1,h1,,Mw1,h1 t= M0,0,M0,1,,M0,h1M1,0,M1,1,,M1,h1Mw1,0,Mw1,1,,Mw1,h1
基本变换
  • 基本变换分为 换行/ 换列 / 行乘标量 / 列乘标量
  • 具体代码实现请翻阅代码 NML_Matrix.hpp , NML_Matrix.cpp
矩阵行列式
  • 矩阵行列式计算时要求矩阵应该是方阵
  • 矩阵行列式几何意义上用于表示线性变换对原对象的规模(体积/面积)影响, 如原对象的体积为 v , 使用变换矩阵的行列式为 d, 则变换后的对象体积为 v·d
  • 本文中, 计算矩阵行列式时使用两种方法, 分别为对 4 阶以及更小规模的方阵使用化简后的快速计算公式, 以及更高阶矩阵使用高斯消元法进行计算
  • 快速计算公式:
    • 2阶方阵行列式快速计算公式
      M = ( m 0 , m 1 m 2 , m 3 ) F d e t 2 ( M ) = ∣ M ∣ = m 0 m 3 − m 1 m 2 ; M=\begin{pmatrix} m_0,m_1 \\ m_2,m_3 \\ \end{pmatrix} \\ \quad \\ F_{det2}(M) = |M| = m_0m_3-m_1m_2; M=(m0,m1m2,m3)Fdet2(M)=M=m0m3m1m2;
    • 3阶方阵行列式快速计算公式
      M = ( m 0 , m 1 , m 2 m 3 , m 4 , m 5 m 6 , m 7 , m 8 ) F d e t 3 ( M ) = ∣ M ∣ = m 0 ( m 4 m 8 − m 5 m 7 ) − m 1 ( m 3 m 8 − m 5 m 6 ) + m 2 ( m 3 m 7 − m 4 m 6 ) ; M=\begin{pmatrix} m_0,m_1,m_2 \\ m_3,m_4,m_5 \\ m_6,m_7,m_8 \\ \end{pmatrix} \\ \quad \\ F_{det3}(M) = |M| = \\ m_0(m_4m_8 - m_5m_7) - \\ m_1(m_3m_8 - m_5m_6) + \\ m_2(m_3m_7 - m_4m_6) ;\quad M= m0,m1,m2m3,m4,m5m6,m7,m8 Fdet3(M)=M=m0(m4m8m5m7)m1(m3m8m5m6)+m2(m3m7m4m6);
    • 4阶方阵行列式快速计算公式
      M = ( m 0 , m 1 , m 2 , m 3 m 4 , m 5 , m 6 , m 7 m 8 , m 9 , m 10 , m 11 m 12 , m 13 , m 14 , m 15 ) t e m p = ( t 0 = m 0 ∗ m 5 − m 1 ∗ m 4 t 1 = m 0 ∗ m 6 − m 2 ∗ m 4 t 2 = m 0 ∗ m 7 − m 3 ∗ m 4 t 3 = m 1 ∗ m 6 − m 2 ∗ m 5 t 4 = m 1 ∗ m 7 − m 3 ∗ m 5 t 5 = m 2 ∗ m 7 − m 3 ∗ m 6 t 6 = m 8 ∗ m 13 − m 9 ∗ m 12 t 7 = m 8 ∗ m 14 − m 10 ∗ m 12 t 8 = m 8 ∗ m 15 − m 11 ∗ m 12 t 9 = m 9 ∗ m 14 − m 10 ∗ m 13 t 10 = m 9 ∗ m 15 − m 11 ∗ m 13 t 11 = m 10 ∗ m 15 − m 11 ∗ m 14 ) F d e t 4 ( M ) = ∣ M ∣ = t 0 t 11 − t 1 t 10 + t 2 t 9 + t 3 t 8 − t 4 t 7 + t 5 t 6 ; M=\begin{pmatrix} m_{0},m_{1},m_{2},m_{3} \\ m_{4},m_{5},m_{6},m_{7} \\ m_{8},m_{9},m_{10},m_{11} \\ m_{12},m_{13},m_{14},m_{15} \\ \end{pmatrix} \\ \quad \\ temp=\begin{pmatrix} t_{0} = m_{0} * m_{5} - m_{1} * m_{4} \\ t_{1} = m_{0} * m_{6} - m_{2} * m_{4} \\ t_{2} = m_{0} * m_{7} - m_{3} * m_{4} \\ t_{3} = m_{1} * m_{6} - m_{2} * m_{5} \\ t_{4} = m_{1} * m_{7} - m_{3} * m_{5} \\ t_{5} = m_{2} * m_{7} - m_{3} * m_{6} \\ t_{6} = m_{8} * m_{13} - m_{9} * m_{12} \\ t_{7} = m_{8} * m_{14} - m_{10} * m_{12} \\ t_{8} = m_{8} * m_{15} - m_{11} * m_{12} \\ t_{9} = m_{9} * m_{14} - m_{10} * m_{13} \\ t_{10} = m_{9} * m_{15} - m_{11} * m_{13} \\ t_{11} = m_{10} * m_{15} - m_{11} * m_{14} \\ \end{pmatrix} \\ \quad \\ F_{det4}(M) = |M| = t_{0}t_{11} - t_{1}t_{10} + t_{2}t_{9} + t_{3}t_{8} - t_{4}t_{7} + t_{5}t_{6} ; M= m0,m1,m2,m3m4,m5,m6,m7m8,m9,m10,m11m12,m13,m14,m15 temp= t0=m0m5m1m4t1=m0m6m2m4t2=m0m7m3m4t3=m1m6m2m5t4=m1m7m3m5t5=m2m7m3m6t6=m8m13m9m12t7=m8m14m10m12t8=m8m15m11m12t9=m9m14m10m13t10=m9m15m11m13t11=m10m15m11m14 Fdet4(M)=M=t0t11t1t10+t2t9+t3t8t4t7+t5t6;
  • n阶方阵(M) 消元法求行列式步骤
    M = ( A 0 , 0 , A 1 , 0 , … , A n − 1 , 0 A 0 , 1 , A 1 , 1 , … , A n − 1 , 1 ⋮ A 0 , n − 1 , A 1 , n − 1 , … , A n − 1 , n − 1 ) M= \begin{pmatrix} A_{0,0},A_{1,0}, \dots ,A_{n-1,0} \\ A_{0,1},A_{1,1}, \dots ,A_{n-1,1} \\ \vdots\\ A_{0,n-1},A_{1,n-1}, \dots ,A_{n-1,n-1} \\ \end{pmatrix} M= A0,0,A1,0,,An1,0A0,1,A1,1,,An1,1A0,n1,A1,n1,,An1,n1
    • 使用基本变换和消元, 从左上开始, 右下结束 ( i = 0 ; i ∈ [ 0 , n ) ; i + = 1 i=0; i\in[0,n); i+=1 i=0;i[0,n);i+=1 )
      • M i , i = 0 M_{i,i}=0 Mi,i=0 时, 向下查找并尝试使用矩阵基本变换的换行操作使 M i , i ≠ 0 M_{i,i}\not=0 Mi,i=0 ; 如果无法完成, 则矩阵行列式为 0
      • 缓存矩阵M的第i行上所有值与 1 M i , i \frac{1}{M_{i,i}} Mi,i1 的积
        t = ( A 0 , 0 M i , i , A 1 , 0 M i , i , . . . , A w − 1 , 0 M i , i ) t=(\frac{A_{0,0}}{M_{i,i}},\frac{A_{1,0}}{M_{i,i}},...,\frac{A_{w-1,0}}{M_{i,i}})\\ t=(Mi,iA0,0,Mi,iA1,0,...,Mi,iAw1,0)
      • j ∈ ( i , n ) j\in(i,n) j(i,n) , 将矩阵的所有j行与t的倍数相加, 使 M i , j = 0 M_{i,j} = 0 Mi,j=0
      • 回到第一步, 再次计算直到完成结束条件
    • 最后会得到一个上三角矩阵 ( M ′ M' M ), 矩阵的行列式为该上三角矩阵的对角线上的值的乘积
      d e t = ∏ i = 0 n M i , i ′ det=\prod_{i=0}^n M'_{i,i} det=i=0nMi,i
  • n阶方阵(M) 消元法求行列式代码实现
    
    /** 
     * @brief 将矩阵某个为0的项 通过初等变换的换行操作, 变成非0
        * 
        * @param  mat          矩阵数据
        * @param  length       矩阵数据长度
        * @param  width        矩阵宽度
        * @param  index        当前下标
        * @param  v            当前v坐标(行下标)
        * @param  step_length  寻址步长, $1为  ±width
        * @return 返回是否成功换行
        */
    bool transformation__ExchangeRow_ToUnZero(var*& mat, Idx_VM length, Idx_VM width, Idx_VM index, Idx_VM v, Idx_VM step_length){
        Idx_VM f=step_length>0?1:-1;
        Idx_VM v_target=v+f;
        for(Idx_VM i=index+step_length;  i>=0&&i<length;  i+=step_length, v_target+=f){
            if(check_Zero(mat[i])){
                // transformation__ExchangeRow 是初等变换的换行操作, 具体实现请翻阅代码 NML_Matrix.hpp , NML_Matrix.cpp 
                transformation__ExchangeRow(mat, width, v, v_target);
                return true;
            }
        }
        return false;
    }
    
    /**
     * @brief 使用初等变换计算行列式;
        * 应在n>4时才使用, n<4时推荐使用 calc_Det__${n}
        * 
        * @param mat       矩阵数据 (必须是方阵)
        * @param n         表示这个矩阵是n*n方矩阵
        * @return 返回计算的行列式值 
        */
    var calc_Det__Transformation(var*& mat, Idx_VM n){
        const Idx_VM length=n*n;
        var *temp_mat=create_Values__Clone(mat, length);
        var temp, det=1;
        Idx_VM _n=n-1;
    
        for(Idx_VM uv=0; uv<_n; ++uv){
            Idx_VM index_v=uv*n;
            Idx_VM index_mat__uv=index_v+uv;
            
            if(check_Zero(temp_mat[index_mat__uv])){    // 换行
                if(!transformation__ExchangeRow_ToUnZero(temp_mat, length, n, index_mat__uv, uv, n)){
                    delete temp_mat;
                    return 0;
                }
                else det=-det;
            }
            
            // 消元
            for(Idx_VM index=index_mat__uv+n;  index<length;  index+=n){
                temp=(temp_mat[index])/temp_mat[index_mat__uv];
                for(Idx_VM i=uv+1, j=index+1;  i<n;  ++i, ++j){
                    temp_mat[j]-=temp*temp_mat[index_v+i];
                }
            }
            det*=temp_mat[index_mat__uv];
        }
        det*=temp_mat[length-1];
    
        delete temp_mat;
    
        return det;
    }
        
    
余子式 / 代数余子式 / 标准伴随矩阵
  • 原矩阵中剔除某个元素的行和列后余剩的其他元素称为余子式矩阵, 余子式矩阵的宽高为原矩阵的宽高减一, 这个矩阵的行列式就是余子式
  • 代数余子式 = 余子式 * $$ -1^{u+v} $
  • 例 :
    原矩阵 M = ( M 0 , 0 , M 1 , 0 , M 2 , 0 M 0 , 1 , M 1 , 1 , M 2 , 1 M 0 , 2 , M 1 , 2 , M 2 , 2 ) 矩阵 M 的元素 M 0 , 0 的余子式矩阵 Q = ( M 1 , 1 , M 2 , 1 M 1 , 2 , M 2 , 2 ) 矩阵 M 的元素 M 0 , 0 的代数余子式 = ( − 1 ) 0 + 0 Q 原矩阵M= \begin{pmatrix} M_{0,0}, M_{1,0}, M_{2,0}\\ M_{0,1}, M_{1,1}, M_{2,1}\\ M_{0,2}, M_{1,2}, M_{2,2}\\ \end{pmatrix} \\ \quad \\ 矩阵M的元素M_{0,0}的余子式矩阵 Q= \begin{pmatrix} M_{1,1}, M_{2,1}\\ M_{1,2}, M_{2,2}\\ \end{pmatrix} \\ \quad \\ 矩阵M的元素M_{0,0}的代数余子式 = (-1)^{0+0}Q 原矩阵M= M0,0,M1,0,M2,0M0,1,M1,1,M2,1M0,2,M1,2,M2,2 矩阵M的元素M0,0的余子式矩阵Q=(M1,1,M2,1M1,2,M2,2)矩阵M的元素M0,0的代数余子式=(1)0+0Q
  • 原矩阵中的每个值的代数余子式组成一个新的矩阵就是标准伴随矩阵 ( a d j ( M ) adj(M) adj(M) );
矩阵的逆
  • 矩阵的逆和行列式一样, 计算时要求矩阵应该是方阵; 当矩阵的行列式=0 时, 逆矩阵不存在
  • 矩阵 ( M M M ) 的逆 (逆矩阵) ( M − 1 M^{-1} M1 ) , 原矩阵和逆矩阵相乘会得到一个单位矩阵 ( I I I ); 几何意义上逆矩阵用于还原一个进行过线性变换的对象
    M − 1 m = M M − 1 = I M^{-1}m=MM^{-1}=I M1m=MM1=I
  • 本文中求矩阵的逆由两种方式组成, 分别为对 4 阶以下的方阵使用 标准伴矩阵 / 行列式 ( a d j ( M ) ∣ M ∣ \frac{adj(M)}{|M|} Madj(M) ) 进行比较简单的计算 , 以及对更高阶的矩阵使用高斯消元法
  • 高斯消元法 求逆矩阵操作与求行列式有些相似之处; 步骤如下
    • 建立增广矩阵 ( M ′ M' M ), 初始化为与原规模相同的单位矩阵
    • 从原矩阵左上开始, 右下结束 ( i = 0 ; i ∈ [ 0 , n ) ; i + = 1 i=0; i\in[0,n); i+=1 i=0;i[0,n);i+=1 )
      • M i , i = 0 M_{i,i}=0 Mi,i=0 时, 向下查找并尝试使用矩阵基本变换的换行操作使 M i , i M_{i,i} Mi,i 为同列元素中绝对值最大的 ; 如果无法满足 $$ M_{i,i}\in=0 $, 则矩阵行列式为 0, 逆矩阵不存在
      • 缓存 M 和 M’ 的第i行上所有值与 1 M i , i \frac{1}{M_{i,i}} Mi,i1 的积
      • ( j ≠ i ) & j ∈ [ 0 , n ) (j\not=i)\&j\in[0,n) (j=i)&j[0,n) , 将矩阵的所有j行与t的倍数相加, 使 M i , j = 0 M_{i,j} = 0 Mi,j=0
      • 回到第一步, 再次计算直到完成结束条件
    • 计算完成后, M 将会变成单位矩阵, 而 M’ 就是原矩阵的逆
  • 消元法求逆矩阵代码实现
    
    /** 
     * @brief 寻找最大主元并换行; 换行将副作用到其他矩阵上
        * 
        * @param  mats         矩阵数据集合
        * @param  length_g     有多少个矩阵
        * @param  length       每个矩阵长度
        * @param  width        矩阵宽度
        * @param  index        当前下标
        * @param  v            当前v坐标(行下标)
        * @param  step_length  寻址步长, $1为  ±width
        * @param  _index_m     传入多个矩阵时使用哪个矩阵的值 默认0
        * @return 返回是否成功换行
        */
    bool transformation__ExchangeRow_PivotToMax(var**& mats, Idx_VM length_g, Idx_VM length, Idx_VM width, Idx_VM index, Idx_VM v, Idx_VM step_length, Idx_VM _index_m){
        Idx_VM f=step_length>0?1:-1;
        Idx_VM v_target=v+f;
        
        Idx_VM max_row=v;
        Idx_VM max_row_pivot_index=index;
        for(Idx_VM i=index+step_length;  i>=0&&i<length;  i+=step_length, v_target+=f){
            if(mats[_index_m][max_row_pivot_index]<mats[_index_m][i]){
                max_row_pivot_index=i;
                max_row=v_target;
            }
        }
        if(check_Zero(mats[_index_m][max_row_pivot_index])){
            return false;
        }
        if(v!=max_row) transformation__ExchangeRow(mats, length_g, width, v, max_row);
        return true;
    }
    
    
    /**
     * @brief 矩阵求逆 使用初等变换法(高斯乔丹消元法)
        * 
        * @param out       输出目标
        * @param mat       矩阵数据 (必须是方阵)
        * @param n         表示这个矩阵是n*n方阵
        * @return 返回是否成功计算逆矩阵
        */
    bool setup_Matrix__Inverse__Transformation(var*& out, var*& mat, Idx_VM n){
        Idx_VM length=n*n;
        var *temp_mat=create_Values__Clone(mat, length);
        
        // 初始化 out 为增广矩阵
        setup_Matrix__Identity(out, n, n);
        var **mats=new var*[2]{temp_mat, out};
        
        for(Idx_VM uv=0; uv<n; ++uv){
            Idx_VM index_v=uv*n;
            Idx_VM index_mat__uv=index_v+uv;
    
            // 换行设置最大主元
            if(!transformation__ExchangeRow_PivotToMax(mats, 2, length, n, index_mat__uv, uv, n)) {
                delete temp_mat;
                delete mats;
                return false;
            }
            transformation__ScaleRow(mats, 2, n, uv, 1/mats[0][index_mat__uv]);
    
            for(Idx_VM i=0, index=0;  i<n;  ++i, index+=n){
                if(i==uv) continue;
                var k=temp_mat[index+uv];
                for(Idx_VM j=0;  j<n;  ++j){
                    temp_mat[index+j] -= k * temp_mat[index_v+j];
                    out[index+j]      -= k * out     [index_v+j];
                }
            }
        }
    
        delete temp_mat;
        delete mats;
        return true;
    }
    
    

到了这里,关于简单的线性代数与几何的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • [足式机器人]Part3机构运动微分几何学分析与综合Ch03-1 空间约束曲线与约束曲面微分几何学——【读书笔记】

    本文仅供学习使用 本文参考: 《机构运动微分几何学分析与综合》-王德伦、汪伟 《微分几何》吴大任 连杆机构中的连杆与连架杆构成运动副,该运动副元素的 特征点 或 特征线 在 机架坐标系 中的 运动轨迹曲线或曲面 称为 约束曲线 或 约束曲面 ,是联系刚体运动与机构

    2024年02月11日
    浏览(50)
  • Core Animation实战三(图层几何学),【一步教学,一步到位

    //calculate hour hand angle //calculate minute hand angle CGFloat minsAngle = (components.minute / 60.0) * M_PI * 2.0; //calculate second hand angle CGFloat secsAngle = (components.second / 60.0) * M_PI * 2.0; //设置锚点 self.hourLabel.layer.anchorPoint =self.minuteLabel.layer.anchorPoint =self.secondLabel.layer.anchorPoint = CGPointMake(0.5f, 0.9f); //r

    2024年04月25日
    浏览(38)
  • CGAL的三角网格曲面脊线和脐点的近似计算(需要微分几何学的知识)

             脊线(Ridges) :在光滑曲面上,脊线是一种特殊的曲线。沿着这条曲线,曲面的一个主曲率在其曲率线上达到极值(最大或最小)。这意味着脊线是那些曲率发生突变的区域,它们在形状感知、物体识别和计算机图形学中都有重要的应用。         脐点(U

    2024年02月03日
    浏览(45)
  • 【生物力学】《人体骨肌系统生物力学》- 王成焘老师 - 第2章 - 人体几何学测量与仿真建模

    第1章 回到目录 第3章 人体测量学 (anthropometry) 是人类学的一个分支学科,旨在通过对人体整体和局部测量,探讨人体的类型、特征、变异和发展规律。人体几何仿真建模是通过数字化技术构建数字化的人体模型,数字化的人体模型能够精确地再现人体复杂的三维结构,其应用

    2024年02月10日
    浏览(44)
  • 线性代数 - 几何原理

    欢迎阅读这篇关于线性代数的文章。在这里,我们将从一个全新的角度去探索线性代数,不再仅仅局限于数值计算,而是深入理解其背后的几何原理。我们将一起探讨向量、线性变换、矩阵、行列式、点乘、叉乘、基向量等核心概念,以及它们如何在实际问题中发挥作用。无

    2024年02月05日
    浏览(46)
  • 线性代数的本质——几何角度理解

    B站网课来自 3Blue1Brown的翻译版,看完醍醐灌顶,强烈推荐: 线性代数的本质 本课程从几何的角度翻译了线代中各种核心的概念及性质,对做题和练习效果有实质性的提高,下面博主来总结一下自己的理解 在物理中的理解是一个有 起点和终点的方向矢量 ,而在计算机科学中

    2024年02月02日
    浏览(62)
  • 线性代数行列式的几何含义

    行列式可以看做是一系列列向量的排列,并且每个列向量的分量可以理解为其对应标准正交基下的坐标。 行列式有非常直观的几何意义,例如: 二维行列式按列向量排列依次是 a mathbf{a} a 和 b mathbf{b} b ,可以表示 a mathbf{a} a 和 b mathbf{b} b 构成的平行四边形的面积 ∣ a b ∣

    2024年02月11日
    浏览(50)
  • 线性代数克莱姆法则的几何含义

    以二元一次方程组的求解为例: { a c a 1 + b c b 1 = c 1 a c a 2 + b c b 2 = c 2 left{begin{array}{l} a_{c}a_{1} +b_{c}b_{1} =c_{1} \\\\ a_{c}a_{2} +b_cb_{2} =c_{2} end{array}right. { a c ​ a 1 ​ + b c ​ b 1 ​ = c 1 ​ a c ​ a 2 ​ + b c ​ b 2 ​ = c 2 ​ ​ 其中 a c a_c a c ​ 和 b c b_c b c ​ 是我们待求的参数。

    2024年02月12日
    浏览(44)
  • MIT线性代数-方程组的几何解释

    假设有一个方程组 A X = B AX=B A X = B 表示如下 2 x − y = 0 (1) 2x-y=0tag{1} 2 x − y = 0 ( 1 ) − x + 2 y = 3 (2) -x+2y=3tag{2} − x + 2 y = 3 ( 2 ) 矩阵表示如下: [ 2 − 1 − 1 2 ] [ x y ] = [ 0 3 ] (3) begin{bmatrix}2-1\\\\\\\\-12end{bmatrix}begin{bmatrix}x\\\\\\\\yend{bmatrix}=begin{bmatrix}0\\\\\\\\3end{bmatrix}tag{3} ​ 2 − 1 ​

    2024年04月15日
    浏览(46)
  • 使用几何和线性代数从单个图像进行 3D 重建

    使用几何和线性代数从单个图像进行 3D 重建 萨蒂亚         3D重构是一个挑战性题目,而且这个新颖的题目正处于启发和膨胀阶段;因此,各种各样的尝试层出不穷,本篇说明尝试的一种,至于其它更多的尝试,我们在陆续的跟踪中。 图1         以上这3张图片有什

    2024年02月13日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包