Skip to content

第 2 章 向量:带方向的量

学习目标

  • 区分标量与向量,理解「向量 = 大小 + 方向」
  • 掌握向量的两种表示:几何表示(有向线段)与代数表示(坐标数组)
  • 理解向量相等与位置向量
  • 理解零向量与负向量
  • 会用 NumPy 表示向量,用 matplotlib 画向量

2.1 为什么需要向量

第 1 章我们学过的数,都是标量:只描述大小,不描述方向。身高 160 厘米、体重 50 千克、温度 25 摄氏度,这些量一个数就够了。

但有些量只说大小不够。老师说「放学后向东走 3 千米」,你必须知道向东这个方向,才能走到家;只说「走 3 千米」,东西南北都可以,等于没说。风是「北风 4 级」,力是「向右拉 10 牛」——这些量都有两个属性:

  1. 大小:3 千米、4 级、10 牛;
  2. 方向:东、北、向右。

既有大小又有方向的量,叫向量。只讲大小不讲方向的量,叫标量

定义先行:向量是既有大小又有方向的量;标量是只有大小没有方向的量。

本书讨论二维平面与三维空间中的向量,但向量的思想(拆成分量、按分量运算)可以推广到任意维度——这正是后面矩阵和线性代数要干的事。

2.2 向量的几何表示:有向线段

在纸上,向量画成一条带箭头的线段:起点叫始点,终点叫终点,箭头指向终点,箭头的方向就是向量的方向,线段的长度就是向量的大小(也叫)。

向量的几何表示

从点 到点 的向量,记作 。注意箭头的方向很重要: 大小相同、方向相反,是两个不同的向量。

向量的名字除了用两个端点,还可以用一个字母加箭头,比如 ;本书中向量统一用加粗的小写字母 表示,和普通数字 区分开。

2.3 向量相等:只看大小和方向

两个向量什么时候相等?大小相等,且方向相同——与起点在哪里无关。

相等向量

图中的三个箭头,起点分别是 ,但都是「向右 3 格、向上 2 格」,所以它们是同一个向量。就像「向东 3 千米」,不管从哪个城市出发,这个描述本身都一样。

位置向量是特例:起点固定在原点 的向量。任何一个向量 ,都可以平移,让起点落在原点,得到一个位置向量——这个位置向量的终点坐标 就是该向量唯一的坐标表示

2.4 向量的坐标表示:从有向线段到数组

把向量放到坐标平面上:起点是 ,终点是 。那么从 的位移是:

即「横坐标的差、纵坐标的差」。例如 :

这个 的意思是:从 出发,向右走 3 格,再向上走 2 格,就到了 。它只与「怎么走」有关,与起点无关——这正好和 2.3 的结论一致:向量是「位移」,不是「位置」。

位置向量的坐标表示最简单:起点是 ,终点是 ,所以位置向量就是 本身。

在 NumPy 里,向量就是一个长度为 2 的数组:

python
import numpy as np

# 位置向量 (3, 2):向右 3,向上 2
v = np.array([3.0, 2.0])
print("v =", v)
print("维度 ndim =", v.ndim)       # 1 维
print("长度 shape =", v.shape)     # (2,),两个分量
print("分量 v[0] =", v[0], ", v[1] =", v[1])

运行输出:

text
v = [3. 2.]
维度 ndim = 1
长度 shape = (2,)
分量 v[0] = 3.0 , v[1] = 2.0

两个数 叫向量的分量(component)。分量就是坐标,只不过用数组装起来以后,以后可以放 3 个、4 个、100 个分量——二维、三维乃至更高维的向量,用同一套代码处理。

PyTorch 里用法几乎一样,后续章节会大量使用:

python
import torch

v = torch.tensor([3.0, 2.0])
print("torch v =", v)
print("类型 dtype =", v.dtype)

运行输出:

text
torch v = tensor([3., 2.])
类型 dtype = torch.float32

2.5 零向量与负向量

零向量是大小为零、方向不确定的向量(习惯上认为它没有方向),记作 :

零向量对应的位移是「原地不动」。

负向量: 的负向量是

大小与 相同,方向正好相反——「向东 3 千米」的相反方向就是「向西 3 千米」。

python
import numpy as np

v = np.array([3.0, 2.0])
print("v  =", v)
print("-v =", -v)
print("零向量:", np.zeros(2))

运行输出:

text
v  = [3. 2.]
-v = [-3. -2.]
零向量: [0. 0.]

2.6 用 matplotlib 画向量

matplotlib 的 quiver 可以画带箭头的线段。把同一个向量 从原点、 三个不同的起点画出来,你会看到三根平行且等长的箭头——它们是同一个向量:

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import numpy as np

v = np.array([3.0, 2.0])
starts = [np.array([0.0, 0.0]), np.array([1.0, 1.0]), np.array([-2.0, 0.0])]
labels = ["起点 O", "起点 A", "起点 C"]
colors = ["tab:red", "tab:blue", "tab:green"]

fig, ax = plt.subplots(figsize=(6, 6))
ax.axhline(0, color="black", linewidth=1)
ax.axvline(0, color="black", linewidth=1)
ax.grid(True, linestyle=":", alpha=0.5)
ax.set_xlim(-3.5, 5)
ax.set_ylim(-1.5, 5)
ax.set_aspect("equal")

