跳转至

线性代数基础

线性代数是机器人学的数学基石。本章将系统地讲解机器人学所需的线性代数知识。

学习目标

完成本章后,你将能够:

  • 理解向量和矩阵的基本运算
  • 掌握特征值和特征向量的概念
  • 理解矩阵分解方法
  • 应用线性代数解决机器人学问题

1. 向量基础

1.1 向量的定义

向量是既有大小又有方向的量,在机器人学中用于表示:

  • 位置:机器人在空间中的位置
  • 速度:机器人的运动速度
  • :作用在机器人上的力
  • 方向:机器人的朝向
向量表示:
v = [v₁, v₂, v₃]ᵀ

示例:
位置向量 p = [1, 2, 3]ᵀ 表示空间中的点 (1, 2, 3)

1.2 向量运算

import numpy as np

# 创建向量
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])

# 向量加法
v_sum = v1 + v2  # [5, 7, 9]

# 向量减法
v_diff = v1 - v2  # [-3, -3, -3]

# 标量乘法
v_scaled = 2 * v1  # [2, 4, 6]

# 向量长度(范数)
v_norm = np.linalg.norm(v1)  # √14 ≈ 3.74

# 单位向量
v_unit = v1 / np.linalg.norm(v1)  # [0.267, 0.535, 0.802]

1.3 点积(内积)

点积是向量运算中最重要的运算之一:

定义:
v₁ · v₂ = v₁ᵀ v₂ = Σ v₁ᵢ v₂ᵢ

几何意义:
v₁ · v₂ = ||v₁|| ||v₂|| cos(θ)

其中 θ 是两个向量之间的夹角
# 点积计算
dot_product = np.dot(v1, v2)  # 32

# 计算夹角
cos_theta = dot_product / (np.linalg.norm(v1) * np.linalg.norm(v2))
theta = np.arccos(cos_theta)  # 弧度

# 应用:计算投影
# 向量 v1 在 v2 方向上的投影长度
projection_length = dot_product / np.linalg.norm(v2)

1.4 叉积(外积)

叉积用于计算垂直于两个向量的向量:

定义:
v₁ × v₂ = [v₁₂v₂₃ - v₁₃v₂₂, v₁₃v₂₁ - v₁₁v₂₃, v₁₁v₂₂ - v₁₂v₂₁]

性质:
- 结果向量垂直于 v₁ 和 v₂
- 方向由右手定则确定
- ||v₁ × v₂|| = ||v₁|| ||v₂|| sin(θ)
# 叉积计算
cross_product = np.cross(v1, v2)  # [-3, 6, -3]

# 验证垂直性
print(np.dot(v1, cross_product))  # 0
print(np.dot(v2, cross_product))  # 0

# 应用:计算面积
# 平行四边形面积
area = np.linalg.norm(cross_product)

# 三角形面积
triangle_area = area / 2

2. 矩阵基础

2.1 矩阵的定义

矩阵是二维数组,在机器人学中用于表示:

  • 变换:旋转、缩放、剪切
  • 系统:线性方程组
  • 状态:系统状态转移
矩阵表示:
A = [a₁₁ a₁₂ a₁₃]
    [a₂₁ a₂₂ a₂₃]
    [a₃₁ a₃₂ a₃₃]

示例:
旋转矩阵 R = [cos(θ) -sin(θ) 0]
             [sin(θ)  cos(θ) 0]
             [0       0      1]

2.2 矩阵运算

import numpy as np

# 创建矩阵
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

# 矩阵加法
C = A + B  # [[6, 8], [10, 12]]

# 矩阵减法
D = A - B  # [[-4, -4], [-4, -4]]

# 标量乘法
E = 2 * A  # [[2, 4], [6, 8]]

# 矩阵乘法
F = np.matmul(A, B)  # [[19, 22], [43, 50]]

# 逐元素乘法(Hadamard积)
G = A * B  # [[5, 12], [21, 32]]

# 转置
A_T = A.T  # [[1, 3], [2, 4]]

2.3 矩阵类型

# 单位矩阵
I = np.eye(3)  # 3x3 单位矩阵

# 零矩阵
Z = np.zeros((3, 3))

# 对角矩阵
D = np.diag([1, 2, 3])

