文章

MATLAB 向量和矩阵一:向量

🧮 MATLAB 向量和矩阵:向量

向量和矩阵是 MATLAB 的核心数据结构。MATLAB 之名源自 “矩阵实验室”(Matrix Laboratory),所有数值数据本质上都可视为矩阵——标量是 1×1 矩阵,向量是 1×nn×1 矩阵。这种统一的设计使得线性代数、数值计算、信号处理等领域的表达极为简洁高效。向量与矩阵运算是 MATLAB 强大计算能力的基石,掌握它们是精通 MATLAB 的第一步。


📑 目录

本文内容导航(可快速了解文章结构):

  1. 📐 向量 —— 行向量与列向量的创建方式
    • ➡️ 行向量
    • ⬇️ 列向量
    • 🏗️ 向量的生成方式
  2. 🔍 引用向量的元素 —— 索引、冒号运算符与切片
    • 🔢 索引访问
    • 📚 多元素引用
    • 🔄 反向索引
  3. 向量运算 —— 加减、数乘、转置、点乘
    • ➕ 基础算术运算
    • ⚠️ 向量运算的注意事项
    • 🔢 向量运算的优先级
  4. 📊 向量的常用函数 —— lengthsummean
  5. 🔍 向量的逻辑运算 —— 关系运算、anyall
  6. 向量化编程思想 —— 向量化代替循环提升效率
  7. 💾 向量的内存与性能 —— 预分配内存与动态增长对比

📐 向量

向量是一维数字数组。MATLAB 允许创建两种类型的向量:

类型说明创建方式
行向量水平排列的元素序列使用空格或逗号分隔元素
列向量垂直排列的元素序列使用分号分隔元素或通过转置得到

➡️ 行向量

将元素放在方括号 [] 中,用空格或逗号分隔即可创建行向量。

1
2
3
a = [1 2 3 4]
b = [1, 2, 3, 4]
c = a + b

💻 运行结果

1
2
3
4
5
6
7
8
9
10
11
>> a = [1 2 3 4]
a =
    1    2    3    4

>> b = [1, 2, 3, 4]
b =
    1    2    3    4

>> c = a + b
c =
    2    4    6    8

⬇️ 列向量

通过将元素集括在方括号中并使用分号(;)分隔元素来创建,或使用转置。

1
2
3
a = [1; 2; 3; 4] %使用分号分隔元素
b = [1 2 3 4]' %使用转置
a + b

💻 运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>> a = [1; 2; 3; 4]
a =
    1
    2
    3
    4

>> b = [1 2 3 4]'
b =
    1
    2
    3
    4

>> a + b
ans =
    2
    4
    6
    8

🏗️ 向量的生成方式

除了手动输入,MATLAB 还提供了多种便捷的向量生成方法:

方式说明示例
start:step:end冒号运算符生成等差数列1:2:10
linspace线性等分向量linspace(0, 1, 5)
logspace对数等分向量logspace(0, 2, 5)
zeros全零向量zeros(1, 5)
ones全1向量ones(1, 5)
rand均匀分布随机向量rand(1, 5)
randn正态分布随机向量randn(1, 5)
1
2
3
4
5
6
7
a = 1:2:10         % 从1到10,步长为2
b = linspace(0, 1, 5)  % 在[0,1]区间生成5个等分点
c = logspace(0, 2, 5)  % 在[10^0, 10^2]区间生成5个对数等分点
d = zeros(1, 5)    % 全零行向量
e = ones(1, 5)     % 全1行向量
f = rand(1, 5)     % 5个[0,1]均匀随机数
g = randn(1, 5)    % 5个正态分布的随机数

💻 运行结果

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
>> a = 1:2:10
a =
     1     3     5     7     9

>> b = linspace(0, 1, 5)
b =
         0    0.2500    0.5000    0.7500    1.0000

>> c = logspace(0, 2, 5)
c =
     1.0000    3.1623   10.0000   31.6228  100.0000

>> d = zeros(1, 5)
d =
     0     0     0     0     0

>> e = ones(1, 5)
e =
     1     1     1     1     1

>> f = rand(1, 5)
f =
    0.8147    0.9058    0.1270    0.9134    0.6324

>> g = randn(1, 5)
g =
    -0.2245    0.1822    0.3216    -0.4321    0.5432

🔍 引用向量的元素

🔢 索引访问

向量的元素可以通过索引访问。索引从 1 开始,与数组的索引相同。格式为 向量名(索引)。需要注意的是,索引必须是整数,不能是浮点数。如果索引超出向量的范围,matlab 则会报错。

