Matlab矩阵特征值计算:eig与eigs区别及jordan数值陷阱

发布时间:2026/10/24 23:05:00
Matlab矩阵特征值计算:eig与eigs区别及jordan数值陷阱

简介:这份资源面向学习MATLAB数值计算与线性代数的学生和工程人员,聚焦矩阵处理中的特征值、特征向量与对角化等核心问题,适合作为课堂实验或自学练习的配套材料。压缩包内共1个doc文档,约98KB,内容以实验讲义形式组织,涵盖特征多项式求解、eig函数求特征值与特征向量、实对称矩阵正交对角化、balance函数提高计算精度以及jordan函数求若当标准形等知识点,并配有可直接运行的MATLAB代码示例与运算结果对照。文档还整理了trace、sum、prod、cdf2rdf等常用矩阵函数的用法说明,便于读者在练习中随时查阅。目前已有727人学习下载,可作为矩阵分析入门与实验报告的参考,帮助读者理解特征值分解的数学原理并掌握相应MATLAB命令的调用方式。

1. 矩阵处理到底在算什么:从“找方向”说起

很多人第一次听到“特征值与特征向量”,脑子里冒出的是一堆符号和公式,完全不知道它在生活里对应什么。其实可以这样理解:你把一个矩阵想象成一台“变形机器”,任何向量丢进去,都会被拉伸、旋转、翻转。但总有那么几个特殊方向,丢进去之后只被拉长或压短,方向纹丝不动——这几个方向就是特征向量,拉伸的倍数就是特征值。Matlab 矩阵处理里最核心的一块,就是帮你把这几条“不动方向”和“拉伸倍数”找出来。

搞懂这件事的价值在于:矩阵对角化、若当标准形、实对称矩阵的正交分解,全都建立在这个概念之上。你不需要手算行列式,Matlab 的eig、jordan、balance这些函数已经把底层运算封装好了。但前提是,你得知道每个函数在做什么、结果怎么读、什么时候会翻车。这篇就把这些概念用大白话拆开,让你看完能分清eig和eigs的区别,知道jordan为什么有时候“不灵”,也明白balance到底在平衡什么。

2. 特征值与特征向量:Matlab 里到底怎么算、结果怎么读

2.1 从特征多项式到poly和roots

在 Matlab 里求特征值,最“笨”但也最直观的路子是先算特征多项式。特征多项式的定义是 det(λI − A),其中 I 是单位阵,λ 是符号变量。Matlab 提供了poly(A)直接返回多项式系数的向量形式。比如一个 2×2 矩阵,poly会给你三个系数,分别对应 λ²、λ¹ 和常数项。

A = [1 0; 2 3]; p = poly(A); % 返回特征多项式系数向量 f = poly2str(p, 'x'); % 转成可读字符串形式

poly返回的是数值向量,poly2str只是把它排版成人类能读的表达式。如果你想知道特征值具体是多少,还得对多项式求根,用roots函数。这条路适合教学演示,因为你能亲眼看到特征多项式长什么样。但实际工程里没人这么干——高阶矩阵的多项式求根数值稳定性很差,Matlab 内部也不会用这条路去算eig。

另一种更“数学”的写法是用符号变量直接算行列式:

syms x; E = eye(2); f = det(x*E - A); % 符号形式的特征多项式

这样得到的是符号表达式,适合推导和验证,但不适合大规模数值计算。符号运算慢,而且当矩阵阶数上去之后,表达式会膨胀到没法看。

2.2eig的三种返回形式与eigs的区别

真正干活用的是eig。它有三种常见调用方式,返回的东西不一样,用途也不一样。

第一种,d = eig(A),只返回一个列向量,里面装着所有特征值。你只关心特征值大小、不关心特征向量时用这个。

第二种,[V, D] = eig(A),返回两个矩阵。D 是对角矩阵,主对角线上的元素就是特征值;V 的每一列是对应的特征向量。满足的关系是 A·V = V·D,等价于 D = V⁻¹AV。这就是矩阵对角化的核心等式。

第三种,[V, D] = eigs(A),注意这里函数名多了个 s。eigs不是返回全部特征值,而是按大小次序返回一部分,通常用于大型稀疏矩阵。它底层用的是迭代法,只算你指定的前 k 个。如果你对一个 10000×10000 的矩阵用eig,它会试图算全部特征值,内存和时间都可能爆掉;用eigs指定算前 6 个,就轻松很多。