# 对称矩阵
S = np.array([[1, 2], [2, 4]])  # S = Sᵀ

# 正交矩阵
# Q^T Q = I
Q = np.array([[0, -1], [1, 0]])  # 90度旋转矩阵

# 验证正交性
print(np.allclose(np.matmul(Q.T, Q), np.eye(2)))  # True

2.4 矩阵的逆

# 矩阵求逆
A = np.array([[1, 2], [3, 4]])
A_inv = np.linalg.inv(A)

# 验证:A * A_inv = I
print(np.allclose(np.matmul(A, A_inv), np.eye(2)))  # True

# 伪逆(用于非方阵或奇异矩阵)
A_pinv = np.linalg.pinv(A)

# 应用:求解线性方程组 Ax = b
b = np.array([5, 6])
x = np.linalg.solve(A, b)  # 更高效的方法
# 或者
x = np.matmul(A_inv, b)

3. 特征值与特征向量

3.1 定义

特征值和特征向量是矩阵最重要的性质之一:

定义:
Ax = λx

其中:
- A 是 n×n 矩阵
- x 是非零向量(特征向量)
- λ 是标量(特征值)

几何意义:
矩阵 A 作用在特征向量 x 上,只是缩放,不改变方向

动画演示 — 观察特征值的几何含义:圆如何被矩阵变换为椭圆,特征向量方向保持不变:

Eigenvalues Animation

3.2 计算方法

import numpy as np

# 创建矩阵
A = np.array([[2, 1], [1, 2]])

# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)

print("特征值:", eigenvalues)  # [3, 1]
print("特征向量:", eigenvectors)

# 验证:Ax = λx
for i in range(len(eigenvalues)):
    lhs = np.matmul(A, eigenvectors[:, i])
    rhs = eigenvalues[i] * eigenvectors[:, i]
    print(f"验证 λ={eigenvalues[i]}:", np.allclose(lhs, rhs))

3.3 特征值分解

# 特征值分解:A = PDP⁻¹
# 其中 P 是特征向量矩阵,D 是特征值对角矩阵

P = eigenvectors
D = np.diag(eigenvalues)
P_inv = np.linalg.inv(P)

# 验证分解
A_reconstructed = np.matmul(np.matmul(P, D), P_inv)
print("重构矩阵:", np.allclose(A, A_reconstructed))  # True

# 应用:矩阵的幂
# A^n = PD^nP⁻¹
n = 5
D_n = np.diag(eigenvalues ** n)
A_n = np.matmul(np.matmul(P, D_n), P_inv)

3.4 奇异值分解 (SVD)

# 奇异值分解:A = UΣVᵀ
A = np.array([[1, 2], [3, 4], [5, 6]])

U, S, Vt = np.linalg.svd(A)

print("U:", U.shape)      # (3, 3)
print("S:", S.shape)      # (2,) - 奇异值
print("Vt:", Vt.shape)    # (2, 2)

# 重构矩阵
Sigma = np.zeros_like(A, dtype=float)
Sigma[:min(A.shape), :min(A.shape)] = np.diag(S)
A_reconstructed = np.matmul(np.matmul(U, Sigma), Vt)

# 应用:低秩近似
# 保留最大的 k 个奇异值
k = 1
U_k = U[:, :k]
S_k = S[:k]
Vt_k = Vt[:k, :]

A_approx = np.matmul(np.matmul(U_k, np.diag(S_k)), Vt_k)

4. 线性方程组

4.1 求解方法

import numpy as np

# 方法 1:直接求解
A = np.array([[2, 1], [5, 7]])
b = np.array([11, 13])

x = np.linalg.solve(A, b)
print("解:", x)  # [7.111, -3.222]

# 方法 2:矩阵求逆
A_inv = np.linalg.inv(A)
x = np.matmul(A_inv, b)

# 方法 3:最小二乘解(超定系统)
# Ax ≈ b
A = np.array([[1, 1], [1, 2], [1, 3]])
b = np.array([1, 2, 2])

x, residuals, rank, s = np.linalg.lstsq(A, b, rcond=None)
print("最小二乘解:", x)  # [0.667, 0.5]

4.2 齐次方程组

# 齐次方程组 Ax = 0
# 解空间是 A 的零空间

