矩阵运算

矩阵创建方法

直接定义

# 标量
a = 5

# 行向量
v = [1 2 3 4 5]

# 列向量
u = [1; 2; 3; 4; 5]

# 矩阵
A = [1 2 3; 4 5 6; 7 8 9]

# 多行定义(等价)
B = [1 2 3
     4 5 6
     7 8 9]

特殊矩阵

# 零矩阵
Z = zeros(3, 4)        # 3×4 零矩阵

# 全1矩阵
O = ones(2, 3)         # 2×3 全1矩阵

# 单位矩阵
I = eye(4)             # 4×4 单位矩阵

# 对角矩阵
D = diag([1 2 3 4])    # 对角线为 [1 2 3 4] 的矩阵

# 随机矩阵
R = rand(3, 3)         # [0,1) 均匀分布
N = randn(3, 3)        # 标准正态分布
K = randi(10, 3, 3)    # [1,10] 整数

使用范围生成

# 等差序列
x = 1:10               # [1 2 3 4 5 6 7 8 9 10]
y = 0:0.5:2            # [0 0.5 1.0 1.5 2.0]
z = 10:-1:1            # [10 9 8 7 6 5 4 3 2 1]

# 线性空间(等分)
t = linspace(0, 1, 5)  # [0 0.25 0.5 0.75 1.0]

矩阵索引和切片

基本索引

A = [1 2 3; 4 5 6; 7 8 9]

# 单个元素(索引从1开始)
x = A(2, 3)            # 6(第2行第3列)

# 整行
row = A(2, :)          # [4 5 6]

# 整列
col = A(:, 2)          # [2; 5; 8]

# 多个元素
sub = A(1:2, 2:3)      # [2 3; 5 6]

向量索引

v = [10 20 30 40 50]

# 单个元素
x = v(3)               # 30

# 范围索引
sub = v(2:4)           # [20 30 40]

# 指定索引
selected = v([1 3 5])  # [10 30 50]

赋值

A = zeros(3, 3)

# 修改单个元素
A(1, 1) = 1

# 修改整行
A(2, :) = [4 5 6]

# 修改整列
A(:, 3) = [7; 8; 9]

# 修改子矩阵
A(1:2, 1:2) = [1 2; 3 4]

矩阵运算

加法和减法

矩阵必须尺寸相同:

A = [1 2; 3 4]
B = [5 6; 7 8]

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

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

# 标量加法(广播)
E = A + 10             # [11 12; 13 14]

矩阵乘法

标准的矩阵乘法,要求 A 的列数等于 B 的行数:

A = [1 2; 3 4]         # 2×2
B = [5 6; 7 8]         # 2×2

# 矩阵乘法
C = A * B              # [19 22; 43 50]

# 矩阵与向量
v = [1; 2]
w = A * v              # [5; 11]

# 矩阵幂
A2 = A * A             # A²
A3 = A ^ 2             # 等价写法

矩阵除法

A = [1 2; 3 4]
B = [5 6; 7 8]

# 右除 A/B = A * inv(B)
C = A / B

# 左除(解线性方程)A\b 求解 Ax = b
# 见"方程求解"章节

转置

A = [1 2 3; 4 5 6]     # 2×3

# 转置
AT = A'                # 3×2: [1 4; 2 5; 3 6]

# 向量转置
v = [1 2 3]            # 行向量
u = v'                 # 列向量 [1; 2; 3]

元素级运算

在运算符前加点 . 表示元素级运算:

元素级乘法

A = [1 2 3; 4 5 6]
B = [2 2 2; 3 3 3]

# 对应元素相乘
C = A .* B             # [2 4 6; 12 15 18]

# 与标量
D = A .* 2             # [2 4 6; 8 10 12]

元素级除法

A = [10 20 30]
B = [2 4 5]

C = A ./ B             # [5 5 6]

# 倒数
D = 1 ./ A             # [0.1 0.05 0.0333...]

元素级幂运算

A = [1 2 3; 4 5 6]

# 每个元素平方
B = A .^ 2             # [1 4 9; 16 25 36]

# 不同的幂
C = A .^ [1 2 3; 1 2 3] # [1 4 27; 4 25 216]

