1. 特征值和特征向量

1.1 特征向量

假设有一个n行n列的方阵A,有 n 个不相同的特征值为 λ \lambda λ,特征向量为 x 1 , x 2 , ⋯   , x n x_1,x_2,\cdots,x_n x1,x2,,xn.等式如下:
A x i = λ i x i , i = 1 , ⋯   , n → A 2 x = λ 2 x \begin{equation} Ax_i=\lambda_ix_i,i=1,\cdots,n\rightarrow A^2x=\lambda^2x \end{equation} Axi=λixi,i=1,,nA2x=λ2x

  • 特征向量的好处在于,对于向量x来说, A x = λ x Ax=\lambda x Ax=λx,通过左乘矩阵A,还是不改变向量的方向,只是按照 λ \lambda λ倍进行缩放。
    A k x = λ k x \begin{equation} A^kx=\lambda^kx \end{equation} Akx=λkx
  • 对于微分方程来说
    d u d t = A u , e A t = e λ t \begin{equation} \frac{\mathrm{d}u}{\mathrm{d}t}=Au,\mathrm{e}^{At}=\mathrm{e}^{\lambda t} \end{equation} dtdu=AueAt=eλt
  • 通解表示如下:
    u ( t ) = S e Λ t S − 1 u ( 0 ) = e A t u ( 0 ) \begin{equation} u(t)=Se^{\Lambda t} S^{-1} u(0)=e^{At}u(0) \end{equation} u(t)=SeΛtS1u(0)=eAtu(0)

1.2 向量分解

假设矩阵A有n个线性无关的特征向量,那么对于任意矩阵v来说,可以分解为特征向量的线性组合
v = c 1 x 1 + c 2 x 2 + ⋯ + c n x n \begin{equation} v=c_1x_1+c_2x_2+\cdots+c_nx_n \end{equation} v=c1x1+c2x2++cnxn

  • 两边同时乘以 A k , A k x = λ k x A^k,A^{k}x=\lambda^kx Ak,Akx=λkx:
    A k v = c 1 λ 1 k x 1 + c 2 λ 2 k x 2 + ⋯ + c n λ n k x n \begin{equation} A^{k}v=c_1\lambda_1^{k}x_1+c_2\lambda_2^{k}x_2+\cdots+c_n\lambda_n^{k}x_n \end{equation} Akv=c1λ1kx1+c2λ2kx2++cnλnkxn
  • 特征向量在差分方程上的应用
    u k + 1 = A u k → u k = A k u 0 = λ k x u 0 \begin{equation} u_{k+1}=Au_k\rightarrow u_k=A^ku_0=\lambda^kxu_0 \end{equation} uk+1=Aukuk=Aku0=λkxu0

2. 矩阵相似

2.1 特征值求解法-相似

假设我们有两个矩阵A,B如果存在一个可逆矩阵M,满足如下关系,可推出A相似于B
B = M − 1 A M → B ∼ A → A 和 B 有相同的特征值 \begin{equation} B=M^{-1}AM\rightarrow B\sim A\rightarrow A和B有相同的特征值 \end{equation} B=M1AMBAAB有相同的特征值

  • 假设矩阵A的特征值为 λ \lambda λ,特征向量为x,
    ∣ B − λ I ∣ = ∣ M − 1 A M − λ I ∣ = ∣ M − 1 A M − M − 1 λ M ∣ = ∣ M − 1 ∣ ∣ A − λ I ∣ ∣ M ∣ = ∣ A − λ I ∣ \begin{equation} |B-\lambda I|=|M^{-1}AM-\lambda I|=|M^{-1}AM-M^{-1}\lambda M|=|M^{-1}||A-\lambda I||M|=|A-\lambda I| \end{equation} BλI=M1AMλI=M1AMM1λM=M1∣∣AλI∣∣M=AλI
  • 所以可得如下:
    B ∼ A ⇒ λ A = λ B \begin{equation} B \sim A \Rightarrow \lambda_A=\lambda_B \end{equation} BAλA=λB
  • Matlab中如何求解特征值
    对于给定的矩阵A来说,我们用一个可逆矩阵 M 1 M_1 M1右乘矩阵A,左乘 M 1 − 1 M_1^{-1} M11,使得矩阵A逐渐变成上三角矩阵,通过不断地左右乘 M 1 , M 2 M1,M2 M1,M2,最后得到一个上三角矩阵B,这样我们就通过相似的形式得到主对角线上的特征值了。
    B = ( M n ⋯ M 2 M 1 ) − 1 A ( M n ⋯ M 2 M 1 ) → B U p T r i a n g l e ∼ A → A 和 B 有相同的特征值 \begin{equation} B={(M_n\cdots M_2M_1)}^{-1}A{(M_n\cdots M_2M_1)}\rightarrow B_{UpTriangle}\sim A\rightarrow A和B有相同的特征值 \end{equation} B=(MnM2M1)1A(MnM2M1)BUpTriangleAAB有相同的特征值

