MATLAB线性方程组,运算符、inv()、pinv()全解析

线性方程组求解是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的维度和秩,方程组分为三类:

  1. 适定方程组 :m=nm=nm=n且AAA满秩(唯一解);
  2. 超定方程组 :m>nm>nm>n(无解,求最小二乘解);
  3. 欠定方程组 :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. 选型原则(优先级从高到低)

  1. 优先用\运算符:无论方程组类型(适定/超定/欠定),\运算符自动选择最优算法,效率和精度均最优;
  2. 仅在特殊场景用inv() :需手动获取逆矩阵(如矩阵分析),且确认AAA为非奇异方阵;
  3. 仅在病态矩阵场景用pinv() :AAA奇异、或需要更高鲁棒性的最小二乘解时使用。

四、常见问题与避坑指南

1. "Matrix is singular"报错(矩阵奇异)

  • 原因:AAA为奇异矩阵(行列式=0),inv()无法求解;
  • 解决:改用pinv()\运算符。

2. 解的精度低(残差大)

  • 原因:AAA为病态矩阵(条件数大),或数据存在噪声;
  • 解决:
    1. cond(A)计算条件数(值越大越病态);
    2. 病态矩阵优先用pinv()
    3. 对数据做预处理(如归一化)。

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
相关推荐
一起努力啊~2 小时前
算法刷题--双指针法
算法
Coovally AI模型快速验证2 小时前
从“单例模仿”到“多面融合”,视觉上下文学习迈向“团队协作”式提示融合
人工智能·学习·算法·yolo·计算机视觉·人机交互
明洞日记2 小时前
【软考每日一练007】位图计算与内存管理深度全解
c++·算法·ai·操作系统·进程
敲敲了个代码2 小时前
前端指纹技术是如何实现的?(Canvas、Audio、硬件API 核心原理解密)
前端·javascript·学习·算法·面试·web
学编程就要猛2 小时前
算法:5.在排序数组中查找元素的第⼀个和最后⼀个位置
算法
夏鹏今天学习了吗2 小时前
【LeetCode热题100(84/100)】乘积最大子数组
算法·leetcode·职场和发展
Yupureki2 小时前
《算法竞赛从入门到国奖》算法基础:入门篇-递归初阶
c语言·开发语言·数据结构·c++·算法·visual studio
a3535413822 小时前
牛顿迭代法中的雅克比矩阵几何意义
线性代数·算法
Coder个人博客2 小时前
Linux6.19-ARM64 crypto NH-Poly1305 NEON子模块深入分析
linux·网络·算法·车载系统·系统架构·系统安全·鸿蒙系统