在自然科学和工程技术中,很多问题可以归结为求解线性方程组。采用MATLAB,不仅可以利用其提供的相关函数直接解决一些简单的线性方程组,而且可以通过简洁的编程来解决一些复杂的线性方程组。
MATLAB 中求解线性方程最直接的方法是矩阵求逆法,它适用于系数矩阵的数据无规律且系数矩阵的阶数比较小的情况。
1. 直接用左除法
2. 使用求逆函数inv()
A = [1 2 3;-1 3 7;9 0 3];
b = [1 4 7]';
x1 = A\b %左除
x2 = inv(A)*b %求逆函数
矩阵分解法是指根据一定的原理用某种算法将系数矩阵分解成若干个矩阵的代数运算,常用的分解是乘积分解,而分解后的新矩阵一般是某种特殊矩阵。
常用的分解有LU分解、QR 分解、Cholesky 分解、Schur 分解、Hessenberg 分解和奇异分解等。
它是将矩阵分解为一个单位下三角矩阵与上三角矩阵的乘积。只要矩阵非奇异,这种分解总是可以进行的。
1. lu函数
2. [L,U] = lu(A) %上三角矩阵U和下三角矩阵L,且有X = LU
3. [L,U,P] = lu(A) %上三角矩阵U和下三角矩阵L,置换矩阵P,且有PA = LU
A = [1.5 3 -0.8 4;2 0 9 10;-7 4.8 -0.6 1;14 12.3 -4 5];
b = [4 0 1 -2]';
[L,U] = lu(A);
x = U\(L\b)
矩阵的QR分解就是把矩阵分解为一个正交矩阵和一个上三角矩阵的乘积。
1. [Q,R] = qr(X) %产生一个正交矩阵Q和一个上三角阵R,使得X=QR ;
2. [Q,R,E] = qr(X) %产生一个正交矩阵Q,一个上三角阵R以及一个置换矩阵E,使得XE=QR
A = [1 0.5 0.3333 0.25;0.5 0.3333 0.25 0.2; 0.3333 0.25 0.2 0.1667;0.25 0.2 0.1667 0.1429];
b = [1 2 2 1]';
[Q,R] = qr(A);
x = R\(Q\b)
- 系数矩阵 A A A正定且对称
- 它能分解为以下的形式: A = R T R A=R^TR A=RTR 。其中 R R R 为上三角矩阵, R T R^T RT 为 R R R 的转置,是下三角矩阵,这种分解称为 C h o l e s k y Cholesky Cholesky分解。
- 如果 X X X对称正定,则 p = 0 p=0 p=0;否则, p p p 为一正整数。如果 X X X 满秩, R R R 是为 p − 1 p-1 p−1阶的上三角矩阵,且有 R T R = X ( 1 : ( p − 1 ) , 1 : ( p − 1 ) ) R^TR=X(1:(p-1),1:(p-1)) RTR=X(1:(p−1),1:(p−1));实现分解后,方程组的解写成x=R(R’\b) 的形式。
1.R=chol(X) %对X进行Cholesky 分解,使得$X=R^TR$;
2.[R,p]=chol(X) %对X进行Cholesky 分解,使得$X=R^TR$;
A=[9 -36 30;-36 192 -180;30 -180 180];
b=ones(3,1);
R=chol (A)
X=R\(R'\b)
注意:
%矩阵A正定但不对称时,程序同样能跑出来,但这时我们验证一下发现“R'R不等于A”
A=[9 -36 30;-36 192 -180;31 -180 180];
b=ones(3,1);
R=chol (A) %输出R矩阵
R' %输出矩阵R的转置
A %输出矩阵A
B = R'*R %验证矩阵B是否等于矩阵A?看结果
X=R\(R'\b) %输出解向量
- 奇异值分解很有用,将系数矩阵进行奇异值分解以后, A A A 的奇异值都在 S S S的对角线上,这样就可以粗略估计 A A A的条件数,看看 A A A是否是病态矩阵,以此决定相应的求解方法;
- 如果系数矩阵对称,那么奇异值分解后的 U U U和 V V V都是正交矩阵,而 S S S是对角矩阵,这样求解方程就十分方便。
[U,S,V] =svd(A) %奇异值分解,使得A=U*S*V'
A=[ 1.0000 0.5000 0.3333 0.2500 0.2000;
0.5000 0.3333 0.2500 0.2000 0.1667;
0.3333 0.2500 0.2000 0.1667 0.1429;
0.2500 0.2000 0.1667 0.1429 0.1250;
0.2000 0.1667 0.1429 0.1250 0.1111];
[U,S,V]=svd(A)
b=[1 0 1 0 1]';
x1=V*inv(S)*U*b %函数求逆
x2=V/S*U*b %左除求逆
- Hessenberg 矩阵指的是第一子对角线以下的元素为0的矩阵。
- Hessenberg 分解法分解后产生正交矩阵和Hessenberg 矩阵,正交矩阵的逆就是其转置; 如果系数矩阵对称的话,产生的Hessenberg矩阵就是三对角矩阵,这种矩阵的求逆速度也很快,因此用这种方法求解线性方程组很快。
[P,H] = hess(A) %Hessenberg分解,使得A = P*H*P',其中P为酉矩阵
A=[1 1 1 1;1 2 3 4;1 3 6 10;1 4 10 20];
b = [1 4 7 -2]';
[P,H] = hess(A)
x = P/H*P'*b
- Schur 矩阵是上三角阵,且其对角元素为被分解矩阵的特征值。
- Schur 分解法在分解后产生正交矩阵和Schur 矩阵,如果系数矩阵对称的话,产生的Schur 矩阵就是对角阵,显然对角阵的逆矩阵非常容易得到,因此用这种方法求解线性方程组也很快。
[U,T] = schur(A) %Schur分解,使得A=U*T*U',其中U为正交矩阶,T为Schur矩阵
tic %计时器-头部
A=[1 1 1 1;1 2 3 4;1 3 6 10;1 4 10 20];
b = [1 4 7 -2]';
[U,T] = schur(A)
x = U/T*U'*b
toc %计时器-结尾
- 适用于阶数很高或零元素多的矩阵!
- 迭代法是将求一组解转换为求一个近似解序列的过程,并用最终的近似解来逼近真实解。
- 迭代法需要考虑以下3个重要的问题。
(1) 迭代的初始值
(2) 迭代算法
(3) 迭代的收敛性
x k + 1 = ( I − A ) x k + b x _ { k + 1 } = ( I - A ) x _ { k } + b xk+1=(I−A)xk+b
[x,n] =richason(A, b, xO, eps, M) %用里查森迭代法求线性方程组Ax=b的解。
function [x,n]=richason(A,b,x0,eps,M)
% 采用里查森迭代法求线性方程组Ax=b的解
% 线性方程组的系数矩阵: A
% 线性方程组中的常数向量: b
% 迭代初始向章: x0
% 解的精度控制: eps
% 迭代步数控制: M
% 线性方程组的解: x
% 求出所需精度的解实际的迭代步数: n
if(nargin == 3)
eps = 1.0e-6 ; % eps 表示迭代精度
M = 200; % M 表示迭代步数的限制值
elseif(nargin == 4)
M = 200;
end
I =eye(size(A));
x1 = x0;
x=(I-A)*x0+b;
n =1;
%迭代过程
while(norm(x-x1)>eps)
x1 = x;
x = (I-A)*x1+b;
n = n + 1;
if(n >= M)
disp('warnning:迭代次数太多,可能不收敛!');
return;
end
end
A = [1.017 -0.0092 -0.0095;-0.0092 0.9903 0.0136;-0.0095 0.0136 0.9898];
b = [1 0 1]';
x0 = [0 0 0]';
[x,n] = richason(A,b,x0)