线性方程组具有一般形式:
其中,
如果线性方程组的系数矩阵
其中
一、消去法
1、高斯(Gauss)消去法
(1) 高斯消去法原理
为统一起见,将上面方程组改写成:
右上角的数字用于区分消元前后的系数变换,简记为:
其中:
一般地,求解
第一步:设
其中:
方程组简记为
第二步:设
如此循环往复,直到完成
简记为:
然后按照变量的逆序,逐步回代得到原来方程组的解。
(2) 高斯消去法代码
下面是这套算法的MATLAB代码:
function x = gauss_solve(A, b) n = length(b); for k = 1:n-1 for i = k+1:n if abs(A(i,k)) > abs(A(k,k)) A([k i], :) = A([i k], :); b([k i]) = b([i k]); end end if abs(A(k,k)) < eps x = []; return; end m = A(k+1:n, k) / A(k,k); A(k+1:n, k) = m; b(k+1:n) = b(k+1:n) - m * b(k); A(k+1:n, k+1:n) = A(k+1:n, k+1:n) - m * A(k, k+1:n); end if abs(A(n,n)) < eps x = []; return; end x = zeros(n,1); x(n) = b(n) / A(n,n); for i = n-1:-1:1 x(i) = (b(i) - A(i, i+1:n) * x(i+1:n)) / A(i,i); endend(3) 高斯消去法计算量
由于计算机作乘除运算所需时间远大于作加减运算所需时间,故我们只讨论乘除运算量。对于三元一次线性方程组的情况,由消去法步骤知,在进行第
乘法次数:
除法次数:
在回代过程中,计算
所以,高斯消去法的乘除总运算量为:
对于
2、主元素消去法
(1) 主元素消去法原理
高斯消去法的计算过程中要求
为简便起见,使用增广矩阵
表示方程组,并直接在增广矩阵上运算。列主元素法的基本思想是在每次消元前,在要消去未知数的系数中找绝对值最大的系数作为主元,通过方程对换将其换到对角线上,然后进行消元。其具体步骤如下:
第一步:首先在矩阵的第
第二步:在矩阵
将矩阵
第三步:在矩阵
将
(2) 列主元素消去法代码
下面是这套算法的MATLAB代码:
function x = gauss_solve(A, b) n = length(b); for k = 1:n-1 [~, p] = max(abs(A(k:n, k))); % 寻找最大主元所在行数 p = p + k - 1; if p ~= k % 交换 A([k p], :) = A([p k], :); b([k p]) = b([p k]); end tol = eps * norm(A, inf); % 防止因为数值稳定性问题对是否有解的判定造成影响 if abs(A(k,k)) < tol x = []; return; end m = A(k+1:n, k) / A(k,k); A(k+1:n, k) = m; b(k+1:n) = b(k+1:n) - m * b(k); A(k+1:n, k+1:n) = A(k+1:n, k+1:n) - m * A(k, k+1:n); end if abs(A(n,n)) < tol x = []; return; end x = zeros(n,1); x(n) = b(n) / A(n,n); for i = n-1:-1:1 x(i) = (b(i) - A(i, i+1:n) * x(i+1:n)) / A(i,i); endend相比于原始的高斯消去法,这里使用用矩阵向量运算代替 for 循环,可以显著提高程序运行速度。
二、直接三角分解法
1、高斯消去法的矩阵形式(LU分解)
(1) LU分解原理
高斯消去法的消元过程可以使用一串初等矩阵左乘增广矩阵表示,例如将第一行同乘
那么对于同一列的消元,可以将上面类型的初等行变换相继左乘得到,例如第一次消元等价于使用矩阵
那么第
经过
因为
于是有:
令:
可以得到:
则有:
这说明,消元过程实际上是把系数矩阵
上述分解称为杜利特尔(Doolittle)分解,也称为LU分解。当系数矩阵进行三角分解后,求解方程组
高斯消去法要求主元元素
设
(2) LU分解代码
下面是计算得出矩阵
function [L, U] = lu_decomp(A) n = size(A,2); U = A; L = eye(n); for k = 1:n-1 L(k+1:n, k) = U(k+1:n, k) / U(k, k); U(k+1:n, k+1:n) = U(k+1:n, k+1:n) - L(k+1:n, k) * U(k, k+1:n); U(k+1:n, k) = 0; endend下面是通过矩阵
function x = LU_solve(L, U, b) n = size(b, 1); y = zeros(n, 1); x = zeros(n, 1); for i = 1:n y(i) = b(i) - L(i, 1:i-1) * y(1:i-1); end for i = n:-1:1 x(i) = (y(i) - U(i, i+1:n) * x(i+1:n)) / U(i, i); endend2、列主元素的三角分解法
从直接三角分解公式知,当
设矩阵
我们一般不使用这种方法,但是下面给出一份代码,在已知
function x = solveWithPLU(P, L, U, b) n = size(b, 1); y = zeros(n, 1); x = zeros(n, 1); Pb = P * b; for i = 1:n y(i) = Pb(i) - L(i, 1:i-1) * y(1:i-1); end for i = n:-1:1 x(i) = (y(i) - U(i, i+1:n) * x(i+1:n)) / U(i, i); endend三、特殊矩阵的三角分解法
1、解三对角方程组的追赶法
(1) 原理
方程组:
称为三对角方程组,其中系数矩阵
则
其中
NOTE
条件的引出: 这三个条件在数学上被称为严格对角占优(首尾严格,中间非严格但整体不可约)。 在后面的计算中,我们需要不断地除以主对角线相关的元素(即公式中的
利用待定系数法计算,可以得到:
当矩阵
解
再解
称上述求解三对角方程组的方法为追赶法。由于矩阵中出现了大量零元素,从而使得计算公式简化,计算量大为减少,乘除法的运算量为
(2) 代码
由于矩阵的大部分位置都是
实现求解的MATLAB代码如下:
function x = solve_tridiag(a, p, q, b) n = length(a); l = zeros(n, 1); u = zeros(n, 1); u(1) = a(1); for i = 1:n if i > 1 l(i) = q(i-1) / u(i-1); u(i) = a(i) - l(i) * p(i-1); end end y = zeros(n, 1); y(1) = b(1); for i = 2:n y(i) = b(i) - l(i) * y(i-1); end x = zeros(n, 1); x(n) = y(n) / u(n); for i = n-1:-1:1 x(i) = (y(i) - p(i) * x(i+1)) / u(i); endend2、平方根法
(1) 朴素平方根法(Cholesky分解法)
NOTE
前置定理:设
且
根据前置定理,使用待定系数法可以导出
比较
计算顺序是按列进行,即:
当矩阵
它们的解分别为:
求解线性方程组的上述方法称为平方根法,也称为 Cholesky 分解法。这种方法无需选主元,计算过程也是稳定的。由于
(2) 改进平方根法( 法)
上面朴素方法中的前置定理的证明过程表明,对称正定矩阵
其中
然后利用待定系数法,导出
计算顺序如下:
为避免重复计算,引进辅助量:
则上式可改写成:
按上式进行
矩阵
求解线性方程组的这一方法称为改进平方根法,也叫
TIP
能够进行
(3) 代码
下面是对矩阵做
function L = decompLL(A) L = eye(size(A)); n = size(A, 1); d = zeros(n, 1); for k = 1:n L(k, k) = sqrt(A(k, k) - L(k, 1:k-1) * (L(k, 1:k-1))'); L(k+1:n, k) = (A(k+1:n, k) - L(k+1:n, 1:k-1) * (L(k, 1:k-1))') / L(k, k); endend下面是利用
function x = solveWithLL(L, b) n = length(b); y = zeros(1, n); x = zeros(1, n); for k = 1:n y(k) = b(k) - L(k, 1:k-1) * (y(1:k-1))'; end for k = n:-1:1 x(k) = (y(k) - x(k+1:n) * L(k+1:n, k)) / L(k, k); endend下面是对矩阵做
function [L, D] = decompLDL(A) D = zeros(size(A)); L = eye(size(A)); U = zeros(size(A)); n = size(A, 1); d = zeros(n, 1); for k = 1:n d(k) = A(k, k) - U(k, 1:k-1) * (L(k, 1:k-1))'; D(k, k) = d(k); U(k+1:n, k) = A(k+1:n, k) - U(k+1:n, 1:k-1) * (L(k, 1:k-1))'; L(k+1:n, k) = U(k+1:n, k) / d(k); endend下面是利用
function x = solveWithLDL(L, D, b) n = length(b); y = zeros(1, n); x = zeros(1, n); y(1) = b(1); for k = 2:n y(k) = b(k) - L(k, 1:k-1) * (y(1:k-1))'; end x(n) = y(n) / D(n, n); for k = n-1:-1:1 x(k) = y(k) / D(k, k) - x(k+1:n) * L(k+1:n, k); endend四、误差分析
1、向量范数
(1) 定义
设
- 正定性(非负性且仅在零向量时为零):
- 齐次性(绝对齐次):
- 三角不等式:
这三条构成范数的公理。
(2) 常见向量范数(p-范数及特殊范数)
对
三个常用的情形:
- 1-范数(曼哈顿范数):
- 2-范数(欧几里得范数):
-范数(切比雪夫范数):
这些都是满足范数公理的函数(下文给出证明与必要不等式)。
(3) 有限维空间范数之间的等价性
在有限维向量空间
我们称任意两范数都是等价的。可以证明,1-范数、2-范数和
2、矩阵范数
(1) 定义
设
, 且 (相容性条件)
上述1-3条为向量范数的直接推广,第四条会使矩阵范数在数值计算中使用更加方便。此外,常用的一类矩阵范数是由向量范数诱导的范数,定义如下:
给定向量范数
其满足矩阵范数的性质要求。
(2) 常见矩阵向量
-
1-范数(矩阵):
即各列绝对值和的最大值(最大列和)。
-
-范数(矩阵):即各行绝对值和的最大值(最大行和)。
-
2-范数(谱范数):
这里
表示对称正定矩阵 的最大特征值。 -
Frobenius 范数(F-范数,希尔伯特–施密特范数):
矩阵的F-范数可以认为是向量2-范数的直接推广,将
阶方阵看做 维向量所得到。可以证明,矩阵的F-范数与向量的2-范数相容,但F-范数不是由向量范数诱导出的矩阵范数,因为 ,而诱导出的矩阵范数上述值都为 。
(3) 等价性与误差
如果将矩阵范数看作
矩阵的误差可用矩阵范数表示。设
3、方程组的状态与条件数
一个实际问题化为数学问题,初始数据往往会有误差,即有扰动,从而使计算结果产生误差,因此需要研究扰动对解的影响。
当一个方程组,由于系数矩阵或右端项的微小扰动,而引起解发生巨大变化时,称该方程组是“病态”的。为了定量刻画方程组“病态”的程度,下面对方程组:
就系数矩阵或右端项分别有扰动的两种情形进行讨论。首先考察右端项
由
两边取范数,得:
又因为对于任意向量
从而:
这里用到
上式表明,当右端项有扰动时,解的相对误差不超过右端项的相对误差的
如果
首先由扰动方程出发:
展开得:
将含
两边左乘
因此:
当
于是取范数并利用三角不等式得到:
两边除以
(由
将
在仅有系数矩阵扰动且
上式表明,当系数矩阵有扰动时,解的扰动仍与
总的来说,若系数矩阵
综合上述各式可以得出,当系数矩阵或右端项有扰动时,数
对于非奇异矩阵
NOTE
在题目未明确说明的情况下,通常在计算时使用2-范数。