4.2 矩阵特征值和奇异值
对于n阶方阵A,求数λ和向量X,使得等式AX=λX成立,满足等式的数λ称为A的特征值,向量X称为A的特征向量。方程AX=λX和(A-λI)X=0是两个等价方程,要使方程(A-λI)X=0有非0解X,则必须使其行列式等于0,即|A-λI |=0。
由线性代数可知,行列式|A-λI |是一个关于λ的n阶多项式,因此方程|A-λI |=0是一个n次方程,有n个根(包含重根)。n个根就是矩阵A的n个特征值,每一个特征值对应无穷多个特征向量。所以,矩阵的特征值问题有确定的解,但特征向量问题没有确定的解。
4.2.1 特征值和特征向量的求取
特征值和特征向量在科学研究和工程计算中的应用非常广泛。在MATLAB中,计算矩阵A的特征值和特征向量的函数是eig(A),常用的调用格式有以下3种。
(1)E=eig(A):用于求矩阵A的全部特征值,构成向量E。
(2)[V,D]=eig(A):用于求矩阵A的全部特征值,构成对角矩阵D,并求A的特征向量,构成V的列向量。
(3)[V,D]=eig(A,’nobalance’):与上一种格式类似,只是上一种格式中是先对A作相似变换后再求矩阵A的特征值和特征向量,而本格式中则是直接求矩阵A的特征值和特征向量。
一个矩阵A的特征向量有无穷多个,eig函数只找出其中的n个,A的其他特征向量均可由这n个特征向量组合表示。
【例4-11】 简单实数矩阵的特征值示例。
>> A=[1,-3;2,2/3]
A =
1.0000 -3.0000
2.0000 0.6667
>> [V,D]=eig(A)
V =
0.7746 + 0.0000i 0.7746 + 0.0000i
0.0430 - 0.6310i 0.0430 + 0.6310i
D =
0.8333 + 2.4438i 0.0000 + 0.0000i
0.0000 + 0.0000i 0.8333 - 2.4438i
【例4-12】 矩阵中有元素与截断误差相当时的特性值问题。
>> A=[3 -2 -0.9 2*eps
-2 4 -1 -eps
-eps/4 eps/2 -1 0
-0.5 -0.5 0.1 1 ];
>> [V1,D1]=eig(A); % 求特征值
>> ER1=A*V1-V1*D1 % 查看计算误差
ER1 =
0.0000 0 -0.0000 0.0000
0 -0.0000 0.0000 -0.0000
0.0000 -0.0000 -0.0000 0
0 0.0000 0.0000 -0.3789
>> [V2,D2]=eig(A,'nobalance');
>> ER2=A*V2-V2*D2 % 查看计算误差
ER2 =
1.0e-14 *
-0.1776 -0.0111 -0.0559 -0.0833
0.3553 0.1055 0.0343 0.0555
0.0017 0.0002 0.0007 0
0.0264 -0.0222 0.0222 0.0333
在本例,若求特征值的过程中不采用'nobalance'参数,那么计算结果是具有相当大的计算误差的。这是因为在执行eig命令的过程中,首先要调用使原矩阵各元素大致相当的“平衡”程序,这些“平衡”程序使得原来方阵中本可以忽略的小元素(本例中如eps)的作用被放大了,所以产生了较大的计算误差。
但是这种误差被放大的情况只发生在矩阵中有元素与截断误差相当的时候,在一般情况下,“平衡”程序的作用是减小计算误差。
【例4-13】 函数eig 与eigs 的比较示例。eigs函数是计算矩阵最大特征值和特征向量的函数。
>> rand('state',0) % 设置随机种子,便于读者验证
>> A=rand(100,100)-0.5;
>> t0=clock;[V,D]=eig(A);T_full=etime(clock,t0) % 函数eig的运行时间
>> options.tol=1e-8; % 为eigs设置计算精度
>> options.disp=0; % 不显示中间迭代结果
>> t0=clock;[v,d]=eigs(A,1,'lr',options); % 计算最大实部特征值和特征向量
>> T_part=etime(clock,t0) % 函数eigs的运行时间
>> [Dmr,k]=max(real(diag(D))); % 在eig求得的全部特征值中找实部最大的
>> d,D(1,1)
运行结果为:
T_full =
0.9510
T_part =
1.6540
d =
2.7278 + 0.3006i
ans =
2.5933 + 1.5643i
>> vk1=V(:,k); % 与d相同的特征向量应是V的第k列
>> vk1=vk1/norm(vk1);v=v/norm(v); % 向量长度归一
>> V_err=acos(norm(vk1'*v))*180/pi % 求复数向量之间的夹角
V_err =
8.5377e-007
>> D_err=abs(D(k,k)-d)/abs(d) % 求两个特征值间的相对误差
D_err =
2.6420e-009
在本例中,对函数运行所需要的时间进行了评估。需要指出的是:在实际使用中因为计算机的配置和系统状态不同,评估得到的绝对时间也不尽相同,不过我们可以通过同一台计算机上两种函数运行所需要时间比较得到两种算法的优劣。通过本例可以得出结论:使用eigs函数求一个特征值和特征向量所需要的时间,反而比使用eig函数求全部特征值和特征向量的时间多。
【例4-14】 用求特征值的方法,求解方程的根。
求解方程组要先构造与方程对应的多项式的伴随矩阵A,再求A的特征值,伴随矩阵A的特征值即为方程的解。具体过程如下:
>> B=[1,-2,3,4,-5]
B =
1 -2 3 4 -5
>> A=compan(B) % 求B 的伴随矩阵
A =
2 -3 -4 5
1 0 0 0
0 1 0 0
0 0 1 0
>> C=eig(A)
C =
1.1641 + 1.8573i
1.1641 - 1.8573i
-1.1973 + 0.0000i
0.8691 + 0.0000i
>> D=roots(B) % 直接求多项式B的零点
D =
1.1641 + 1.8573i
1.1641 - 1.8573i
-1.1973 + 0.0000i
0.8691 + 0.0000i函数compan计算的是矩阵B的伴随矩阵A。伴随矩阵的特征值C就是方程的根。roots函数用于直接对线形方程求解,得到结果D,可以看出两种方法得出的结果C和D是一样的。
4.2.2 奇异值分解
如果存在两个矢量u、v及一个常数s,使得矩阵A满足下式:
Av=su
A’u=sv
则称s为奇异值,称u、v为奇异矢量。
将奇异值写成对角方阵∑,而相对应的奇异矢量作为列矢量,则可写成两个正交矩阵U、V,使得:
AV=U∑
A’U=V∑
因为U、V正交,所以可得奇异值的表达式为:
A=U∑V’
一个m行n列的矩阵A经奇异值分解,可求得m行m列的距阵U,m行n列的矩阵∑,n行n列的矩阵V。
奇异值分解是另一种正交矩阵分解法,是最可靠的分解法,但是它与QR分解法相比,要花近10倍的计算时间。奇异值分解由svd函数实现,其调用格式为:[U,S,V]=svd(A)。
【例4-15】 奇异值分解示例。
>> A=magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
>> [U,S,V] = svd(A) % 奇异值分解
U =
-0.5000 0.6708 0.5000 -0.2236
-0.5000 -0.2236 -0.5000 -0.6708
-0.5000 0.2236 -0.5000 0.6708
-0.5000 -0.6708 0.5000 0.2236
S =
34.0000 0 0 0
0 17.8885 0 0
0 0 4.4721 0
0 0 0 0.0000
V =
-0.5000 0.5000 0.6708 0.2236
-0.5000 -0.5000 -0.2236 0.6708
-0.5000 -0.5000 0.2236 -0.6708
-0.5000 0.5000 -0.6708 -0.2236
>> U*S*V' % 分解结果正确性验证
ans =
16.0000 2.0000 3.0000 13.0000
5.0000 11.0000 10.0000 8.0000
9.0000 7.0000 6.0000 12.0000
4.0000 14.0000 15.0000 1.0000