设有线性方程组如下所示:
{ a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n = b 1 , a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n = b 2 , ⋮ a n 1 x 1 + a n 2 x 2 + ⋯ + a n n x n = b n , \begin{cases}a_{11}x_{1}+a_{12}x_{2}+\cdots+a_{1n}x_{n}=b_{1},\\a_{21}x_{1}+a_{22}x_{2}+\cdots+a_{2n}x_{n}=b_{2},\\\vdots\\a_{n1}x_{1}+a_{n2}x_{2}+\cdots+a_{nn}x_{n}=b_{n},\end{cases} ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧a11x1+a12x2+⋯+a1nxn=b1,a21x1+a22x2+⋯+a2nxn=b2,⋮an1x1+an2x2+⋯+annxn=bn,
或者写成矩阵形式如下所示
[ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a 1 n a 2 n ⋯ a n n ] [ x 1 x 2 ⋮ x n ] = [ b 1 b 2 ⋮ b n ] \left[\begin{matrix}a_{11} & a_{12} & \cdots & a_{1n}\\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{1n} & a_{2n} & \cdots & a_{nn} \\\end{matrix}\right] \left[\begin{matrix}x_{1}\\x_{2}\\\vdots\\x_{n}\\\end{matrix}\right]=\left[\begin{matrix}b_{1}\\b_{2}\\\vdots\\b_{n}\\\end{matrix}\right] ⎣⎢⎢⎢⎡a11a21⋮a1na12a22⋮a2n⋯⋯⋱⋯a1na2n⋮ann⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡b1b2⋮bn⎦⎥⎥⎥⎤
将此方程简记为 A x = b Ax=b Ax=b
高斯消元法解线性方程组的基本思想是用逐次消去未知数的方法把原线性方程组 A x = b Ax=b Ax=b化为与其等价的三角形线性方程组,而求解三角形线性方程组可用回代的方法求解。
由于直接高斯消元法往往因为主元 a k k ( k ) a^{(k)}_{kk} akk(k)过小,会导致乘数 m i k = a i k ( k ) / a k k ( k ) m_{ik}=a^{(k)}_{ik}/a^{(k)}_{kk} mik=aik(k)/akk(k)损失较多位有效数字,比如用直接高斯消元法求解下面的线性方程组: [ 0.001 2.000 3.000 − 1.000 3.712 4.623 − 2.000 1.072 5.643 ] [ x 1 x 2 x 3 ] = [ 1.000 2.000 3.000 ] \left[\begin{matrix} 0.001 & 2.000 & 3.000 \\ -1.000 & 3.712 & 4.623 \\ -2.000 & 1.072 & 5.643 \\\end{matrix}\right]\ \left[\begin{matrix} x_1 \\ x_2 \\ x_3 \\\end{matrix}\right] = \left[\begin{matrix} 1.000 \\ 2.000 \\ 3.000 \\\end{matrix}\right] ⎣⎡0.001−1.000−2.0002.0003.7121.0723.0004.6235.643⎦⎤ ⎣⎡x1x2x3⎦⎤=⎣⎡1.0002.0003.000⎦⎤.
该矩阵的的准确解为: x ∗ = ( − 0.4904 , − 0.05104 , 0.3675 ) T x^{*}=\left(\begin{matrix} -0.4904, -0.05104, 0.3675\end{matrix}\right)^T x∗=(−0.4904,−0.05104,0.3675)T
若用直接高斯消元法求解该方程组,则得到的解为: x ‾ = ( − 0.400 , − 0.09980 , 0.4000 ) T \overline{x}=\left(\begin{matrix} -0.400, -0.09980, 0.4000\end{matrix}\right)^T x=(−0.400,−0.09980,0.4000)T
可见该结果跟实际值相差还是很大的,所以需要改进算法,下面引入列主元消去法,若我们在进行高斯消元法时,将主元选取为该列的最大元素,即该矩阵为: [ − 2.000 1.072 5.643 − 1.000 3.712 4.623 0.001 2.000 3.000 ] [ x 1 x 2 x 3 ] = [ 3.000 2.000 1.000 ] \left[\begin{matrix} -2.000 & 1.072 & 5.643 \\ -1.000 & 3.712 & 4.623 \\ 0.001 & 2.000 & 3.000 \\\end{matrix}\right]\left[\begin{matrix} x_1 \\ x_2 \\ x_3 \\\end{matrix}\right] = \left[\begin{matrix} 3.000 \\ 2.000 \\ 1.000 \\\end{matrix}\right] ⎣⎡−2.000−1.0000.0011.0723.7122.0005.6434.6233.000⎦⎤⎣⎡x1x2x3⎦⎤=⎣⎡3.0002.0001.000⎦⎤
用这种选取主元的方法可以求得解为: x ‾ = ( − 0.4900 , − 0.05113 , 0.3678 ) T ≈ x ∗ \overline{x}=\left(\begin{matrix} -0.4900, -0.05113, 0.3678\end{matrix}\right)^T\approx x^{*} x=(−0.4900,−0.05113,0.3678)T≈x∗
用这种方法求得的结果比较接近于实际值。
因为直接高斯消元法容易因为主元过小,而导致误差很大,所以在一般求解的时候采用列主元消去法改进高斯消元法,具体实现的代码如下所示:
function [ x ] = Gauss_solve( A,b )
n = size(A,1);
x = zeros(n,1);
%寻找当前列的绝对值最大的元素
for k = 1:n-1
Max = abs(A(k,k));
MaxIndex = k;
for u = k+1:n
if(abs(A(u,k)) > Max)
MaxIndex = u;
Max = abs(A(u,k));
end
end
%交换增广矩阵相应的行和列
temp = A(MaxIndex,:);
A(MaxIndex,:) = A(k,:);
A(k,:) = temp;
bt = b(MaxIndex);
b(MaxIndex) = b(k);
b(k) = bt;
%判断顺序余子式是否为0,若是则方程无法用Gauss求解
Det = A(1:k,1:k);
if(Det==0)
error('This matrix can''t be solved by Gauss algorithm');
end
%Gauss消元法的消元计算
for i = k+1:n
Mik = A(i,k)/A(k,k);
b(i) = b(i) - Mik*b(k);
for j = k+1:n
A(i,j) = A(i,j) - Mik*A(k,j);
end
disp(A);
disp(b);
end
end
%Gauss回代运算
x(n) = b(n) / A(n,n);
for i = n-1:-1:1
x(i) = ( b(i) - sum(A(i,i+1:n)*x(i+1:n)) ) / A(i,i);
end
end