A = [0 1 0 0; 1 0 0 0; 0 0 0 1; 0 0 1 0]; d = eig(A); % 全部特征值,列向量 [V, D] = eig(A); % 特征向量矩阵 V 和特征值对角阵 D

运行后你会发现特征值是 1、-1、1、-1,有重根。D 的主对角线上按顺序排列,V 的列向量对应每个特征值。这里有个细节:当特征值有重根时,eig返回的特征向量不一定是正交的,甚至可能线性相关。如果你需要正交基,得用实对称矩阵那条路,后面会讲。

2.3 结果怎么验证:V^-1*A*V和符号化输出

算出[V, D]之后,怎么确认没算错?最直接的办法是验算 V⁻¹AV 是否等于 D。在 Matlab 里可以写成:

V_inv = inv(V); check = V_inv * A * V; % 应该接近对角阵 D

如果 A 可对角化,check的非对角元素应该接近 0。但数值计算有浮点误差,你可能会看到 10⁻¹⁵ 量级的小数,那是正常的。

有时候你希望看到精确的分数或根号形式,而不是小数。这时可以把 V 转成符号类型:

V_sym = sym(V); V_sym^-1 * A * V_sym

这样输出就是分数和根号,方便对照手算结果。但注意,符号运算只适合小矩阵验证,大矩阵会非常慢。

提示:eig返回的特征向量默认是归一化的,但归一化方式不唯一。不同版本的 Matlab 可能在符号上差一个负号,这不影响正确性。

3. 对角化与若当标准形:能对角化最好,不能也别慌

3.1 可对角化的条件与实对称矩阵的特殊待遇

一个 n 阶方阵能不能对角化,取决于它有没有 n 个线性无关的特征向量。如果特征值都是单根,那一定可对角化;如果有重根,就要看重根对应的特征向量个数够不够。不够的话,就只能退而求其次,求若当标准形。

实对称矩阵是个特例:它一定可以对角化,而且特征向量可以选成两两正交的。Matlab 的eig对实对称矩阵会自动返回正交矩阵 P,满足 P⁻¹AP = D,而且 P⁻¹ 就等于 Pᵀ。这意味着你不需要求逆,转置一下就行,数值上更稳定。

A = [2 2 -2; 2 5 -4; -2 -4 5]; % 实对称矩阵 [P, D] = eig(A); % P 是正交阵,D 是对角阵

这个性质在二次型化简里特别有用。二次型矩阵是实对称的,对角化之后就得到了标准形,P 就是变换矩阵。你不需要手动配方,eig一步到位。

3.2jordan函数与若当块的上三角定义

当矩阵不能对角化时,jordan(A)返回它的若当标准形 J。若当标准形长什么样?对角线上是特征值,对角线上方可能有 1,形成一个个“块”。Matlab 里若当块是按上三角形定义的,也就是说 1 出现在对角线上方,而不是下方。

A = [-1 -2 6; -1 0 3; -1 -1 4]; J = jordan(A);

运行后 J 是一个上三角矩阵,对角线上是特征值,某些位置有 1。这些 1 的位置和个数反映了矩阵的“缺陷程度”——也就是特征向量不够用的程度。

但jordan有个血泪经验:它对数值误差极其敏感。稍微扰动一下矩阵元素,若当块结构就可能完全改变。所以实际工程里,除非你确定矩阵是精确的符号矩阵或者小整数矩阵,否则不要轻易依赖jordan的数值结果。它更适合教学和理论验证,不适合处理实验测得的浮点数据。

3.3 复对角矩阵转实对角:cdf2rdf在做什么

实矩阵的特征值可能是复数,而且成共轭对出现。eig返回的 D 可能是复对角阵,对角线上有 a+bi 和 a−bi。如果你希望保持实数运算,可以用cdf2rdf把复对角阵转成实块对角阵。

A = [0 2 1; -2 0 3; -1 -3 0]; [v, d] = eig(A); % d 是复对角阵 [V, D] = cdf2rdf(v, d); % D 是实块对角阵

转换之后,D 的对角线上不再是复数,而是 2×2 的实数块。每个 2×2 块对应一对共轭特征值。这样做的好处是后续计算全在实数域进行,避免复数运算带来的额外开销和精度问题。

注意:cdf2rdf只对实矩阵有意义。如果原矩阵本身就是复矩阵,这个转换不适用。

4. 常见误区与易混概念:别把这几组函数搞混了

