首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【线性代数】理解矩阵乘法的意义(点乘)

  • 25-03-02 23:02
  • 3174
  • 5518
blog.csdn.net

刚接触线性代数时,很不理解矩阵乘法的计算规则,为什么规则定义的看起来那么有规律却又莫名其妙,现在参考了一些资料,回过头重新总结下个人对矩阵乘法的理解(严格来说是点乘)。

理解矩阵和矩阵的乘法,可以先理解矩阵和向量的乘法,因为矩阵可以看成是不同列向量的集合。

基变换视角

下面从基变换视角理解矩阵的乘法原理,基变换视角是将矩阵看成一个新的参考系,矩阵的每个列向量是新基坐标系中的一个基向量。

先考虑一个规则的 2x2 的矩阵和一个 2x1 的向量之间的乘法,例如:
[ 1 − 2 1 2 ] [ 1 1 ] = [ − 1 3 ] [1−212]

[11−22]
[11]
[11]
= [−13]
[−13]
[11​−22​][11​]=[−13​]
后面为了方便描述,分别用A表示矩阵,a表示等号左边的向量(1, 1),b表示等号右边的向量(-1, 3)。

上面这个乘法过程可以理解为:把矩阵A看成一个新的基坐标系,(1, 1) 和 (-2, 2) 分别是新基坐标系中的两个轴。b(1, 1)是原始空间笛卡尔坐标系中的一个向量,左边乘上一个矩阵A,相当于求出在以矩阵A为新的基坐标系的视角下,向量(1, 1)在原始空间中的坐标表示。

可视化上面这个计算:

import numpy as np
import matplotlib.pyplot as plt

# 定义矩阵和向量
A = np.array([[1, -2], [1, 2]])
b = np.array([1, 1])

# 计算变换后的向量
b_transformed = A @ b

# 定义标准基
origin = np.array([[0, 0], [0, 0]])

# 绘制
fig, ax = plt.subplots()

# 绘制原始向量
ax.quiver(*origin, b[0], b[1], angles='xy', scale_units='xy', scale=1, color='blue', label='Original Vector (1,1)')

# 绘制新基
ax.quiver(*origin, A[0, 0], A[1, 0], angles='xy', scale_units='xy', scale=1, color='red', label='New x-axis (1,1)')
ax.quiver(*origin, A[0, 1], A[1, 1], angles='xy', scale_units='xy', scale=1, color='green', label='New y-axis (-2,2)')

# 绘制变换后的向量
ax.quiver(*origin, b_transformed[0], b_transformed[1], angles='xy', scale_units='xy', scale=1, color='purple', label='Transformed Vector (-1,3)')

# 设置图形属性
ax.set_xlim(-3, 3)
ax.set_ylim(0, 3)  # 只显示x轴的上半部分
ax.set_aspect('equal')
plt.grid()

# 调整图例位置
plt.legend(loc='upper left', bbox_to_anchor=(0.6, 1), fontsize='small')
plt.title('Vector Transformation and Basis Visualization')
plt.xlabel('X')
plt.ylabel('Y')

plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

在这里插入图片描述

红色和绿色的向量构成了一个新的坐标基底,从这个基底的视角来看,棕色的向量还是(1, 1),也就是该参考系下的向量和原始空间中的向量都是同一个。只不过这个新基坐标系下的向量(1, 1)用原始空间坐标系的表示是(-1, 3)。

所以基变换角度来看矩阵乘向量 A ⋅ b A \cdot b A⋅b,可以理解成以矩阵A为新的参考系,该参考系下中的向量b,在原始空间笛卡尔坐标系中的真实位置。

由此理解矩阵乘法的计算规则,为什么就是像下面这样,前面一个矩阵的第 i 行 x 后一个矩阵的第 j 列,结果为新的矩阵的第 ij 个元素:
[ 1 − 2 1 2 ] [ 1 1 ] = [ − 1 × 1 + ( − 2 ) × 1 1 × 1 + 2 × 1 ] = [ − 1 3 ] [1−212]

[11−22]
[11]
[11]
= [−1×1+(−2)×11×1+2×1]
[−1×1+(−2)×11×1+2×1]
= [−13]
[−13]
[11​−22​][11​]=[−1×1+(−2)×11×1+2×1​]=[−13​]
因为左边矩阵不同的列向量代表新基坐标系中不同维度下的基底,后面矩阵列向量中的不同坐标分别表示新的基坐标系中不同维度的坐标,而新的基坐标系中,不同维度的基坐标轴的坐标表示,又可以看成是相对于原笛卡尔坐标系的投影,比如新的x轴(1, 1),表示这个轴在笛卡尔坐标系中的x, y轴上的投影分别都是1,新的x轴中的一个单位长度,等价于原笛卡尔坐标系中x, y轴各自一个单位长度。

