news 2026/10/14 23:19:11

逆矩阵微课演示(1)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
逆矩阵微课演示(1)

1.2.10 计算逆矩阵

主线比喻:逆矩阵 = 矩阵运算里的 Ctrl+Z 撤销键

① 导入:先变形,再撤销

修图时把照片旋转、拉伸,想恢复原样怎么办?按Ctrl+Z一键撤销。

矩阵 A 对数据做一次「加工」,A 的逆矩阵就是把这次加工「还原」回去。

② 什么是逆矩阵

  • 矩阵= 一台「加工机器」:把数据变个样子
  • 逆矩阵= 这台机器的「还原按钮」:把加工过的数据变回原样
  • 单位阵 I= 一台「啥也不干」的机器:进去什么样,出来还是什么样

换个比喻:把一句话翻译成英语(乘 A),再翻译回中文(乘 A 的逆),就得到原话。

数学上就是:A · A⁻¹ = I(先加工再还原 = 啥也没变)

③ 怎么知道能不能还原?

算一个数值叫行列式 det,它就是一张「体检报告」:

  • det ≠ 0 → 信息没丢,能还原
  • det = 0 → 信息被「压扁」了,还原不回去

想象复印机把一张画压成一条线:原来丰富的图案信息丢了,再也变不回原图。det=0 的矩阵就是这样。

2×2 手算口诀(方便对答案):主对角线交换位置、副对角线变号、整体除以 det。

🤔 互动预测 1

A @ A_inv会精确等于单位阵 I 吗?先想 30 秒,再运行下面这格。

importnumpyasnpimportmatplotlib.pyplotasplt plt.rcParams['font.sans-serif']=['Microsoft YaHei','SimHei']plt.rcParams['axes.unicode_minus']=False# 例 1:能还原的矩阵——求逆并验证A=np.array([[2,1],[1,2]])A_inv=np.linalg.inv(A)print('A =\n',A)print('A 的逆矩阵(还原矩阵)=\n',A_inv)print('\n验证:A @ A_inv =\n',A @ A_inv)print('用 allclose 判断(容忍小数尾巴):',np.allclose(A @ A_inv,np.eye(2)))# 手算口诀核对a,b,c,d=2,1,1,2manual=np.array([[d,-b],[-c,a]])/(a*d-b*c)print('\n手算口诀结果与 inv 一致:',np.allclose(manual,A_inv))

运行结果:

A = [[2 1] [1 2]] A 的逆矩阵(还原矩阵)= [[ 0.66666667 -0.33333333] [-0.33333333 0.66666667]] 验证:A @ A_inv = [[1. 0.] [0. 1.]] 用 allclose 判断(容忍小数尾巴): True 手算口诀结果与 inv 一致: True

💡 浮点误差(小数尾巴)

A @ A_inv对角线上是 1,但别的位置有1e-16这种极小量,不是精确的 0——这是计算机存小数时的「四舍五入尾巴」。

所以判断「是不是单位阵」不能用==,要用np.allclose()。

④ 先找找感觉:对角矩阵的逆 = 每个数取倒数

运行下面这格,你会看到结果特别好记。

# 例 2:对角矩阵——逆矩阵就是“每个数取倒数”D=np.array([[2,0],[0,4]])D_inv=np.linalg.inv(D)print('D =\n',D)print('D 的逆矩阵(对角线取倒数)=\n',D_inv)

运行结果:

D = [[2 0] [0 4]] D 的逆矩阵(对角线取倒数)= [[0.5 0. ] [0. 0.25]]

2 的倒数是 0.5,4 的倒数是 0.25。对角矩阵求逆,就是把对角线上每个数取倒数——这就是「还原」最直观的感觉。

🤔 互动预测 2

矩阵 B =[[1,2],[2,4]],第二行是第一行的 2 倍。

它还能「还原」吗?先预测,再运行下一格揭晓。

# 例 3:还原不回去的矩阵——det 等于 0B=np.array([[1,2],[2,4]])# 第二行是第一行的 2 倍,信息被“压扁”print('B =\n',B)print('det(B) =',np.linalg.det(B))# 0.0try:np.linalg.inv(B)exceptnp.linalg.LinAlgErrorase:print('强行求逆报错:',e)

运行结果:

B = [[1 2] [2 4]] det(B) = 0.0 强行求逆报错: Singular matrix

det=0 说明这台「加工机器」把信息压扁了,还原按钮自然失效,Python 会直接报错提醒你。

⑤ 还原不回去时:求一个「尽量还原」

现实数据经常有冗余(比如两列几乎一样),严格还原做不到。这时退而求其次,求一个广义逆(伪逆):np.linalg.pinv(),奇异矩阵也能算。

类比:回不到一模一样,就给出「最接近」的答案。

# 例 4:尽量还原(广义逆 / 伪逆)B_pinv=np.linalg.pinv(B)print('B 的广义逆 =\n',B_pinv)print('验证 B @ B_pinv @ B ≈ B:',np.allclose(B @ B_pinv @ B,B))

运行结果:

B 的广义逆 = [[0.04 0.08] [0.08 0.16]] 验证 B @ B_pinv @ B ≈ B: True

⑥ 为什么要学逆矩阵?——解方程组

方程组x + 2y = 5、2x + y = 4可以写成矩阵形式C·x = b,两边同乘 C 的逆:x = C⁻¹·b。

# 例 5:用逆矩阵解方程组C=np.array([[1,2],[2,1]])rhs=np.array([5,4])x=np.linalg.inv(C)@ rhsprint('x + 2y = 5');print('2x + y = 4')print('解得 x =',x)# [1. 2.],即 x=1, y=2print('与 np.linalg.solve 一致:',np.allclose(x,np.linalg.solve(C,rhs)))

