矩阵的逆的定义:一个 n × n n\times n n×n的矩阵 A A A是可逆的,如果存在一个 n × n n\times n n×n的矩阵 C C C使得:
C A = I , 且 A C = I CA=I, 且 AC=I CA=I,且AC=I
其中 I = I n I=I_n I=In为 n × n n\times n n×n的单位矩阵,此时矩阵 C C C就是矩阵 A A A的逆,矩阵 A A A的逆记为矩阵 A − 1 A^{-1} A−1。若矩阵 A A A可逆,那么它的逆是唯一的。
奇异矩阵与非奇异矩阵:
不可逆矩阵有时也叫奇异矩阵,可逆矩阵有时也成为非奇异矩阵。
求矩阵逆的方法:
把 n × n n\times n n×n的方阵 A A A与同样是 n × n n\times n n×n的单位矩阵 I I I排在一起,构成增广矩阵 [ A I ] [A \qquad I] [AI],对此增广矩阵进行初等行变换,直到化简为 [ I A − 1 ] [I \qquad A^{-1}] [IA−1],这样矩阵 A A A的逆 A − 1 A^{-1} A−1就出现在增广矩阵右边。如果不能做如上化简,则表明矩阵 A A A没有逆。
假设矩阵 A A A为 n × n n\times n n×n的方阵,以下命题是等价的,即它们同时为真或同时为假:
判断矩阵可逆的方法:
判断矩阵可逆的方法有很多,例如:
A =
1 2
4 7
>> [n,n] = size(A)
n =
2
n =
2
>> b = rand(n,1)
b =
0.5469
0.9575
>> x1= A\b //MATLAB中使用反斜杠“\”法直接求x
x1 =
-1.9132
1.2300
>> C = [A b]
C =
1.0000 2.0000 0.5469
4.0000 7.0000 0.9575
>> rref(C) // MATLAB中rref函数将矩阵化简为简化阶梯阵。
ans =
1.0000 0 -1.9132
0 1.0000 1.2300
可见,化简得到的简化阶梯阵最后一列 [ − 1.9132 1.2300 ] \begin{bmatrix}-1.9132\\1.2300\end{bmatrix} [−1.91321.2300]即为方程的解,与方法1结果相同。
A =
1 2
4 7
>> Ai = inv(A) //函数inv求矩阵A的逆
Ai =
-7 2
4 -1
>> x2 = Ai * b
x2 =
-1.9132
1.2300
可见解得的结果与上面两种方法相同。
关于Hilbert矩阵及其逆的求法:
该矩阵为方阵,中任意元素表示为 A i j = 1 i + j − 1 A_{ij}=\frac {1}{i+j-1} Aij=i+j−11。Hilbert矩阵是高度病态的,任何一个元素发生一点变动,整个矩阵的行列式的值和逆矩阵都会发生巨大变化,病态程度和阶数相关。
Hilbert矩阵( H H H)阶数越大,其病态程度越严重,使用浮点数计算来解方程 H x = b Hx=b Hx=b的误差就越大。
MATLAB里面有内置函数invhilb(n)
来计算n阶Hilbert矩阵的逆,输出的解为精确解,如下:
>> H = hilb(5) //生成5阶Hilbert矩阵
H =
1 1/2 1/3 1/4 1/5
1/2 1/3 1/4 1/5 1/6
1/3 1/4 1/5 1/6 1/7
1/4 1/5 1/6 1/7 1/8
1/5 1/6 1/7 1/8 1/9
>> invhilb(5) //求5阶Hilbert矩阵逆的精确解
ans =
25 -300 1050 -1400 630
-300 4800 -18900 26880 -12600
1050 -18900 79380 -117600 56700
-1400 26880 -117600 179200 -88200
630 -12600 56700 -88200 44100
一个可逆矩阵是病态的(ill-conditioned),即中的某些元素稍作改变就会变成奇异矩阵(不可逆矩阵),矩阵的逆和以其为系数矩阵的方程组的解对微小的扰动十分敏感,这类矩阵叫病态矩阵,或接近奇异的矩阵。这类矩阵会给数值求解带来很大困难。
矩阵病态的反面是良态(well-conditioned),关于良态矩阵与病态矩阵的判断,可以使用条件数(Condition Number)作为依据,见下文。
在MATLAB中实现上面三种方法,对于求解存在该类矩阵的方程(如 A x = b Ax=b Ax=b中 A A A为Hilbert矩阵),精确度都是不太够的,可能会有warning。
>> A = hilb(20) //生成20阶的Hilbert矩阵
A =
Columns 1 through 5
1 1/2 1/3 1/4 1/5
1/2 1/3 1/4 1/5 1/6
1/3 1/4 1/5 1/6 1/7
1/4 1/5 1/6 1/7 1/8
1/5 1/6 1/7 1/8 1/9
1/6 1/7 1/8 1/9 1/10
1/7 1/8 1/9 1/10 1/11
1/8 1/9 1/10 1/11 1/12
1/9 1/10 1/11 1/12 1/13
1/10 1/11 1/12 1/13 1/14
1/11 1/12 1/13 1/14 1/15
1/12 1/13 1/14 1/15 1/16
1/13 1/14 1/15 1/16 1/17
1/14 1/15 1/16 1/17 1/18
1/15 1/16 1/17 1/18 1/19
1/16 1/17 1/18 1/19 1/20
1/17 1/18 1/19 1/20 1/21
1/18 1/19 1/20 1/21 1/22
1/19 1/20 1/21 1/22 1/23
1/20 1/21 1/22 1/23 1/24
Columns 6 through 10
1/6 1/7 1/8 1/9 1/10
1/7 1/8 1/9 1/10 1/11
1/8 1/9 1/10 1/11 1/12
1/9 1/10 1/11 1/12 1/13
1/10 1/11 1/12 1/13 1/14
1/11 1/12 1/13 1/14 1/15
1/12 1/13 1/14 1/15 1/16
1/13 1/14 1/15 1/16 1/17
1/14 1/15 1/16 1/17 1/18
1/15 1/16 1/17 1/18 1/19
1/16 1/17 1/18 1/19 1/20
1/17 1/18 1/19 1/20 1/21
1/18 1/19 1/20 1/21 1/22
1/19 1/20 1/21 1/22 1/23
1/20 1/21 1/22 1/23 1/24
1/21 1/22 1/23 1/24 1/25
1/22 1/23 1/24 1/25 1/26
1/23 1/24 1/25 1/26 1/27
1/24 1/25 1/26 1/27 1/28
1/25 1/26 1/27 1/28 1/29
Columns 11 through 15
1/11 1/12 1/13 1/14 1/15
1/12 1/13 1/14 1/15 1/16
1/13 1/14 1/15 1/16 1/17
1/14 1/15 1/16 1/17 1/18
1/15 1/16 1/17 1/18 1/19
1/16 1/17 1/18 1/19 1/20
1/17 1/18 1/19 1/20 1/21
1/18 1/19 1/20 1/21 1/22
1/19 1/20 1/21 1/22 1/23
1/20 1/21 1/22 1/23 1/24
1/21 1/22 1/23 1/24 1/25
1/22 1/23 1/24 1/25 1/26
1/23 1/24 1/25 1/26 1/27
1/24 1/25 1/26 1/27 1/28
1/25 1/26 1/27 1/28 1/29
1/26 1/27 1/28 1/29 1/30
1/27 1/28 1/29 1/30 1/31
1/28 1/29 1/30 1/31 1/32
1/29 1/30 1/31 1/32 1/33
1/30 1/31 1/32 1/33 1/34
Columns 16 through 20
1/16 1/17 1/18 1/19 1/20
1/17 1/18 1/19 1/20 1/21
1/18 1/19 1/20 1/21 1/22
1/19 1/20 1/21 1/22 1/23
1/20 1/21 1/22 1/23 1/24
1/21 1/22 1/23 1/24 1/25
1/22 1/23 1/24 1/25 1/26
1/23 1/24 1/25 1/26 1/27
1/24 1/25 1/26 1/27 1/28
1/25 1/26 1/27 1/28 1/29
1/26 1/27 1/28 1/29 1/30
1/27 1/28 1/29 1/30 1/31
1/28 1/29 1/30 1/31 1/32
1/29 1/30 1/31 1/32 1/33
1/30 1/31 1/32 1/33 1/34
1/31 1/32 1/33 1/34 1/35
1/32 1/33 1/34 1/35 1/36
1/33 1/34 1/35 1/36 1/37
1/34 1/35 1/36 1/37 1/38
1/35 1/36 1/37 1/38 1/39
>> b = rand(20,1) //生成b向量
b =
687/712
589/3737
6271/6461
581/607
614/1265
1142/1427
689/4856
407/965
1065/1163
61/77
1966/2049
3581/5461
489/13693
439/517
283/303
1481/2182
979/1292
541/728
1645/4194
1406/2145
>> x1 = A\b //反斜杠法求解x=A\b
Warning: Matrix is close to singular or badly scaled. Results may be
inaccurate. RCOND = 5.231543e-20. //此处为Warning,
x1 =
-3424659463
528255780716
-19975903782848
321018859628437
-2688760131266522
12761814815871434
-34399090053517208
45897097341921456
-7254237859641766
-37322034685407312
-49284163552153728
217508096052998944
-205446702755182752
64773453754244512
-105964986075521504
193373000517961920
-30851727609549800
-163776311038511840
135720005301748528
-33347024092943792
R = rref([A b]); x3 = R(:,21) //方法2求解,化简阶梯阵的方法,此方法最通用,没有warning。
x3 =
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
>> x2=inv(A)*b //方法3求解,矩阵A的逆乘b
Warning: Matrix is close to singular or badly scaled. Results may be
inaccurate. RCOND = 9.542396e-20.
x2 =
-3095618963
478515839234
-18128046963749
291709089884240
-2443748498671269
11565944181737902
-30772016457394916
38422934259310336
6062876912518655
-64009870499747464
-815625744960023
161923881096513024
-174734421275108320
49731260512141016
-57082196217625456
111820626128154624
24957912964649792
-173285108058004640
129261793086585504
-30878300969326916
上面的Warning中的“RCOND”表示条件数的倒数(reciprocal),如果这个值很小,则表示条件数很大,也就是说矩阵求解的误差越大。
条件数很大的矩阵是病态矩阵,对矩阵中元素很小的扰动会对结果产生很大影响。上面对含有Hilbert矩阵的方程进行求解过程中得到的RCOND = 9.542396e-20
或RCOND = 5.231543e-20
都是很小的,表示条件数都非常大,所以,产生上面报警的计算是非常不精确的。
由于MATLAB中的反斜杠求解 A x = b Ax=b Ax=b(矩阵 A A A是可逆方阵)算法是使用了部分主元法的LU分解法,使用部分主元法的算法计算量较小,且舍入误差较小。所以这种方法误差总体来说较小。
如果使用inv(A)先求A的逆,再x2=inv(A)*b的话,MATLAB先计算inv(A),也就是求解 A x = e i Ax=e_i Ax=ei, e i e_i ei是单位矩阵 I I I中的每一列向量,这样每一列向量 e i e_i ei对应的解向量 x x x求出后,拼合起来就是矩阵 A A A的逆 A − 1 A^{-1} A−1,最后计算 A − 1 b A^{-1}b A−1b。可见此种计算方法的计算量很大,所以每步的误差积累更多,总体误差更大。
对于使用rref( )求增广矩阵的简化阶梯式的方法,由于这种算法不检测矩阵是病态还是良态(所以不会提示矩阵是否是近奇异的或者病态的),仅在小的矩阵中比较精确,矩阵很大则计算很慢,但是这并不是说这种方法就最精确,其误差和上述两种方法在一个量级,但是一般不使用这种方法。
条件数越大,矩阵越接近于奇异。单位矩阵的条件数是1,奇异矩阵的条件数为无穷大。在极端情况下,矩阵计算程序可能无法区别奇异矩阵与病态矩阵。
当条件数很大时,矩阵计算可能产生很大的误差。
定义:矩阵 A A A的条件数(Condition Number)为 ∣ ∣ A ∣ ∣ ∣ ∣ A − 1 ∣ ∣ ||A||\space ||A^{-1}|| ∣∣A∣∣ ∣∣A−1∣∣。
计算方法有很多种,如:矩阵 A A A是可逆矩阵,其最大奇异值和最小奇异值之比 σ 1 σ n \frac {\sigma_1}{\sigma_n} σnσ1就是矩阵 A A A的条件数。
MATLAB中计算矩阵条件数的函数:cond( )。例如:
A =
0.7060 0.8235 0.4387 0.4898 0.2760
0.0318 0.6948 0.3816 0.4456 0.6797
0.2769 0.3171 0.7655 0.6463 0.6551
0.0462 0.9502 0.7952 0.7094 0.1626
0.0971 0.0344 0.1869 0.7547 0.1190
>> cond(A) //计算矩阵A的条件数
ans =
7.4466