矩阵运算
矩阵创建方法
直接定义
# 标量
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