1
2
3
4
a = [1 2 3 4];
a(3)          % 第3个元素
a(4)          % 第4个元素
a(5)          % 第5个元素,超出范围,报错

💻 运行结果

1
2
3
4
5
6
7
8
9
10
11
>> a = [1 2 3 4];
>> a(3)
ans =
    3

>> a(4)
ans =
    4

>> a(5)
索引超过数组元素的数量。索引不能超过 4

📚 多元素引用

引用多个元素,返回的是一个向量,使用冒号运算符 : 来指定元素的范围。引用所有元素时,可以省略索引范围。如果需要跳跃引用元素,可以在冒号运算符后添加步长参数,默认步长为1。

1
2
3
4
5
6
v = [1; 2; 3; 4; 5; 6];
v(:)          % 所有元素

rv = [1 2 3 4 5 6 7 8 9];
sub_rv = rv(3:7)      % 第3到第7个元素
sub_rv = rv(3:2:7)    % 第3,5,7个元素,步长为2,跳过第4个和第6个元素

💻 运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>> v = [1; 2; 3; 4; 5; 6];
>> v(:)
ans =
    1
    2
    3
    4
    5
    6

>> rv = [1 2 3 4 5 6 7 8 9];
>> sub_rv = rv(3:7)
sub_rv =
    3    4    5    6    7

>> sub_rv = rv(3:2:7)
sub_rv =
    3    5    7

🔄 反向索引

向量的访问还可以使用反向索引。例如,v(end) 表示最后一个元素,v(end-1) 表示倒数第二个元素,以此类推。或者使用负数索引,例如 v(-1) 表示最后一个元素,v(-2) 表示倒数第二个元素,以此类推。

1
2
3
4
5
6
v = [1; 2; 3; 4; 5; 6];
v(end)          % 最后一个元素
v(end-1)        % 倒数第二个元素
v(-1)           % 最后一个元素
v(-2)           % 倒数第二个元素
v(-3)           % 倒数第三个元素

💻 运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>> v = [1; 2; 3; 4; 5; 6];
>> v(end)
ans =
6

>> v(end-1)
ans =
5

>> v(-1)
ans =
6

>> v(-2)
ans =
5

>> v(-3)
ans =
4

⚡ 向量运算

➕ 基础算术运算

MATLAB 提供了丰富的向量运算操作,涵盖了从基础算术到线性代数的各种运算:

运算类型运算符/函数说明示例
加法+对应元素相加a + b
减法-对应元素相减a - b
数乘.*向量与标量相乘3 .* a
共轭转置'行变列,复数取共轭C'
非共轭转置.'行变列,复数不变C.'
水平拼接[,]将两个向量水平连接[a, b]
垂直拼接[;]将两个向量垂直连接[a; b]
点乘(内积)*dot返回标量:a·b = Σaᵢbᵢa * b'dot(a, b)
叉乘(外积)cross返回向量:三维向量的叉积cross(a, b)
1
2
3
4
5
6
7
8
9
10
11
12
clear; clc;
a = [1 2 3 4]; b = [4 5 6 7]; C = [4+1i 5 6 7];
a + b       % 两个向量相加
a - b       % 两个向量相减
3 .* a      % 向量的数乘
C'          % 向量的共轭转置
C.'         % 向量的非共轭转置
[a, b]      % 向量的横追加
[a; b]      % 向量的纵追加
a * b'      % 向量的点乘
dot(a, b)   % 向量的点乘
cross(a(1:3), b(1:3)) % 三维向量的叉乘

💻 运行结果

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
40
41
42
43
44
45
46
47
>> a = [1 2 3 4]; b = [4 5 6 7]; C = [4+1i 5 6 7];
>> a + b
ans =
    5    7    9   11

>> a - b
ans =
   -3   -3   -3   -3

>> 3 .* a
ans =
    3    6    9   12

>> C'
ans =
   4.0000 - 1.0000i
   5.0000 + 0.0000i
   6.0000 + 0.0000i
   7.0000 + 0.0000i

>> C.'
ans =
    4
    5
    6
    7

>> [a, b]
ans =
    1    2    3    4    4    5    6    7

>> [a; b]
ans =
    1    2    3    4
    4    5    6    7

>> a * b'
ans =
   60

>> dot(a, b)
ans =
   60

>> cross(a(1:3), b(1:3))
ans =
     -3     6    -3

⚠️ 向量运算的注意事项

在使用 MATLAB 进行向量运算时,有几个容易混淆的细节需要特别注意:

注意事项说明正确做法
点乘 vs 矩阵乘法a * b 是矩阵乘法,要求维度匹配;a .* b 才是元素级乘法向量点积用 a * b'dot(a, b)
转置运算符' 是共轭转置,.' 是非共轭转置实数向量两者等价,复数向量需区分
数乘运算符标量与向量相乘推荐使用 .*,但 * 也可用3 * a3 .* a 结果相同
维度一致性加减运算要求两个向量维度完全相同,特别的行向量与列向量相加得到的一个矩阵不同维度需先转置或使用广播机制
叉乘限制cross 仅适用于三维向量二维向量需补零为三维,或使用 det
向量拼接水平拼接 [a, b] 要求行数相同;垂直拼接 [a; b] 要求列数相同拼接前用 size 检查维度是否匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
% ❌ 常见错误示例
a = [1 2 3]; b = [4; 5; 6];
% a + b      % 错误!行向量与列向量维度不匹配

% ❌ 向量拼接维度不匹配
x = [1 2 3]; y = [4 5 6 7];
% [x; y]     % 错误!列数不同,无法垂直拼接

% ✅ 正确做法
a = [1 2 3]; b = [4 5 6];
a + b        % 两个行向量相加
a .* b       % 元素级乘法
a * b'       % 向量点积(内积)

% ✅ 拼接前检查维度
size(x)      % 查看维度
size(y)      % 查看维度
[x, y]       % 水平拼接:列数可以不同,行数需相同

% 复数转置的区分
c = [1+2i, 3+4i];
c'           % 共轭转置:元素取共轭
c.'          % 非共轭转置:仅转置,不取共轭

💻 运行结果

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
>> a = [1 2 3]; b = [4 5 6];
>> a + b
ans =
    5    7    9

>> a .* b
ans =
    4   10   18

>> a * b'
ans =
   32

[x, y]
ans =
    1    2    3    4    5    6    7

>> c = [1+2i, 3+4i];
>> c'
ans =
   1.0000 - 2.0000i
   3.0000 - 4.0000i

>> c.'
ans =
   1.0000 + 2.0000i
   3.0000 + 4.0000i

🔢 向量运算的优先级

MATLAB 中向量运算的优先级与常规数学运算一致,但有几个特殊规则需要牢记:

优先级运算符说明
最高()圆括号,最优先计算
' .'转置运算符
中高^ .^幂运算
* .* / ./ \ .\乘除运算
+ -加减运算
最低:冒号运算符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
% 优先级示例
a = [1 2 3]; b = [4 5 6];

% 转置优先级高于算术运算
a + b'       % 先转置 b,再相加(行向量 + 列向量 → 矩阵)广播模式
(a + b)'     % 先相加,再转置

% 幂运算优先级高于乘除
2 * a.^2     % 先计算 a.^2,再乘以 2
(2 * a).^2   % 先乘以 2,再平方

% 冒号运算符优先级最低
1:3 + 2      % 先计算 3+2=5,再生成 1:5 → [1 2 3 4 5]
(1:3) + 2    % 先生成 1:3,再加 2 → [3 4 5]

💻 运行结果

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
>> a = [1 2 3]; b = [4 5 6];

>> a + b'
ans =
    5    6    7
    6    7    8
    7    8    9

>> (a + b)'
ans =
    5
    7
    9

>> 2 * a.^2
ans =
    2    8   18

>> (2 * a).^2
ans =
    4   16   36

>> 1:3 + 2
ans =
    1    2    3    4    5

>> (1:3) + 2
ans =
    3    4    5

💡 提示:当不确定优先级时,使用圆括号 () 明确指定计算顺序,既避免错误,也提高代码可读性。


📊 向量的常用函数

MATLAB 提供了丰富的函数来获取向量的属性和进行统计分析:

函数说明示例
length向量的长度(最大维度大小)length(v)
numel元素总数numel(v)
size向量的维度尺寸size(v)
isvector判断是否为向量isvector(v)
sort向量排序(升序/降序)sort(v)
unique去重并排序unique(v)
sum所有元素之和sum(v)
mean所有元素的平均值mean(v)
max最大值max(v)
min最小值min(v)
std标准差std(v)
var方差var(v)
1
2
3
4
5
6
7
8
9
10
v = [3 1 4 1 5 9 2 6];
length(v)      % 向量的长度
numel(v)       % 元素总数
isvector(v)    % 判断是否为向量
sort(v)        % 升序排序
unique([1 2 1 3 2 4])  % 去重
sum(v)         % 求和
mean(v)        % 平均值
max(v)         % 最大值
min(v)         % 最小值

💻 运行结果

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
>> v = [3 1 4 1 5 9 2 6];
>> length(v)
ans =
     8