# 开方
D = A .^ 0.5           # sqrt(A)

比较运算

A = [1 2 3; 4 5 6]
B = [2 2 2; 5 5 5]

# 元素级比较(返回逻辑矩阵)
C = A > 2              # [0 0 1; 1 1 1]
D = A == B             # [0 1 0; 0 1 0]
E = A >= B             # [0 1 1; 0 1 1]

逻辑索引

逻辑索引允许用一个与矩阵等大的 0/1 掩码矩阵来选取或修改元素,而不必手动写循环。

读取:用逻辑掩码提取元素

A = [1 2 3 4 5]

# 用比较运算创建逻辑掩码
mask = A > 2            # [0 0 1 1 1]

# 用掩码索引,返回满足条件的元素(列向量)
result = A(mask)        # [3; 4; 5]

# 等价的一行写法
positive = A(A > 0)     # 取所有正数

修改:用逻辑掩码批量赋值

A = [1 -2 3 -4 5]

# 将所有负数置为 0
A(A < 0) = 0            # A = [1 0 3 0 5]

# 将大于 3 的元素置为 3(截断)
B = [1 2 3 4 5]
B(B > 3) = 3            # B = [1 2 3 3 3]

二维矩阵逻辑索引

A = [1 2 3; 4 5 6; 7 8 9]

# 提取所有大于 5 的元素(结果为列向量,按行优先顺序)
large = A(A > 5)        # [6; 7; 8; 9]

# 将矩阵中的 NaN 替换为 0
data = [1 nan 3; nan 5 6]
data(isnan(data)) = 0   # [1 0 3; 0 5 6]

逻辑掩码判定:与目标矩阵元素个数相同,且全为 0 或 1。数值索引(如 A([1 3]))不受影响。

矩阵拼接

水平拼接

A = [1 2; 3 4]
B = [5 6; 7 8]

# 水平拼接(行数必须相同)
C = [A B]              # [1 2 5 6; 3 4 7 8]
C = [A, B]             # 等价写法

# 添加列
v = [9; 10]
D = [A v]              # [1 2 9; 3 4 10]

垂直拼接

A = [1 2 3]
B = [4 5 6]

# 垂直拼接(列数必须相同)
C = [A; B]             # [1 2 3; 4 5 6]

# 添加行
v = [7 8 9]
D = [A; B; v]          # 3×3 矩阵

混合拼接

# 创建块矩阵
A = [1 2]
B = [3 4]
C = [5 6]
D = [7 8]

M = [A B; C D]         # [1 2 3 4; 5 6 7 8]

矩阵变换

reshape - 改变形状

# 将向量变为矩阵
v = 1:12
A = reshape(v, 3, 4)   # 3×4 矩阵(按列填充)

# 改变矩阵形状(元素总数必须相同)
B = [1 2 3; 4 5 6]     # 2×3
C = reshape(B, 3, 2)   # 3×2

transpose - 转置

A = [1 2 3; 4 5 6]
B = transpose(A)       # 等价于 A'
C = A'                 # 简写

flipud - 上下翻转

A = [1 2 3; 4 5 6; 7 8 9]
B = flipud(A)          # [7 8 9; 4 5 6; 1 2 3]

fliplr - 左右翻转

A = [1 2 3; 4 5 6; 7 8 9]
B = fliplr(A)          # [3 2 1; 6 5 4; 9 8 7]

rot90 - 旋转90度

A = [1 2 3; 4 5 6; 7 8 9]
B = rot90(A)           # 逆时针旋转90度
C = rot90(A, 2)        # 旋转180度
D = rot90(A, -1)       # 顺时针旋转90度

线性代数运算

行列式

A = [1 2; 3 4]
d = det(A)             # -2

# 奇异矩阵
B = [1 2; 2 4]
d = det(B)             # 0(行列式为0)

矩阵的逆

A = [1 2; 3 4]
Ainv = inv(A)          # [-2 1; 1.5 -0.5]

# 验证
I = A * Ainv           # [1 0; 0 1](单位矩阵)

A = [1 2 3; 4 5 6; 7 8 9]
r = rank(A)            # 2(秩为2)

