IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数值计算方法 Chapter7. 计算矩阵的特征值和特征向量 -> 正文阅读

[数据结构与算法]数值计算方法 Chapter7. 计算矩阵的特征值和特征向量

0. 问题描述

这一章节面对的问题是说,给定一个 n n n阶矩阵,如何数值求解其特征值,即:

A x = λ x Ax = \lambda x Ax=λx

1. 幂法

1. 思路

幂法的主要思路其实依然还是来源于迭代思想。

显然,对于任意一个向量 x ? \vec{x} x ,我们总可以将其用 n n n阶矩阵的一组正交基进行表示,即:

x ? = ∑ i = 1 n x i ? n i ? \vec{x} = \sum_{i=1}^{n} x_i \cdot \vec{n_i} x =i=1n?xi??ni? ?

其中, n i ? \vec{n_i} ni? ?为矩阵 A A A的一个单位向量,有 A n i ? = λ i n i ? A\vec{n_i} = \lambda_i \vec{n_i} Ani? ?=λi?ni? ?

x ? ( 0 ) = ∑ i x i n i ? \vec{x}^{(0)} = \sum_{i}x_i \vec{n_i} x (0)=i?xi?ni? ? x ? ( k + 1 ) = A x ? ( k ) \vec{x}^{(k+1)} = A\vec{x}^{(k)} x (k+1)=Ax (k),则易有:

x ? ( k ) = ∑ i x i ? λ i k ? n i ? \vec{x}^{(k)} = \sum_{i} x_i \cdot \lambda_i^k \cdot \vec{n_i} x (k)=i?xi??λik??ni? ?

对应的模长为:

∣ ∣ x ? ( k ) ∣ ∣ = ∑ i x i 2 λ i 2 k ||\vec{x}^{(k)}|| = \sqrt{\sum_i x_i^2 \lambda_i^{2k}} x (k)=i?xi2?λi2k? ?

我们考虑当 k → ∞ k \to \infty k x ? ( k ) \vec{x}^{(k)} x (k)的方向,不妨设 m a x ( ∣ λ i ∣ ) = λ max(|\lambda_i|) = \lambda max(λi?)=λ

不妨设 λ = ∣ λ 1 ∣ ≥ ∣ λ 2 ∣ ≥ . . . ≥ ∣ λ n ∣ \lambda = |\lambda_1| \geq |\lambda_2| \geq ... \geq |\lambda_n| λ=λ1?λ2?...λn?,则我们可以分情况讨论有:

  1. 假设有且仅有一个正的 λ i \lambda_i λi?使得 ∣ λ i ∣ = λ |\lambda_i| = \lambda λi?=λ

    lim ? k → ∞ x ? ( k ) ∣ ∣ x ? ( k ) ∣ ∣ = n 1 ? \lim_{k \to \infty} \frac{\vec{x}^{(k)}}{||\vec{x}^{(k)}||} = \vec{n_1} klim?x (k)x (k)?=n1? ?

    此时有:

    x ? ( k + 1 ) = A x ? ( k ) = λ x ? ( k ) \vec{x}^{(k+1)} = A\vec{x}^{(k)} = \lambda \vec{x}^{(k)} x (k+1)=Ax (k)=λx (k)

  2. 假设满足 ∣ λ i ∣ = λ |\lambda_i| = \lambda λi?=λ条件的 i i i共有 m m m个,且均有 λ i > 0 \lambda_i > 0 λi?>0

    lim ? k → ∞ x ? ( k ) ∣ ∣ x ? ( k ) ∣ ∣ = ∑ i m x i ∑ i m x i 2 n i ? \lim_{k \to \infty} \frac{\vec{x}^{(k)}}{||\vec{x}^{(k)}||} = \sum_{i}^{m}\frac{x_i}{\sqrt{\sum_i^m x_i^2}}\vec{n_i} klim?x (k)x (k)?=im?im?xi2? ?xi??ni? ?

    此时同样有:

    x ? ( k + 1 ) = A x ? ( k ) = λ x ? ( k ) \vec{x}^{(k+1)} = A\vec{x}^{(k)} = \lambda \vec{x}^{(k)} x (k+1)=Ax (k)=λx (k)

  3. 假设有 m m m个正的 ∣ λ i ∣ = λ |\lambda_i| = \lambda λi?=λ l l l个负的 ∣ λ i ∣ = λ |\lambda_i| = \lambda λi?=λ

    lim ? k → ∞ x ? ( k ) ∣ ∣ x ? ( k ) ∣ ∣ = ∑ i m x i ∑ i m + l x i 2 n i ? + ∑ j l ( ? 1 ) k ? x j ∑ i m + l x j 2 n j ? \lim_{k \to \infty} \frac{\vec{x}^{(k)}}{||\vec{x}^{(k)}||} = \sum_{i}^{m}\frac{x_i}{\sqrt{\sum_i^{m+l} x_i^2}}\vec{n_i} + \sum_{j}^{l}\frac{(-1)^{k} \cdot x_j}{\sqrt{\sum_i^{m+l} x_j^2}}\vec{n_j} klim?x (k)x (k)?=im?im+l?xi2? ?xi??ni? ?+jl?im+l?xj2? ?(?1)k?xj??nj? ?

    此时,虽然 x ? ( k + 1 ) / x ? ( k ) \vec{x}^{(k+1)} / \vec{x}^{(k)} x (k+1)/x (k)不稳定,但是依然有:

    x ? ( k + 2 ) = A A x ? ( k ) = λ 2 x ? ( k ) \vec{x}^{(k+2)} = AA\vec{x}^{(k)} = \lambda^2 \vec{x}^{(k)} x (k+2)=AAx (k)=λ2x (k)