2.2 特殊特征值

假设我们有两个矩阵A,B,令AB的特征值为 λ A B \lambda_{AB} λAB,特征向量为x,令BA的特征值为 λ B A \lambda_{BA} λBA,证明 λ A B = λ B A \lambda_{AB}=\lambda_{BA} λAB=λBA

  • 根据定义可得:
    A B x = λ A B x \begin{equation} ABx=\lambda_{AB}x \end{equation} ABx=λABx
  • 两边同时乘以B可得:
    B A B x = λ A B B x → ( B A ) ( B x ) = λ A B ( B x ) → λ A B = λ B A \begin{equation} BABx=\lambda_{AB}Bx\rightarrow (BA)(Bx)=\lambda_{AB}(Bx)\rightarrow \lambda_{AB}=\lambda_{BA} \end{equation} BABx=λABBx(BA)(Bx)=λAB(Bx)λAB=λBA

2.3 反对称矩阵

假设我们有一个矩阵A表示如下:
A = [ 0 1 − 1 0 ] → A T = − A \begin{equation} A=\begin{bmatrix} 0&1\\\\ -1&0 \end{bmatrix}\rightarrow A^T=-A \end{equation} A= 0110 AT=A

  • 矩阵A实现的功能是将向量x顺时针旋转90°。
    在这里插入图片描述
  • 求矩阵A的特征值和特征向量如下:
    λ 1 = i , v 1 = [ 1 i ] ; λ 2 = − i , v 1 = [ 1 − i ] ; S = [ 1 1 i − i ] ; Λ = [ i 0 0 − i ] ; \begin{equation} \lambda_1=i,v_1=\begin{bmatrix}1\\\\i\end{bmatrix};\lambda_2=-i,v_1=\begin{bmatrix}1\\\\-i\end{bmatrix};S=\begin{bmatrix}1&1\\\\i&-i\end{bmatrix};\Lambda=\begin{bmatrix}i&0\\\\0&-i\end{bmatrix}; \end{equation} λ1=i,v1= 1i ;λ2=i,v1= 1i ;S= 1i1i ;Λ= i00i ;
  • 分解A如下:
    A = S Λ S − 1 ⇒ [ 0 1 − 1 0 ] = [ 1 1 i − i ] [ i 0 0 − i ] [ 1 1 i − i ] − 1 ; \begin{equation} A=S\Lambda S^{-1}\Rightarrow \begin{bmatrix}0&1\\\\-1&0\end{bmatrix}=\begin{bmatrix}1&1\\\\i&-i\end{bmatrix}\begin{bmatrix}i&0\\\\0&-i\end{bmatrix}\begin{bmatrix}1&1\\\\i&-i\end{bmatrix}^{-1}; \end{equation} A=SΛS1 0110 = 1i1i i00i 1i1i 1;

3.对称矩阵

对称矩阵具有实数特征值和正交的特征向量。我们定义矩阵A如下:
A = [ 0 1 1 0 ] → λ 1 = 1 , v 1 = [ 1 1 ] ; λ 2 = − 1 , v 2 = [ − 1 1 ] ; \begin{equation} A=\begin{bmatrix}0&1\\\\1&0\end{bmatrix}\rightarrow \lambda_1=1,v_1=\begin{bmatrix}1\\\\1\end{bmatrix};\lambda_2=-1,v_2=\begin{bmatrix}-1\\\\1\end{bmatrix}; \end{equation} A= 0110 λ1=1,v1= 11 ;λ2=1,v2= 11 ;

  • 可得如下:
    A = S Λ S − 1 → [ 0 1 1 0 ] = [ 1 1 1 − 1 ] [ 1 0 0 − 1 ] [ 1 1 1 − 1 ] − 1 \begin{equation} A=S\Lambda S^{-1}\rightarrow \begin{bmatrix}0&1\\\\1&0\end{bmatrix}= \begin{bmatrix}1&1\\\\1&-1\end{bmatrix}\begin{bmatrix}1&0\\\\0&-1\end{bmatrix}\begin{bmatrix}1&1\\\\1&-1\end{bmatrix}^{-1} \end{equation} A=SΛS1 0110 = 1111 1001 1111 1

4. Python 代码

  • 代码:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :EValueAndEVector.py
# @Time      :2024/10/19 5:27
# @Author    :Jason Zhang
import numpy as np

np.set_printoptions(suppress=True, precision=3)