因此矩阵乘法之所以规定行乘列的值作为计算的结果,本质上是把新基坐标系下,一个向量所有维度的坐标,在原笛卡尔坐标系下按照不同维度(前面矩阵的行)进行了一个汇总求和。

所以也能理解为什么规定矩阵乘法,要求必须前面一个矩阵的列数等于后一个矩阵的行数,因为前面矩阵的列数其实就是新的基坐标系的维度,后面矩阵的行数,其实就是一个向量在这个新基坐标系中各维度下的坐标表示,二者维度不同,也就没有汇总的必要和意义。

推广到高维的不规则的矩阵,比如一个3x2的矩阵乘上一个2x1的向量,新的基坐标系还是只有两个维度,只不过每个维度会投影到一个三维的笛卡尔坐标系(因为矩阵的列向量是用3个数表示,说明在笛卡尔坐标系中有3个维度的投影)。后面这个2x1的向量可以看成是新的基坐标系下的向量表示,最终的计算还是将这个向量分别在笛卡尔坐标系的三个维度上汇总求和。

以下面这个为例:

[ 0 1 1 0 1 1 ] [ 1 1 ] = [ 1 1 2 ] [011011]

[11]
= [112]
​011​101​ ​[11​]= ​112​ ​

在这里插入图片描述
至于推广到更多行或列的矩阵乘法,无非增加行数是增加了新的基坐标在标准笛卡尔坐标系下的分解维度,增加列数是增加了新坐标系的基底数量,原理都还是一样的。

至于矩阵乘矩阵,可以把后一个矩阵看成是多个列向量的集合,用矩阵乘向量的视角去理解。

向量的线性组合视角

矩阵乘向量,也可以看作是矩阵列向量的线性组合,还是拿最上面的这个计算来说:
[ 1 − 2 1 2 ] [ 1 1 ] = [ − 1 3 ] [1−212]

[11]
= [−13]
[11​−22​][11​]=[−13​]
可以看做是:
1 [ 1 1 ] + 1 [ − 2 2 ] = [ − 1 3 ] 1 [11]
+ 1 [−22]
= [−13]
1[11​]+1[−22​]=[−13​]

怎么理解上面公式?原矩阵是一个线性映射,这个线性映射告诉了我们原来的基向量(1, 0)和(0, 1)分别被映射到了(1, 1)和(-2, 2),原空间中的(x, y)是对(1, 0)和(0, 1)的线性组合,映射空间中的(x, y)也就是对(1, 1)和(-2, 2)的线性组合。

其实个人觉得,这种视角能更好帮助理解基变换视角,矩阵列向量是新基的单位向量,后面向量是新基中的坐标。

ps.关于线性的理解

可以把线性变换理解为“等距变换”,自变量变化相等时,函数值变化也是相等的,不受具体的变量值影响。或者把线性变换看做是一台机器,左边放入水果,右边输出果汁。一堆水果一起放入得到的果汁和分开放入然后将输出汇总后得到的果汁都是一样的(水果的数量、类型都可能不同,对应变换中变量系数和变量个数)。

在几何的直观理解上,一个因变量是一条直线,两个因变量是一个面,三个及以上…,超平面。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# 定义系数
k1 = 2  # 例如,k1 = 2
k2 = 3  # 例如,k2 = 3
b = 5  # 例如,b = 5

# 创建 x1 和 x2 数据
x1 = np.linspace(-10, 10, 100)
x2 = np.linspace(-10, 10, 100)

# 创建网格
x1_grid, x2_grid = np.meshgrid(x1, x2)

# 计算 y 值
y = k1 * x1_grid + k2 * x2_grid + b

# 创建 3D 图形
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 绘制表面
ax.plot_surface(x1_grid, x2_grid, y, cmap='viridis', edgecolor='none')

# 设置图形标签
ax.set_xlabel('x1')
ax.set_ylabel('x2')
ax.set_zlabel('y')

# 显示图形
plt.title(f'Graph of y = {k1}*x1 + {k2}*x2 + {b}')
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

在这里插入图片描述

注:本文转载自blog.csdn.net的atwdy的文章"https://blog.csdn.net/atwdy/article/details/144535462"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

137
数学
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top