参数设置
非对角线元素固定: A[1,2]=3, A[1,3]=2, A[2,1]=1, A[2,3]=1, A[3,1]=2, A[3,2]=1。b[2]=8, b[3]=13 固定。
高斯消去:A→U 与 L 的构成(动画)
绿=主元(对角线)/橙=正在消去的行。右侧 L 填入各行倍数 l_ij=a_ij/a_kk,左侧工作矩阵收敛为 U。
L·U 分解和前进、后退代入解
绿=下三角L(对角线=1)/蓝=上三角U/黄=中间向量y=L⁻¹·b/橙=解x=U⁻¹·y
理论、主要公式
LU分解是一种将正方矩阵A分解为L(单位下三角)和U(上三角)乘积的方法。加入部分主元选择后,可以写成 P·A = L·U 的形式。
分解的公式(Doolittle法,L的对角为1):
$$P \cdot A = L \cdot U, \quad L_{ii} = 1$$
Ax=b可以通过两个三角系统求解。前进代入求 y,后退代入求 x:
$$L\,y = P\,b \quad\Longrightarrow\quad U\,x = y$$
行列式和残差。det(A) 是U的对角线元素的乘积(带有行交换次数的符号),残差是数值误差的指标:
$$\det(A) = (-1)^{s}\prod_i U_{ii}, \qquad r = \|A\,x - b\|_2$$
计算复杂度为 O(n³)。一旦分解完成,对于同一个 A 可以用 O(n²) 的时间求解多个右手边 b,因此在有限元法的多荷载工况中显示出强大的威力。
LU分解模拟器简介
🙋
线性方程组就是中学里面用加减消元法解的那个,对吧?计算机也是这样做的吗?
🎓
基本思路是一样的「高斯消去法」。但实务中会把消去过程中的中间结果保存为「L和U这两个矩阵」。这就是LU分解。看看上面的模拟器第二个画布,绿色的L是「消去时对每一行乘的倍数」,蓝色的U是「整理好的上三角矩阵」。这两个矩阵的乘积可以还原A。
🎓
好处在这里。比如有限元法的线性静力分析,同一个刚性矩阵K,要对10个、100个不同的荷载工况求解。把LU分解一次保存起来,之后每个工况只需要「前进代入和后退代入」就行。一次分解是O(n³)的重操作,但每个工况只要O(n²)。1000元方程的话,一次分解的成本就能解1000个工况!
🙋
「部分主元选择」是什么意思?模拟器下面提了一下。
🎓
消去时要除以对角线元素(主元)。如果主元是0或非常小的数,除法就会爆炸误差。所以每一步先从当前列里找绝对值最大的元素,交换行,然后再消去。这叫部分主元选择。试试把A[1,1]设成1,b[1]设成-20,看看行交换怎么自动跑起来,解还是对的。
🎓
对。求出的x代进原矩阵A,和b做差,这个差向量的长度就是残差。理论上应该是0,实际上用双精度浮点数也只能到10⁻¹⁰这个量级。要是残差变成1或10,说明矩阵接近奇异(条件数极大)或者代码有bug。残差检查是「自我验证数值解」的必做功课。
常见问答
两者都是LU分解的实现方式。Doolittle法把L的对角设为1,Crout法把U的对角设为1。本工具用的是Doolittle法,所以L的对角全是1,而U的对角是主元值。数值结果本质相同,选择通常取决于内存排列和运算顺序的偏好。教科书里Doolittle法用得更普遍。
条件数定义为 cond(A)=‖A‖·‖A⁻¹‖,表示输入数据的误差会被放大多少倍到解里。条件数是10ᵏ时,用双精度浮点(约16位精度)求得的解会失去大约k位有效数字。条件数超过10¹⁶就没有可信的解了。实务中用迭代改进法(iterative refinement)、重标度、或改变定式来应对。
大规模有限元和计算流体力学的矩阵99%以上是0(稀疏矩阵)。直接分解会在原来为0的位置产生新的非零值(fill-in),导致内存爆炸。实务中用AMD、METIS等重新排列行列顺序来减少fill-in,再用SuperLU、PARDISO、MUMPS等稀疏LU库。如果数据量非常大,反复共轭梯度法(CG)或GMRES等迭代法更有利。
线性弹性分析的刚性矩阵K是对称正定的,用Cholesky分解(K=L·Lᵀ)比LU分解快一倍、省内存一倍,也比较稳定。接触分析、塑性分析、流体结构耦合等非对称情况才用LU分解。动力学分析的质量矩阵也是对称正定,特征值分析也多用Cholesky。关键是「一次分解、多右手边重用」的场景,直接法的优势最大。
现实应用
有限元法(FEM)线性静力分析:结构分析软件(NASTRAN、Abaqus、ANSYS、Marc等)的核心是对刚性矩阵的直接解法。对称正定用Cholesky,一般情况用LU分解,同一个刚性矩阵对多个荷载工况(自重、风载、地震、温度等)求解时,分解一次的重用价值巨大。稀疏版本(SuperLU、PARDISO、MUMPS)是业界标准,能在实用时间内解决数千万自由度的模型。
电路仿真(SPICE):电路节点方程 G·v = i 中,节点导纳矩阵G通常是稀疏的对称矩阵,用LU分解求解。SPICE类仿真器在时间积分的每一步都要线性化并求解,如果矩阵的非零模式不变,LU的重用会大幅加速。
最优化和机器学习的正规方程:线性最小二乘 (XᵀX)·β = Xᵀy 的正规方程,或高斯过程回归的 (K+σ²I)·α = y,都是对称正定矩阵,用Cholesky分解(特殊的LU)求解。批量学习和贝叶斯推断的中心步骤,矩阵分解的速度直接影响整体性能。
控制理论的Lyapunov方程:状态空间模型的稳定性判定中出现的连续时间Lyapunov方程 AᵀP + PA = -Q,用Bartels-Stewart法先对A作Schur分解,再对三角矩阵做代入求解。本质是LU分解对上、下三角系的代入应用,MATLAB控制工具箱等的标准实现。
常见误区和注意事项
最常见的误区是以为「LU分解是为了求逆矩阵」。实际上解Ax=b根本不需要显式计算逆矩阵A⁻¹,LU分解就够了。陈显出逆矩阵会让内存和计算量增加约3倍,数值误差也变大。MATLAB推荐用 \(A\b\)(反斜杠,内部用LU)而不是 inv(A)*b,理由就在这。本工具也不计算任何逆矩阵,只靠L·y和U·x这两步代入求解。
其次是误认为「有部分主元选择就总是数值稳定」。部分主元选择防止对角线变得太小,但矩阵本身条件数很大(接近奇异)的话,解的精度依然会下降。试试把A[1,1]=A[2,2]=A[3,3]都设成1,会看到行列式变小、残差容易增大。实务中要事先估计条件数(rcond函数)或用反复改进法来保证精度。
最后是「直接法复杂度O(n³),随意拿去解大规模问题」的失误。3×3瞬间完成,但自由度100万的FEM矩阵要直接分解,内存和时间都是天文数字。即使是稀疏版LU(SuperLU、PARDISO),也常在几百万自由度以上不如共轭梯度法(CG)、GMRES、代数多网格等迭代法。一定要先问「对称吗」「正定吗」「稀疏吗」「多大」,再选方法。本工具是入门的3×3,背后有数值线性代数半个多世纪的沉淀。
具体计算例
钢框架结构3自由度体系,刚性矩阵A=[5.0, -1.0, 0; -1.0, 4.5, -0.5; 0, -0.5, 3.8],荷载向量b=[1000N, 500N, 250N]时,LU分解后行列式det(A)≈84.35,无主元选择时条件数3.2,解为x_1≈210mm、x_2≈145mm、x_3≈75mm,残差‖Ax-b‖_2≈0.012。应用主元后残差降低到1/100以下