class NpEigen(object):
    def __init__(self, Matrix):
        self.matrix = Matrix
        self.N = self.matrix.shape[0]
        self.evalue = np.zeros_like(self.matrix)
        self.evector = np.zeros_like(self.matrix)
        self.init_method()

    def init_method(self):
        self.get_Evalue()
        self.ge_Evector()

    def get_Evalue(self):
        my_evalue, _ = np.linalg.eig(self.matrix)
        my_evalue = np.diag(my_evalue)
        self.evalue = my_evalue
        return my_evalue

    def ge_Evector(self):
        _, my_evector = np.linalg.eig(self.matrix)
        self.evector = my_evector
        return my_evector

    def get_Ak(self, power_k: int):
        temp = self.matrix
        for i in range(power_k):
            temp = self.matrix @ temp

        Ak_evalue, _ = np.linalg.eig(temp)
        Ak_evalue = np.diag(Ak_evalue)
        print(f"A_evalue=\n{self.evalue}")
        A_eigen_power = np.power(self.evalue, power_k + 1)
        print(f"A_eigen_power=\n{A_eigen_power}")
        print(f"Ak_evalue=\n{Ak_evalue}")
        print(f"A_eigen_power is {np.allclose(A_eigen_power, Ak_evalue)} with Ak_evalue")


class SimilarMatrix(object):
    def __init__(self, matrixA, matrixB):
        self.matrixa = matrixA
        self.matrixb = matrixB
        self.matrixAB = self.matrixa @ self.matrixb
        self.matrixBA = self.matrixb @ self.matrixa

    def get_result(self):
        AB_evalue, _ = np.linalg.eig(self.matrixAB)
        AB_evalue = np.diag(AB_evalue)

        BA_evalue, _ = np.linalg.eig(self.matrixBA)
        BA_evalue = np.diag(BA_evalue)
        same = np.allclose(BA_evalue, AB_evalue)
        print("*" * 100)
        print(f"BA_evalue=\n{BA_evalue}\n"
              f"AB_evalue=\n{AB_evalue}\n"
              f"BA_evalue is {same} same for AB_evalue")
        print("*" * 100)


if __name__ == "__main__":
    run_code = 0
    A = np.arange(9).reshape((3, 3))
    B = np.random.randn(3, 3)
    A_eigen = NpEigen(A)
    A_eigen.get_Ak(3)
    ABSimilar = SimilarMatrix(A, B)
    ABSimilar.get_result()
    A_sample = [np.array([[0, 1], [-1, 0]]), np.array([[0, 1], [1, 0]])]
    for i in A_sample:
        Ant_S = i
        Ant_S_evalue, Ant_S_evector = np.linalg.eig(Ant_S)
        Ant_S_evalue = np.diag(Ant_S_evalue)
        Ant_S_evector_inv = np.linalg.inv(Ant_S_evector)
        Check_Ant_S = Ant_S_evector @ Ant_S_evalue @ Ant_S_evector_inv
        print("*"*100)
        print(f"Ant_S=\n{Ant_S}")
        print(f"Check_Ant_S =\n{Check_Ant_S}")
        print(f"Ant_S is {np.allclose(Ant_S, Check_Ant_S)} same for Check_Ant_S")
        print("*"*100)
        print("\n")
  • 结果:
A_evalue=
[[13.348  0.     0.   ]
 [ 0.    -1.348  0.   ]
 [ 0.     0.    -0.   ]]
A_eigen_power=
[[31748.694     0.        0.   ]
 [    0.        3.306     0.   ]
 [    0.        0.        0.   ]]
Ak_evalue=
[[31748.694     0.        0.   ]
 [    0.        3.306     0.   ]
 [    0.        0.        0.   ]]
A_eigen_power is True with Ak_evalue
****************************************************************************************************
BA_evalue=
[[32.874  0.     0.   ]
 [ 0.    -0.661  0.   ]
 [ 0.     0.     0.   ]]
AB_evalue=
[[32.874  0.     0.   ]
 [ 0.    -0.661  0.   ]
 [ 0.     0.     0.   ]]
BA_evalue is True same for AB_evalue
****************************************************************************************************
****************************************************************************************************
Ant_S=
[[ 0  1]
 [-1  0]]
Check_Ant_S =
[[ 0.+0.j  1.+0.j]
 [-1.+0.j  0.+0.j]]
Ant_S is True same for Check_Ant_S
****************************************************************************************************


****************************************************************************************************
Ant_S=
[[0 1]
 [1 0]]
Check_Ant_S =
[[0. 1.]
 [1. 0.]]
Ant_S is True same for Check_Ant_S
****************************************************************************************************

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