线性方程组求解是MATLAB数值计算的核心应用之一,广泛用于工程计算、物理建模、数据分析等领域。MATLAB提供了多种求解方法,其中\运算符、inv()、pinv()是最常用的三种方式,不同方法适配不同场景的方程组(适定、超定、欠定)。
一、线性方程组的基本形式
在开始求解前,先明确线性方程组的矩阵表示形式:
对于方程组 A⋅X=BA \cdot X = BA⋅X=B:
- AAA:系数矩阵(m×nm×nm×n,mmm为方程数,nnn为未知数个数);
- XXX:未知数列向量(n×1n×1n×1);
- BBB:常数项列向量(m×1m×1m×1)。
根据AAA的维度和秩,方程组分为三类:
- 适定方程组 :m=nm=nm=n且AAA满秩(唯一解);
- 超定方程组 :m>nm>nm>n(无解,求最小二乘解);
- 欠定方程组 :m<nm<nm<n(无穷多解,求最小范数解)。
三种求解方法的核心适配场景:
| 方法 | 核心适配场景 | 计算效率 | 精度 |
|---|---|---|---|
\ 运算符 |
所有类型(优先推荐) | 最高 | 最高 |
inv() |
适定方程组(小规模矩阵) | 中等 | 较高 |
pinv() |
超定/欠定/奇异矩阵方程组 | 较低 | 适用于病态矩阵 |
二、核心求解方法实操
1. \运算符(左除,推荐首选)
\是MATLAB求解线性方程组的"最优解算子",无需手动判断方程组类型,会自动根据AAA的特性选择最优算法(直接求解/最小二乘/最小范数),计算效率和精度均为最优。
场景1:适定方程组(唯一解)
示例 :求解方程组
{x1+2x2+3x3=142x1+5x2+2x3=183x1+x2+5x3=20\begin{cases} x_1 + 2x_2 + 3x_3 = 14 \\ 2x_1 + 5x_2 + 2x_3 = 18 \\ 3x_1 + x_2 + 5x_3 = 20 \end{cases}⎩ ⎨ ⎧x1+2x2+3x3=142x1+5x2+2x3=183x1+x2+5x3=20
对应矩阵形式 A⋅X=BA \cdot X = BA⋅X=B:
A=[123252315],B=[141820]A = \begin{bmatrix}1 & 2 & 3 \\ 2 & 5 & 2 \\ 3 & 1 & 5\end{bmatrix}, \quad B = \begin{bmatrix}14 \\ 18 \\ 20\end{bmatrix}A= 123251325 ,B= 141820
代码实现:
matlab
% 步骤1:定义系数矩阵A和常数向量B
A = [1 2 3; 2 5 2; 3 1 5];
B = [14; 18; 20];
% 步骤2:使用\运算符求解
X = A \ B;
% 步骤3:验证解的正确性(残差接近0则正确)
residual = A * X - B;
% 输出结果
disp('方程组的解:');
disp(X);
disp('残差(理论应为0):');
disp(residual);
输出结果:
方程组的解:
1.0000
2.0000
3.0000
残差(理论应为0):
1.0e-14 *
-0.0888
0.1776
0
场景2:超定方程组(最小二乘解)
示例 :求解超定方程组(4个方程,3个未知数)
{x1+x2+x3=62x1+x2=7x1+3x3=103x2+2x3=11\begin{cases} x_1 + x_2 + x_3 = 6 \\ 2x_1 + x_2 = 7 \\ x_1 + 3x_3 = 10 \\ 3x_2 + 2x_3 = 11 \end{cases}⎩ ⎨ ⎧x1+x2+x3=62x1+x2=7x1+3x3=103x2+2x3=11
代码实现:
matlab
A = [1 1 1; 2 1 0; 1 0 3; 0 3 2];
B = [6; 7; 10; 11];
% \运算符自动计算最小二乘解
X = A \ B;
% 计算残差平方和(评估拟合效果)
residual_sum = sum((A * X - B).^2);
disp('最小二乘解:');
disp(X);
disp('残差平方和:');
disp(residual_sum);
场景3:欠定方程组(最小范数解)
示例 :求解欠定方程组(2个方程,3个未知数)
{x1+2x2+3x3=142x1+5x2+2x3=18\begin{cases} x_1 + 2x_2 + 3x_3 = 14 \\ 2x_1 + 5x_2 + 2x_3 = 18 \end{cases}{x1+2x2+3x3=142x1+5x2+2x3=18
代码实现:
matlab
A = [1 2 3; 2 5 2];
B = [14; 18];
% \运算符自动计算最小范数解
X = A \ B;
disp('最小范数解:');
disp(X);
2. inv()函数(矩阵求逆,仅适定方程组)
inv(A)用于计算可逆矩阵AAA的逆矩阵,仅适用于m=nm=nm=n且AAA非奇异(满秩)的适定方程组,求解逻辑为 X=inv(A)⋅BX = inv(A) \cdot BX=inv(A)⋅B。
注意:inv()计算效率低于\运算符,且对病态矩阵(行列式接近0)精度差,非必要不推荐使用。
示例:用inv()求解上述适定方程组
matlab
A = [1 2 3; 2 5 2; 3 1 5];
B = [14; 18; 20];
% 求逆矩阵求解
X_inv = inv(A) * B;
disp('inv()求解结果:');
disp(X_inv);
% 对比\运算符结果(验证一致性)
X_backslash = A \ B;
disp('\\运算符求解结果:');
disp(X_backslash);
输出结果:
inv()求解结果:
1.0000
2.0000
3.0000
\运算符求解结果:
1.0000
2.0000
3.0000
3. pinv()函数(伪逆矩阵,适配奇异/超定/欠定)
pinv(A)计算矩阵AAA的摩尔-彭罗斯伪逆,适用于以下场景:
- AAA为奇异矩阵(行列式=0,inv()无法求解);
- 超定方程组(求最小二乘解);
- 欠定方程组(求最小范数解)。
求解逻辑为 X=pinv(A)⋅BX = pinv(A) \cdot BX=pinv(A)⋅B,计算效率最低,但对病态矩阵鲁棒性强。
场景1:奇异矩阵方程组
示例 :求解系数矩阵奇异的适定方程组
{x1+x2+x3=62x1+2x2+2x3=12x1+2x2+3x3=14\begin{cases} x_1 + x_2 + x_3 = 6 \\ 2x_1 + 2x_2 + 2x_3 = 12 \\ x_1 + 2x_2 + 3x_3 = 14 \end{cases}⎩ ⎨ ⎧x1+x2+x3=62x1+2x2+2x3=12x1+2x2+3x3=14
(AAA的秩=2 < 3,inv()报错,需用pinv())
代码实现:
matlab
A = [1 1 1; 2 2 2; 1 2 3];
B = [6; 12; 14];
% inv(A)会报错:Matrix is singular to working precision.
% X_inv = inv(A) * B;
% 用pinv()求解
X_pinv = pinv(A) * B;
disp('pinv()求解结果:');
disp(X_pinv);
% 对比\运算符结果
X_backslash = A \ B;
disp('\\运算符求解结果:');
disp(X_backslash);
场景2:超定方程组(与\运算符对比)
matlab
A = [1 1 1; 2 1 0; 1 0 3; 0 3 2];
B = [6; 7; 10; 11];
% pinv()求解最小二乘解
X_pinv = pinv(A) * B;
% \运算符求解
X_backslash = A \ B;
disp('pinv()求解结果:');
disp(X_pinv);
disp('\\运算符求解结果:');
disp(X_backslash);
三、三种方法的核心对比与选型建议
1. 性能对比(以1000阶随机矩阵为例)
matlab
% 生成1000阶满秩随机矩阵
A = randn(1000);
B = randn(1000, 1);
% 测试\运算符耗时
tic;
X1 = A \ B;
t1 = toc;
% 测试inv()耗时
tic;
X2 = inv(A) * B;
t2 = toc;
% 测试pinv()耗时
tic;
X3 = pinv(A) * B;
t3 = toc;
disp(['\运算符耗时:', num2str(t1), 's']);
disp(['inv()耗时:', num2str(t2), 's']);
disp(['pinv()耗时:', num2str(t3), 's']);
典型输出:
\运算符耗时:0.021s
inv()耗时:0.058s
pinv()耗时:1.245s
2. 选型原则(优先级从高到低)
- 优先用\运算符:无论方程组类型(适定/超定/欠定),\运算符自动选择最优算法,效率和精度均最优;
- 仅在特殊场景用inv() :需手动获取逆矩阵(如矩阵分析),且确认AAA为非奇异方阵;
- 仅在病态矩阵场景用pinv() :AAA奇异、或需要更高鲁棒性的最小二乘解时使用。
四、常见问题与避坑指南
1. "Matrix is singular"报错(矩阵奇异)
- 原因:AAA为奇异矩阵(行列式=0),inv()无法求解;
- 解决:改用
pinv()或\运算符。
2. 解的精度低(残差大)
- 原因:AAA为病态矩阵(条件数大),或数据存在噪声;
- 解决:
- 用
cond(A)计算条件数(值越大越病态); - 病态矩阵优先用
pinv(); - 对数据做预处理(如归一化)。
- 用
3. 维度不匹配报错
- 原因:AAA的列数与BBB的行数不一致,或BBB为行向量;
- 解决:确保BBB为列向量(如
B = [6; 7; 8]而非B = [6 7 8])。
4. 欠定方程组解不唯一
- 原因:未知数个数多于方程数,有无穷多解;
- 说明:\运算符和pinv()均返回最小范数解(各元素平方和最小的解),满足工程需求。
五、完整实战案例(工程应用)
需求 :求解电路节点电压方程组(适定),验证解的正确性
{3V1−V2−V3=5−V1+4V2−2V3=0−V1−2V2+5V3=10\begin{cases} 3V_1 - V_2 - V_3 = 5 \\ -V_1 + 4V_2 - 2V_3 = 0 \\ -V_1 - 2V_2 + 5V_3 = 10 \end{cases}⎩ ⎨ ⎧3V1−V2−V3=5−V1+4V2−2V3=0−V1−2V2+5V3=10
完整代码:
matlab
% 1. 定义系数矩阵和常数向量
A = [3 -1 -1; -1 4 -2; -1 -2 5];
B = [5; 0; 10];
% 2. 三种方法求解对比
% 方法1:\运算符
X1 = A \ B;
% 方法2:inv()
X2 = inv(A) * B;
% 方法3:pinv()
X3 = pinv(A) * B;
% 3. 验证解的正确性
res1 = norm(A * X1 - B); % 残差的范数
res2 = norm(A * X2 - B);
res3 = norm(A * X3 - B);
% 4. 输出结果
disp('=== 求解结果对比 ===');
disp('\\运算符解:');
disp(X1);
disp('inv()解:');
disp(X2);
disp('pinv()解:');
disp(X3);
disp('=== 残差范数(越小越好) ===');
disp(['\\运算符:', num2str(res1)]);
disp(['inv():', num2str(res2)]);
disp(['pinv():', num2str(res3)]);
输出结果:
=== 求解结果对比 ===
\运算符解:
3.0000
2.0000
2.0000
inv()解:
3.0000
2.0000
2.0000
pinv()解:
3.0000
2.0000
2.0000
=== 残差范数(越小越好) ===
\运算符:1.1102e-15
inv():1.1102e-15
pinv():1.1102e-15