for s, label, c in zip(starts, labels, colors):
    ax.quiver(s[0], s[1], v[0], v[1], angles="xy", scale_units="xy", scale=1,
              color=c, width=0.012)
    ax.annotate(label, s, textcoords="offset points", xytext=(-24, -14), color=c)

ax.annotate("v = (3, 2)", (1.8, 3.2), color="tab:red", fontsize=13)
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_title("同一个向量,不同的起点")
fig.savefig("book/public/figs/fig02-equal_vectors.png", dpi=120, bbox_inches="tight")
plt.close(fig)

第一张图(2.2 的插图)画的是向量 的分量分解:

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import numpy as np

v = np.array([3.0, 2.0])

fig, ax = plt.subplots(figsize=(6, 6))
ax.axhline(0, color="black", linewidth=1)
ax.axvline(0, color="black", linewidth=1)
ax.grid(True, linestyle=":", alpha=0.5)
ax.set_xlim(-0.5, 4)
ax.set_ylim(-0.5, 3.5)
ax.set_aspect("equal")

# 向量本体
ax.quiver(0, 0, v[0], v[1], angles="xy", scale_units="xy", scale=1,
          color="tab:red", width=0.02)
# 分量虚线:x 方向 3、y 方向 2
ax.plot([0, v[0]], [0, 0], color="tab:blue", linestyle="--")
ax.plot([v[0], v[0]], [0, v[1]], color="tab:green", linestyle="--")
ax.text(1.5, -0.3, "3", color="tab:blue", fontsize=13, ha="center")
ax.text(v[0] + 0.1, 0.9, "2", color="tab:green", fontsize=13)
ax.annotate("v = (3, 2)", (1.5, 1.4), color="tab:red", fontsize=14)

ax.scatter([0], [0], color="black", zorder=3)
ax.annotate("O", (0, 0), textcoords="offset points", xytext=(-14, -10))
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_title("向量 v = (3, 2):大小 1 格,方向向右上")
fig.savefig("book/public/figs/fig02-vector.png", dpi=120, bbox_inches="tight")
plt.close(fig)

动手实践

  1. 说出下列量哪些是向量,哪些是标量:「体重 60 千克」「北风 5 级」「电梯下降 3 层」「从家到学校直线距离 2 千米」「向东偏南 30° 走 500 米」。
  2. 已知 ,写出向量 的坐标,再写 ,并解释两者有什么关系。
  3. 用 NumPy 表示 ,打印分量;再用 torch.tensor 表示同样的向量。
  4. 修改 2.6 的代码,画一个从 指向 的向量,并标注它的坐标。

常见错误

错误写法/理解原因
认为 相等方向相反,不相等;它们互为负向量
把「位置」和「向量」混为一谈位置是「点在哪」,向量是「怎么走」;同一个向量可以从不同起点出发
认为向量 必须从原点出发坐标表示是「位移量」,与起点无关;位置向量才固定从原点出发
把向量长度当成分量个数v.shape(2,),表示有 2 个分量;向量的「长度/大小」是模,第 4 章才学

章末练习

基础

  1. 写出从 的向量坐标;从 的向量坐标;比较两个向量,说明它们是否相等。
  2. 向量 的负向量是什么?画出
  3. 用 NumPy 创建向量 ,打印它的分量与 shape。

提高

  1. 一个向量从 出发,终点是 ;另一个向量从 出发,终点是 。它们相等吗?为什么?用代码验证两个「终点减起点」的结果。
  2. ,且 ,求终点 的坐标。提示:终点坐标 = 起点坐标 + 向量坐标。

挑战

  1. 已知 ,写出它的模(大小)的表达式。提示:用 1.4 的距离公式,把起点放在原点。运行 np.linalg.norm(v) 验证你的表达式。
  2. 在三维空间里,向量用三个分量 表示。猜测并验证:从 的向量坐标是什么?np.array 里三个分量表示它。

章末自测

  1. 下列哪个量是向量?
    • A. 身高 160 厘米
    • B. 向东 3 千米
    • C. 体重 50 千克
    • D. 温度 25 摄氏度
  2. 的向量 是?
    • A.
    • B.
    • C.
    • D.
  3. 向量 与下列哪个相等?
    • A. 从 的向量
    • B. 从 的向量
    • C. 从 的向量
    • D. 从 的向量
  4. 的关系是?
    • A. 相等
    • B. 互为负向量
    • C. 没有关系
    • D. 一个在 x 轴一个在 y 轴
  5. 零向量是?
    • A. 没有方向的任何向量
    • B. 大小为 0 的向量
    • C. 长度为 0 的数组
    • D. 以上都对
  6. 向量 的负向量是?
    • A.
    • B.
    • C.
    • D.
  7. NumPy 中 np.array([3.0, 2.0]).shape 的结果是?
    • A. 2
    • B. (2,)
    • C. [2]
    • D. (1, 2)
  8. 「位置向量」的特点是?
    • A. 终点在原点
    • B. 起点在原点
    • C. 大小等于 1
    • D. 方向朝上
  9. 向量的「坐标表示」 的含义是?
    • A. 从原点出发向右 2、向上 3
    • B. 横方向移动 3、纵方向移动 2
    • C. 长度是 3+2=5
    • D. 终点一定是
  10. torch.tensor([3.0, 2.0]) 的 dtype 通常是?
    • A. torch.float32
    • B. torch.int64
    • C. torch.float64
    • D. torch.bool