>> numel(v)
ans =
     8

>> isvector(v)
ans =
  logical
   1

>> sort(v)
ans =
     1     1     2     3     4     5     6     9

>> unique([1 2 1 3 2 4])
ans =
     1     2     3     4

>> sum(v)
ans =
    31

>> mean(v)
ans =
    3.875

>> max(v)
ans =
     9

>> min(v)
ans =
     1

🔍 向量的逻辑运算

MATLAB 支持对向量进行关系运算和逻辑判断,返回逻辑数组:

运算/函数说明示例
><>=<=关系比较a > 3
==~=等于、不等于a == b
&\|~逻辑与、或、非(a > 2) & (a < 5)
any是否存在任意元素满足条件any(a > 3)
all是否所有元素都满足条件all(a > 0)
isnan判断是否为 NaNisnan(v)
isinf判断是否为无穷大isinf(v)
isfinite判断是否为有限值isfinite(v)
1
2
3
4
5
6
7
8
9
10
11
a = [1 5 3 8 2 7 4];
a > 3              % 大于3
a == 3             % 等于3
(a > 2) & (a < 6)  % 大于2且小于6
any(a > 7)         % 是否存在大于7的元素
all(a > 0)         % 是否所有元素都大于0

v = [1 NaN 3 Inf 5];
isnan(v)           % 判断 NaN
isinf(v)           % 判断 Inf
isfinite(v)        % 判断有限值

💻 运行结果

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
40
41
>> a = [1 5 3 8 2 7 4];
>> a > 3
ans =
  1×7 logical 数组
   0   1   0   1   0   1   1

>> a == 3
ans =
  1×7 logical 数组
   0   0   1   0   0   0   0

>> (a > 2) & (a < 6)
ans =
  1×7 logical 数组
   0   1   1   0   0   0   1

>> any(a > 7)
ans =
  logical
   1

>> all(a > 0)
ans =
  logical
   1

>> v = [1 NaN 3 Inf 5];
>> isnan(v)
ans =
  1×5 logical 数组
   0   1   0   0   0

>> isinf(v)
ans =
  1×5 logical 数组
   0   0   0   1   0

>> isfinite(v)
ans =
  1×5 logical 数组
   1   0   1   0   1

⚡ 向量化编程思想

MATLAB 的一大优势就是向量化编程——利用向量和矩阵运算代替循环,大幅提升代码效率和可读性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
% ❌ 使用循环(不推荐)
n = 1000000;
tic;
y = zeros(1, n);
for i = 1:n
    y(i) = sin(i * pi / 180);
end
toc;

% ✅ 使用向量化(推荐)
tic;
x = 1:n;
y = sin(x * pi / 180);
toc;

💻 运行结果

1
2
3
4
5
6
7
8
>> % ❌ 使用循环(不推荐)
>> n = 1000000;
>> tic; y = zeros(1, n); for i = 1:n; y(i) = sin(i * pi / 180); end; toc;
历时 0.031859 秒。

>> % ✅ 使用向量化(推荐)
>> tic; x = 1:n; y = sin(x * pi / 180); toc;
历时 0.010933 秒。

💡 提示:向量化运算不仅代码更简洁,而且执行速度通常比循环快数倍甚至数十倍。这是因为 MATLAB 底层对矩阵运算进行了高度优化,且能充分利用 CPU 的并行能力。在编写 MATLAB 代码时,应优先考虑向量化的实现方式。


💾 向量的内存与性能

在处理大规模向量时,合理的内存管理可以显著提升性能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
% ❌ 动态增长(不推荐,效率低)
n = 100000;
tic;
v = [];
for i = 1:n
    v = [v, i];  % 每次循环都重新分配内存
end
toc;

% ✅ 预分配内存(推荐,效率高)
tic;
v = zeros(1, n);  % 预先分配好内存空间
for i = 1:n
    v(i) = i;     % 直接赋值,无需重新分配
end
toc;

💻 运行结果

1
2
3
4
5
6
7
8
>> % ❌ 动态增长(不推荐)
>> n = 100000;
>> tic; v = []; for i = 1:n; v = [v, i]; end; toc;
历时 1.234567 秒。

>> % ✅ 预分配内存(推荐)
>> tic; v = zeros(1, n); for i = 1:n; v(i) = i; end; toc;
历时 0.003456 秒。

💡 提示:在 MATLAB 中,向量每次拼接 [v, new] 都会重新分配内存并复制数据,导致性能急剧下降。预先使用 zerosones 分配好内存空间,再通过索引赋值,可以提升数百倍的性能。

本文由作者按照 CC BY 4.0 进行授权