I = eye(3)
r = rank(I)            # 3(满秩)

迹(对角线元素之和)

A = [1 2 3; 4 5 6; 7 8 9]
t = trace(A)           # 15 (1+5+9)

范数

v = [3 4]

# 向量的2-范数(欧几里得范数)
n2 = norm(v)           # 5

# 向量的1-范数
n1 = norm(v, 1)        # 7

# 向量的无穷范数
ninf = norm(v, inf)    # 4

# 矩阵范数
A = [1 2; 3 4]
nA = norm(A)           # 矩阵的2-范数

特征值和特征向量

A = [4 1; 2 3]

# 特征值
lambda = eig(A)        # 返回特征值向量

# 特征值和特征向量
[V, D] = eig(A)        # V: 特征向量矩阵, D: 特征值对角矩阵

统计运算

求和

v = [1 2 3 4 5]
s = sum(v)             # 15(向量所有元素之和)

A = [1 2 3; 4 5 6]
s1 = sum(A)            # [5 7 9](每列的和)
s2 = sum(A, 2)         # [6; 15](每行的和)
total = sum(sum(A))    # 21(所有元素之和)

平均值

v = [1 2 3 4 5]
m = mean(v)            # 3

A = [1 2 3; 4 5 6]
m1 = mean(A)           # [2.5 3.5 4.5](每列平均)
m2 = mean(A, 2)        # [2; 5](每行平均)

最大值和最小值

v = [3 7 2 9 1 5]

maxv = max(v)          # 9
minv = min(v)          # 1

# 矩阵
A = [1 5 3; 9 2 7]
maxc = max(A)          # [9 5 7](每列最大值)
minr = min(A, [], 2)   # [1; 2](每行最小值)

实用示例

示例1:计算向量夹角

# 计算两个向量的夹角
u = [1, 0]
v = [1, 1]

# 使用点积公式:cos(θ) = (u·v) / (|u||v|)
dot_product = sum(u .* v)
norm_u = norm(u)
norm_v = norm(v)

cos_theta = dot_product / (norm_u * norm_v)
theta = acos(cos_theta)

disp("夹角(弧度):" + num2str(theta))
disp("夹角(度):" + num2str(theta * 180 / pi))

示例2:矩阵的条件数

# 条件数衡量矩阵的数值稳定性
A = [1 2; 2 4.0001]

# 条件数 = |A| * |A^-1|
cond_A = norm(A) * norm(inv(A))
disp("条件数:" + num2str(cond_A))

# 条件数大表示矩阵接近奇异,数值不稳定

示例3:投影矩阵

# 计算向量 v 在向量 u 上的投影
u = [3; 4]
v = [2; 1]

# 投影公式:proj_u(v) = (v·u / u·u) * u
dot_vu = sum(v .* u)
dot_uu = sum(u .* u)

proj = (dot_vu / dot_uu) * u
disp("投影向量:")
disp(proj)

示例4:格拉姆-施密特正交化

# 将两个线性无关的向量正交化
v1 = [1; 1; 0]
v2 = [1; 0; 1]

# 第一个向量归一化
u1 = v1 / norm(v1)

# 第二个向量正交化并归一化
proj = sum(v2 .* u1) * u1
u2 = v2 - proj
u2 = u2 / norm(u2)

disp("正交向量 u1:")
disp(u1)
disp("正交向量 u2:")
disp(u2)

# 验证正交性
dot_product = sum(u1 .* u2)
disp("点积(应接近0):" + num2str(dot_product))

示例5:最小二乘拟合

# 线性最小二乘:拟合直线 y = ax + b
x = [1 2 3 4 5]'
y = [2.1 3.9 6.2 8.1 9.9]'

# 构造设计矩阵 [x, ones]
A = [x, ones(size(x))]

# 最小二乘解:(A'A)^-1 * A'y
coeffs = inv(A' * A) * A' * y
# 或使用左除:
# coeffs = A \ y

a = coeffs(1)
b = coeffs(2)

disp("拟合直线:y = " + num2str(a) + "x + " + num2str(b))

# 预测值
y_pred = A * coeffs