不过需要注意的是,这里讨论的只是一般的情况,其基于的假设是说所有的 x i ≠ 0 x_i \neq 0 xi??=0,如果恰好存在某些分量上的投影为0, 即某些 x i = 0 x_i = 0 xi?=0,那么上述讨论会发生一定的变化甚至失效。

而且,如上述分析,通过幂法,我们只能够获得一般矩阵当中绝对值最大的一个特征值 λ \lambda λ,无法获取其所有的特征值,这个也需要注意一下。

2. 规范运算

基于上述思路,我们给出幂法计算的规范运算方法:

{ y ? ( k ) = x ? ( k ) / ∣ ∣ x ? ( k ) ∣ ∣ x ? ( k + 1 ) = A ? y ? ( k ) \left\{ \begin{aligned} \vec{y}^{(k)} &= \vec{x}^{(k)} / ||\vec{x}^{(k)}|| \\ \vec{x}^{(k+1)} &= A \cdot \vec{y}^{(k)} \end{aligned} \right. {y ?(k)x (k+1)?=x (k)/x (k)=A?y ?(k)?

通过上述迭代,我们即可求取矩阵 A A A的绝对值最大的特征值。

3. 伪代码实现

给出python伪代码实现如下:

def power_fn(A, epsilon=1e-6):
    n = len(A)
    x = [1 for _ in range(n)]
    for _ in range(10**3):
        s = math.sqrt(sum(t*t for t in x))
        y = [t/s for t in x]
        z = [0 for _ in range(n)]
        for i in range(n):
            for j in range(n):
                z[i] += A[i][j] * y[j]
                
        lamda = sum([a/b for a, b in zip(z, y)]) / n
        delta =  max(abs(a-b) for a, b in zip(z, x))
        x = z
        if delta < epsilon:
            break
    return lamda

当然,这里只考虑了仅有单一符号的最大绝对值 λ \lambda λ的情况,如果存在绝对值相同且符号相反的最大特征值 λ \lambda λ,上述代码会失效,需要进行一些复杂操作还有判断,这里就不过多展开了。

2. 反幂法

1. 思路 & 方法

反幂法的思路和幂法其实大差不差,不过幂法是直接正向的进行迭代,即:

x ? ( k + 1 ) = A x ? ( k ) \vec{x}^{(k+1)} = A \vec{x}^{(k)} x (k+1)=Ax (k)

反幂法的迭代方式则是:

x ? ( k + 1 ) = A ? 1 x ? ( k ) \vec{x}^{(k+1)} = A^{-1} \vec{x}^{(k)} x (k+1)=A?1x (k)

或者说:

x ? ( k ) = A x ? ( k + 1 ) \vec{x}^{(k)} = A \vec{x}^{(k+1)} x (k)=Ax (k+1)

解法而言,我们只需要在上述幂法的基础上叠加上一章节当中多元方程组求解的方法即可。

需要额外说明的是,由于这里使用的迭代与之前的幂法是相反的,因此,这里求解的是 A ? 1 A^{-1} A?1当中绝对值最大的特征值,也就是 A A A当中绝对值最小的特征值。

而同样的,这里的额外隐性条件就是需要矩阵 A A A是满秩的,否则矩阵不存在逆矩阵,上述方程 x ? ( k ) = A x ? ( k + 1 ) \vec{x}^{(k)} = A \vec{x}^{(k+1)} x (k)=Ax (k+1)可能无解。

2. 伪代码实现

同样的,这里我们给出最简单情况下(即 A A A满秩且且仅存在一个最小的绝对值特征根的情况),反幂法的python伪代码实现:

def rev_power_fn(A, epsilon=1e-6):
    n = len(A)
    x = [1 for _ in range(n)]
    for _ in range(10**3):
        s = math.sqrt(sum(t*t for t in x))
        y = [t/s for t in x]
        z = loose_iter(A, y)
                
        lamda = sum([a/b for a, b in zip(y, z)]) / n
        delta =  max(abs(a-b) for a, b in zip(z, x))
        x = z
        if delta < epsilon:
            break
    return lamda

3. 实对称矩阵的Jacobi方法

1. 思路 & 方法

如前所述,幂法和反幂法本质上都是通过迭代的思路找一个稳定的特征向量,然后通过特征向量来求特征值。

因此,他们只能求取矩阵的某一个特征值,无法对矩阵的全部特征值进行求解。如果要对矩阵的全部特征值进行求解,上述方法就会失效。

但是,对于一些特殊的矩阵,即实对称矩阵,事实上我们是可以对其全部的特征值进行求解的,一种典型的方法就是Jacobi方法。

本质上来说,Jacobi方法依然还是进行迭代,不过其迭代的思路则是不断地对矩阵进行酉变换,使之收敛到一个对角矩阵上面,此时对角矩阵的各个对角元就是原矩阵的特征值。

具体而言,已知 A x = λ x Ax = \lambda x Ax=λx,有正交矩阵 U U U满足 U U T = I UU^{T} = I UUT=I,则有:

U A U T ? U x = λ ? U x UAU^{T} \cdot Ux = \lambda \cdot Ux UAUT?Ux=λ?Ux

此时, λ \lambda λ依然是矩阵 U A U T UAU^{T} UAUT的特征值。

如果经过一系列变换之后:

U k U k ? 1 . . . U 1 A U 1 T U 2 T . . . U k T = d i a g ( λ 1 , . . . , λ n ) U_kU_{k-1}...U_{1}AU_1^{T}U_2^{T}...U_{k}^T = diag(\lambda_1, ..., \lambda_n) Uk?Uk?1?...U1?AU1T?U2T?...UkT?=diag(λ1?,...,λn?)

λ 1 , . . . , λ n \lambda_1, ..., \lambda_n λ1?,...,λn?即为矩阵 A A A的全部特征值。

剩下的问题就是如何求解这些矩阵 U U U,Jacobi方法给出的一种可行的思路是通过Givens矩阵,即:

G ( p , q , θ ) = ( 1 . . . c o s θ . . . s i n θ . . . . . . ? s i n θ . . . c o s θ . . . 1 ) G(p, q, \theta) = \begin{pmatrix} 1 \\ & ... \\ & & cos\theta & ... & sin\theta \\ & & ... & & ... \\ & & -sin\theta & ... & cos\theta \\ & & & & & ... \\ & & & & & & 1 \end{pmatrix} G(p,q,θ)=???????????1?...?cosθ...?sinθ?......?sinθ...cosθ?...?1????????????

也就是说,只对 p , q p,q p,q两行的元素进行角度为 θ \theta θ的旋转变换。

令:

B = G ( p , q , θ ) ? A ? G T ( p , q , θ ) B = G(p,q,\theta) \cdot A \cdot G^{T}(p,q,\theta) B=G(p,q,θ)?A?GT(p,q,θ)

则有:

{ b i , j = a i , j b i , p = b p , i = a p , i c o s θ ? a q , i s i n θ b i , q = b q , i = a p , i s i n θ + a q , i c o s θ b p , p = a p , p c o s 2 θ + a q , q s i n 2 θ ? a p , q s i n 2 θ b q , q = a p , p s i n 2 θ + a q , q c o s 2 θ + a p , q s i n 2 θ b p , q = b q , p = a p , q c o s 2 θ + a p , p ? a q , q 2 s i n 2 θ \left\{ \begin{aligned} b_{i, j} &= a_{i, j} \\ b_{i,p} &= b_{p,i} = a_{p, i}cos\theta - a_{q, i}sin\theta \\ b_{i,q} &= b_{q,i} = a_{p, i}sin\theta + a_{q, i}cos\theta \\ b_{p,p} &= a_{p,p}cos^{2}\theta + a_{q,q}sin^{2}\theta - a_{p,q}sin2\theta \\ b_{q,q} &= a_{p,p}sin^{2}\theta + a_{q,q}cos^{2}\theta + a_{p,q}sin2\theta \\ b_{p,q} &= b_{q,p} = a_{p,q} cos2\theta + \frac{a_{p,p} - a_{q,q}}{2}sin2\theta \end{aligned} \right. ????????????????????????bi,j?bi,p?bi,q?bp,p?bq,q?bp,q??=ai,j?=bp,i?=ap,i?cosθ?aq,i?sinθ=bq,i?=ap,i?sinθ+aq,i?cosθ=ap,p?cos2θ+aq,q?sin2θ?ap,q?sin2θ=ap,p?sin2θ+aq,q?cos2θ+ap,q?sin2θ=bq,p?=ap,q?cos2θ+2ap,p??aq,q??sin2θ?

我们取合适的 θ \theta θ,使得 b q , p = 0 b_{q,p} = 0 bq,p?=0,则有:

{ ∑ i ≠ j b i , j 2 = ∑ i ≠ j a i , j 2 ? 2 a p , q 2 ∑ i b i , i 2 = ∑ i a i , i 2 + 2 a p , q 2 \left\{ \begin{aligned} \sum_{i\neq j} b_{i,j}^2 &= \sum_{i\neq j} a_{i,j}^2 - 2a_{p,q}^2 \\ \sum_{i} b_{i,i}^2 &= \sum_{i} a_{i,i}^2 + 2a_{p,q}^2 \end{aligned} \right. ??????????i?=j?bi,j2?i?bi,i2??=i?=j?ai,j2??2ap,q2?=i?ai,i2?+2ap,q2??

可以看到,非对角元的元素绝对值会越来越小。

因此,经过足够次数的迭代,可以将原始矩阵 A A A变换成为一个特征值相同的近对角矩阵。

而为了进一步提升迭代的速度,可以优先选择绝对值最大的非对角元进行迭代消去。

2. 伪代码实现

同样的,我们给出python伪代码实现如下:

def jacobi_eigen_fn(A, epsilon=1e-6):
    n = len(A)
    assert(len(A[0]) == n)
    assert(A[i][j] == A[j][i] for i in range(n) for j in range(i+1, n))
    
    finished = False
    for _ in range(1000):
        for p in range(n):
            for q in range(p+1, n):
                if A[p][p] != A[q][q]:
                    theta = 0.5 * math.atan(2*A[p][q] / (A[q][q] - A[p][p]))
                else:
                    theta = math.pi / 4
                ap = deepcopy(A[p])
                aq = deepcopy(A[q])
                for i in range(n):
                    if i == p or i == q:
                        continue
                    A[i][p] = A[p][i] = ap[i] * math.cos(theta) - aq[i] * math.sin(theta)
                    A[i][q] = A[q][i] = ap[i] * math.sin(theta) + aq[i] * math.cos(theta)
                A[p][p] = ap[p] * math.cos(theta)**2 + aq[q] * math.sin(theta)**2 - ap[q] * math.sin(2*theta)
                A[q][q] = ap[p] * math.sin(theta)**2 + aq[q] * math.cos(theta)**2 + ap[q] * math.sin(2*theta)
                A[p][q] = A[q][p] = ap[q] * math.cos(2 * theta) + (ap[p] - aq[q])/2 * math.sin(2*theta)
                
                finished = all(A[i][j] < epsilon for i in range(n) for j in range(i+1, n))
                if finished:
                    break
            if finished:
                break
        if finished:
            break
    return [A[i][i] for i in range(n)]
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-25 18:20:58  更:2022-06-25 18:22:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:03:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码