A = np.array([[1, 2, 3], [4, 5, 6]])

# 计算零空间
from scipy.linalg import null_space
ns = null_space(A)
print("零空间:", ns)

# 验证:A @ ns ≈ 0
print("验证:", np.allclose(np.matmul(A, ns), 0))

5. 向量空间

5.1 基与维数

import numpy as np

# 向量空间的基
v1 = np.array([1, 0, 0])
v2 = np.array([0, 1, 0])
v3 = np.array([0, 0, 1])

# 标准正交基
# v1, v2, v3 是 R³ 的标准正交基

# 任意基
u1 = np.array([1, 1, 0])
u2 = np.array([0, 1, 1])
u3 = np.array([1, 0, 1])

# 验证线性独立性
matrix = np.column_stack([u1, u2, u3])
det = np.linalg.det(matrix)
print("行列式:", det)  # 非零表示线性独立

5.2 子空间

# 子空间示例:R³ 中的平面
# 平面方程:ax + by + cz = 0

# 生成子空间
v1 = np.array([1, 0, -1])
v2 = np.array([0, 1, -1])

# 子空间中的任意向量
# v = α*v1 + β*v2
alpha, beta = 2, 3
v = alpha * v1 + beta * v2  # [2, 3, -5]

# 验证在平面上:x + y + z = 0
print("验证:", v[0] + v[1] + v[2])  # 0

6. 应用示例

6.1 机器人运动学中的线性代数

import numpy as np

# 旋转矩阵
def rotation_matrix_z(theta):
    """绕 Z 轴旋转"""
    return np.array([
        [np.cos(theta), -np.sin(theta), 0],
        [np.sin(theta),  np.cos(theta), 0],
        [0,              0,             1]
    ])

# 齐次变换矩阵
def homogeneous_transform(R, p):
    """创建齐次变换矩阵"""
    T = np.eye(4)
    T[:3, :3] = R
    T[:3, 3] = p
    return T

# 示例:2 连杆机器人
theta1 = np.pi/4  # 45度
theta2 = np.pi/6  # 30度
l1 = 1.0
l2 = 0.8

# 正运动学
x = l1 * np.cos(theta1) + l2 * np.cos(theta1 + theta2)
y = l1 * np.sin(theta1) + l2 * np.sin(theta1 + theta2)

print(f"末端位置: ({x:.3f}, {y:.3f})")

# 雅可比矩阵
J = np.array([
    [-l1*np.sin(theta1) - l2*np.sin(theta1+theta2), 
     -l2*np.sin(theta1+theta2)],
    [l1*np.cos(theta1) + l2*np.cos(theta1+theta2),  
     l2*np.cos(theta1+theta2)]
])

print("雅可比矩阵:")
print(J)

6.2 线性回归

import numpy as np
import matplotlib.pyplot as plt

# 生成数据
np.random.seed(42)
X = np.random.randn(100, 1)
y = 2 * X + 1 + np.random.randn(100, 1) * 0.5

# 添加偏置项
X_b = np.c_[np.ones((100, 1)), X]

# 最小二乘解:θ = (XᵀX)⁻¹Xᵀy
theta = np.linalg.inv(X_b.T @ X_b) @ X_b.T @ y

print("斜率:", theta[1][0])  # ≈ 2
print("截距:", theta[0][0])  # ≈ 1

# 预测
X_new = np.array([[0], [2]])
X_new_b = np.c_[np.ones((2, 1)), X_new]
y_predict = X_new_b @ theta

7. 练习题

基础练习

  1. 计算向量 v1 = [1, 2, 3]v2 = [4, 5, 6] 的点积和叉积
  2. 验证矩阵 R = [[0, -1], [1, 0]] 是正交矩阵
  3. 计算矩阵 A = [[2, 1], [1, 2]] 的特征值和特征向量

进阶练习

  1. 实现 2 连杆机器人的正运动学
  2. 计算雅可比矩阵并分析奇异性
  3. 使用 SVD 进行图像压缩

应用练习

  1. 实现简单的线性回归
  2. 使用最小二乘法拟合数据
  3. 实现主成分分析 (PCA)

下一步

参考资源


← 返回索引 | 下一页:微积分 →