运行结果:

x + 2y = 5 2x + y = 4 解得 x = [1. 2.] 与 np.linalg.solve 一致: True

⑦ 画图看:能还原 vs 不能还原

先看能还原的情况:单位圆被 A 拉成椭圆,再用 A 的逆把它拉回原状。

theta=np.linspace(0,2*np.pi,300)circle=np.vstack([np.cos(theta),np.sin(theta)])img_A=A @ circle back=A_inv @ img_A fig,ax=plt.subplots(1,3,figsize=(12,4),sharex=True,sharey=True)forainax:a.axhline(0,color='gray',lw=0.5)a.axvline(0,color='gray',lw=0.5)a.set_aspect('equal')ax[0].plot(*circle,lw=2);ax[0].set_title('原始单位圆')ax[1].plot(*img_A,lw=2);ax[1].set_title('A 变换后(椭圆)')ax[2].plot(*back,lw=2);ax[2].set_title('再用 A 的逆拉回')fig.suptitle('能还原:A 的逆把 A 的变换“撤销”回原状')plt.show()

再看不能还原的情况:同样一个圆,被 B 直接压成一条线——信息丢了,再也变不回圆。

fig2,ax2=plt.subplots(1,2,figsize=(8,4),sharex=True,sharey=True)forainax2:a.axhline(0,color='gray',lw=0.5)a.axvline(0,color='gray',lw=0.5)a.set_aspect('equal')ax2[0].plot(*circle,lw=2);ax2[0].set_title('原始单位圆')img_B=B @ circle ax2[1].plot(*img_B,lw=2);ax2[1].set_title('B 变换后:被压成一条线')fig2.suptitle('不能还原:信息被“压扁”,回不去了')plt.show()

⑧ 小结

inv是完美还原,det是能不能还原的体检报告,pinv是还原不了时的尽量还原。

函数作用(大白话)什么时候用
np.linalg.inv完美还原det≠0 的方阵
np.linalg.det体检报告先判断能不能还原
np.linalg.pinv尽量还原还原不回去时

下一节预告:用逆矩阵解线性方程组(1.2.12)。

⑨ 练一练

矩阵 E =[[4,7],[2,6]]:

  1. 先心算 det(E),判断它能不能还原;
  2. 再用口诀手算它的逆矩阵;
  3. 最后运行下面这格核对答案。
# 练习答案(先自己想,再运行核对)E=np.array([[4,7],[2,6]])print('det(E) =',np.linalg.det(E))# 10,非零 → 能还原print('E 的逆矩阵 =\n',np.linalg.inv(E))

运行结果:

det(E) = 10.000000000000002 E 的逆矩阵 = [[ 0.6 -0.7] [-0.2 0.4]]
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 23:19:08

轻量级桌面视觉分析系统设计与实现

1. 项目概述:这不是一个“会动的桌面小人”,而是一套轻量级桌面视觉分析系统“XiaoMate功能介绍:让桌宠帮你分析你的桌面屏幕”——这个标题乍看像某款萌系桌面助手的营销话术,但拆开来看,它藏着一个被严重低估的技术切…

作者头像 李华
网站建设 2026/10/14 23:18:39

Rust迭代器惰性求值与内存优化:告别中间collect,日志处理内存直降

1. 一次日志聚合任务&#xff0c;让我重新认识迭代器的内存差异前阵子我接到一个日志聚合的小需求&#xff1a;从几百 MB 的访问日志里统计每个接口的调用次数和总耗时。第一版写得很顺手&#xff0c;把BufReader::lines()先collect成一个Vec<String>&#xff0c;再逐行 …

作者头像 李华
网站建设 2026/10/14 23:17:59

HTML难点不在标签而在结构:语义化与嵌套自查

1. 先说一个被低估的事实&#xff1a;HTML的难度不在标签&#xff0c;而在结构聊前端基础&#xff0c;绕不开HTML&#xff1b;聊HTML&#xff0c;又常让人产生“这有什么好学的”错觉。甚至有人觉得HTML根本不算编程语言&#xff0c;随手写写就有页面出来&#xff0c;何必认真。…

作者头像 李华
网站建设 2026/10/14 23:17:11

配置顺序即索引:告别硬编码,实现自动化分配

这段时间我在重构一个内部系统&#xff0c;遇到一个非常典型的需求&#xff1a;一批渠道配置放在配置中心里&#xff0c;代码里却到处是写死的编号&#xff0c;0、1、2、3……每次新增一个渠道&#xff0c;既要改配置、又要改代码、还要同步改数据库注释&#xff0c;稍不留神顺…

作者头像 李华
网站建设 2026/10/14 23:17:10

协程上下文、Job与SupervisorJob:从取消到异常传播的完全解析

协程这名字这几年已经被说烂了&#xff0c;但每次在项目里看到崩溃日志和异常静默&#xff0c;还是能发现不少人对Job和SupervisorJob的理解只停留在“会用就行”。我甚至见过有人因为把SupervisorJob当成万能保险&#xff0c;最终在Android崩溃上报里看到整屏的CancellationEx…

作者头像 李华
网站建设 2026/10/14 23:16:59

SpringBoot+PostGIS构建千里巡检线:空间数据建模与查询实战

第一次在项目原型里看到整条巡检线路铺满地图的时候&#xff0c;我确实被这个项目的工作量震了一下。单条线路分支加主路&#xff0c;横跨一千多公里&#xff0c;穿越好几个生态和地形差异明显的区域&#xff0c;原来零散在各张表里的坐标点&#xff0c;到这里必须变成连续、可…

作者头像 李华