4.1eig和eigs:一个算全部,一个算部分

最容易混的就是这两个。名字只差一个字母,行为差很远。eig算全部特征值,适合中小型稠密矩阵;eigs算部分特征值,适合大型稀疏矩阵。如果你对一个 5000×5000 的稀疏矩阵用eig,Matlab 会试图算 5000 个特征值,内存直接吃满。用eigs(A, 6)只算前 6 个,几秒钟就出结果。

区分方法很简单:看矩阵大小和稀疏性。小矩阵、需要全部特征值,用eig;大矩阵、只关心最大或最小的几个,用eigs。

4.2poly和polyfit:名字像,用途完全不同

poly是求特征多项式系数的,输入是方阵,输出是系数向量。polyfit是多项式拟合,输入是数据点,输出是拟合系数。两者都和“多项式”有关,但一个服务于矩阵特征值,一个服务于数据拟合。初学者看到poly容易联想到拟合,这是典型的望文生义。

区分方法:看输入。输入是方阵,用poly;输入是 x 和 y 数据向量,用polyfit。

4.3jordan的数值陷阱:理论成立不等于数值可靠

理论上任何方阵都有若当标准形,但数值上jordan可能给你一个完全错误的结果。原因在于若当块结构对扰动极其敏感。一个特征值接近重根的矩阵,在浮点误差下可能被判定为可对角化,也可能被判定为有若当块,结果不稳定。

区分方法:如果矩阵元素是精确整数或符号,jordan可信;如果矩阵来自实验测量或浮点计算,不要依赖jordan的结构,只看特征值就够了。

4.4balance不是“平衡方程”,而是缩放矩阵

balance(A)返回一个相似变换矩阵 T 和平衡矩阵 B,使得 B = T⁻¹AT。它的作用是缩放矩阵的行和列,让各行各列的范数尽量接近,从而提高特征值计算的精度。它不是用来解平衡方程的,也不是用来做物理平衡的。

区分方法:看到balance出现在特征值计算上下文里,就知道它在做矩阵缩放,目的是数值稳定。

4.5trace和sum:迹是特征值之和,但sum不一定是

trace(A)返回矩阵的迹,等于主对角线元素之和,也等于所有特征值之和。sum(A, dim)是元素求和,dim=1 按列求和,dim=2 按行求和。sum(sum(A,1),2)才是所有元素之和。初学者容易把trace和sum混为一谈,尤其是在验证特征值之和等于迹的时候。

区分方法:trace只针对方阵,结果是标量;sum对任意矩阵都行,结果可能是向量。

5. 什么时候用、什么时候别用:一个具体例子和边界判断

假设你手头有一个 3×3 的实对称矩阵,来自某个物理系统的刚度矩阵,你想知道它的特征值和特征向量,用来判断系统的振动模态。这时候eig是最合适的选择,因为实对称矩阵保证正交对角化,数值稳定,结果可靠。

A = [2 2 -2; 2 5 -4; -2 -4 5]; [P, D] = eig(A); % P 的列是振动模态,D 的对角线是频率平方

但如果你面对的是一个 20000×20000 的稀疏矩阵,来自有限元分析,你只关心前 10 个最小特征值。这时候绝对不能用eig,必须用eigs(A, 10, 'sm'),其中'sm'表示 smallest magnitude。否则内存和时间都扛不住。

再比如,你有一个矩阵,特征值有重根,你想知道它能不能对角化。这时候不要直接上jordan,因为数值结果可能骗你。更稳妥的做法是检查特征向量的秩:用[V, D] = eig(A),然后看rank(V)是否等于矩阵阶数。如果等于,说明有足够多的线性无关特征向量,可对角化;如果小于,说明不能对角化,若当块存在。

还有一个场景:你算完特征值,发现结果里有很小的虚部,比如 1.0000 + 0.0000i。这通常是浮点误差,不是真的复数特征值。可以用real函数取实部,或者用cdf2rdf转成实块对角阵。

提示:判断特征值是否为实数,不要看虚部是否严格为零,而是看虚部是否小于某个容差,比如abs(imag(d)) < 1e-10。

从那以后我每次用eig之前,都会先问自己三个问题:矩阵是稠密还是稀疏?需要全部特征值还是前几个?矩阵有没有特殊结构(对称、三角、稀疏)?这三个问题决定了用eig还是eigs,用不用balance,以及结果怎么验证。希望帮到你。

本文还有配套的精品资源,点击获取