MATLAB 向量和矩阵基础

向量和矩阵是MATLAB的核心数据结构,MATLAB的名称就来源于”Matrix Laboratory”(矩阵实验室)。理解向量和矩阵的操作是掌握MATLAB的关键基础。

MATLAB中的所有数据都以矩阵形式存储:

  • 标量:1×1的矩阵
  • 行向量:1×n的矩阵
  • 列向量:n×1的矩阵
  • 矩阵:m×n的矩阵
  • 高维数组:多维矩阵

MATLAB提供了丰富的函数来创建、操作和分析向量和矩阵,这些功能使得复杂的数学运算变得简单直观。

向量的创建和基本操作

向量创建方法

向量是一维数组,在MATLAB中可以是行向量或列向量。创建向量有多种方法,每种方法适用于不同的场景。

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
% ===== 向量创建方法示例 =====

% 方法1:直接输入(行向量)
row_vector = [1, 2, 3, 4, 5];
fprintf('行向量:');
disp(row_vector);

% 方法2:分号分隔创建列向量
col_vector = [1; 2; 3; 4; 5];
fprintf('列向量:\n');
disp(col_vector);

% 方法3:使用冒号操作符创建等差序列
sequence1 = 1:5; % 步长为1,从1到5
sequence2 = 0:0.5:3; % 步长为0.5,从0到3
sequence3 = 10:-2:0; % 步长为-2,从10到0(递减)

fprintf('等差序列1:'); disp(sequence1);
fprintf('等差序列2:'); disp(sequence2);
fprintf('等差序列3:'); disp(sequence3);

% 方法4:使用linspace创建线性等分向量
linear_space = linspace(0, 10, 11); % 从0到10,等分为11个点
fprintf('线性等分向量:'); disp(linear_space);

% 方法5:使用logspace创建对数等分向量
log_space = logspace(0, 2, 5); % 从10^0到10^2,等分为5个点
fprintf('对数等分向量:'); disp(log_space);

% 方法6:使用专用函数创建特殊向量
zeros_vec = zeros(1, 5); % 零向量
ones_vec = ones(1, 5); % 单位向量
random_vec = rand(1, 5); % 随机向量
normal_vec = randn(1, 5); % 正态分布随机向量

fprintf('零向量:'); disp(zeros_vec);
fprintf('单位向量:'); disp(ones_vec);
fprintf('随机向量:'); disp(random_vec);
fprintf('正态分布向量:'); disp(normal_vec);

向量基本属性和操作

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
% ===== 向量基本属性示例 =====

% 创建示例向量
data_vector = [2, 5, 1, 8, 3, 9, 4, 7, 6];

% 基本属性
fprintf('向量长度:%d\n', length(data_vector));
fprintf('向量大小:%dx%d\n', size(data_vector, 1), size(data_vector, 2));
fprintf('元素总数:%d\n', numel(data_vector));

% 向量统计信息
fprintf('最大值:%.2f\n', max(data_vector));
fprintf('最小值:%.2f\n', min(data_vector));
fprintf('平均值:%.2f\n', mean(data_vector));
fprintf('中位数:%.2f\n', median(data_vector));
fprintf('标准差:%.2f\n', std(data_vector));
fprintf('方差:%.2f\n', var(data_vector));
fprintf('总和:%.2f\n', sum(data_vector));
fprintf('乘积:%.2f\n', prod(data_vector));

% 查找操作
[max_val, max_idx] = max(data_vector);
[min_val, min_idx] = min(data_vector);
fprintf('最大值 %.2f 位于索引 %d\n', max_val, max_idx);
fprintf('最小值 %.2f 位于索引 %d\n', min_val, min_idx);

% 查找特定条件的元素
greater_than_5 = find(data_vector > 5);
fprintf('大于5的元素索引:'); disp(greater_than_5);
fprintf('大于5的元素值:'); disp(data_vector(greater_than_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
30
31
32
33
% ===== 向量索引和切片示例 =====

% 创建测试向量
test_vector = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];

% 基本索引
fprintf('第3个元素:%d\n', test_vector(3));
fprintf('最后一个元素:%d\n', test_vector(end));
fprintf('倒数第二个元素:%d\n', test_vector(end-1));

% 多个索引
selected_elements = test_vector([1, 3, 5, 7]);
fprintf('选中的元素:'); disp(selected_elements);

% 范围索引(切片)
slice1 = test_vector(2:5); % 第2到第5个元素
slice2 = test_vector(1:2:end); % 每隔一个元素取一个
slice3 = test_vector(end:-1:1); % 反向所有元素

fprintf('切片1(2到5):'); disp(slice1);
fprintf('切片2(步长为2):'); disp(slice2);
fprintf('切片3(反向):'); disp(slice3);

% 逻辑索引
logical_mask = test_vector > 50;
filtered_elements = test_vector(logical_mask);
fprintf('大于50的元素:'); disp(filtered_elements);

% 修改元素
modified_vector = test_vector;
modified_vector(3) = 999; % 修改单个元素
modified_vector(1:3) = 0; % 修改多个元素
fprintf('修改后的向量:'); disp(modified_vector);

矩阵的创建和基本操作

矩阵创建方法

矩阵是二维数组,MATLAB提供了多种创建矩阵的方法。

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
% ===== 矩阵创建方法示例 =====

% 方法1:直接输入
matrix1 = [1, 2, 3; 4, 5, 6; 7, 8, 9];
fprintf('直接输入矩阵:\n');
disp(matrix1);

% 方法2:使用分号分隔行
matrix2 = [1, 2, 3
4, 5, 6
7, 8, 9];
fprintf('多行输入矩阵:\n');
disp(matrix2);

% 方法3:使用专用函数创建特殊矩阵
zeros_matrix = zeros(3, 4); % 零矩阵
ones_matrix = ones(3, 4); % 全1矩阵
eye_matrix = eye(4); % 单位矩阵
diag_matrix = diag([1, 2, 3, 4]); % 对角矩阵
rand_matrix = rand(3, 4); % 随机矩阵
randn_matrix = randn(3, 4); % 正态分布随机矩阵

fprintf('零矩阵:\n'); disp(zeros_matrix);
fprintf('全1矩阵:\n'); disp(ones_matrix);
fprintf('单位矩阵:\n'); disp(eye_matrix);
fprintf('对角矩阵:\n'); disp(diag_matrix);
fprintf('随机矩阵:\n'); disp(rand_matrix);

% 方法4:从向量创建矩阵
vector_data = 1:12;
reshaped_matrix = reshape(vector_data, 3, 4); % 重新整形为3x4矩阵
fprintf('重新整形的矩阵:\n');
disp(reshaped_matrix);

% 方法5:矩阵拼接
A = [1, 2; 3, 4];
B = [5, 6; 7, 8];
horizontal_concat = [A, B]; % 水平拼接
vertical_concat = [A; B]; % 垂直拼接

fprintf('水平拼接:\n'); disp(horizontal_concat);
fprintf('垂直拼接:\n'); disp(vertical_concat);

矩阵基本属性

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
% ===== 矩阵基本属性示例 =====

% 创建示例矩阵
sample_matrix = [1, 4, 7, 2;
8, 3, 6, 9;
5, 1, 4, 3];

% 基本属性
[rows, cols] = size(sample_matrix);
fprintf('矩阵大小:%d x %d\n', rows, cols);
fprintf('总元素数:%d\n', numel(sample_matrix));

% 矩阵维度信息
fprintf('行数:%d\n', size(sample_matrix, 1));
fprintf('列数:%d\n', size(sample_matrix, 2));

% 矩阵统计信息
fprintf('矩阵最大值:%.2f\n', max(sample_matrix(:)));
fprintf('矩阵最小值:%.2f\n', min(sample_matrix(:)));
fprintf('矩阵平均值:%.2f\n', mean(sample_matrix(:)));
fprintf('矩阵总和:%.2f\n', sum(sample_matrix(:)));

% 按行列统计
row_sums = sum(sample_matrix, 2); % 每行的和
col_sums = sum(sample_matrix, 1); % 每列的和
row_means = mean(sample_matrix, 2); % 每行的平均值
col_means = mean(sample_matrix, 1); % 每列的平均值

fprintf('每行的和:'); disp(row_sums');
fprintf('每列的和:'); disp(col_sums);
fprintf('每行的平均值:'); disp(row_means');
fprintf('每列的平均值:'); disp(col_means);

矩阵索引和切片

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
% ===== 矩阵索引和切片示例 =====

% 创建测试矩阵
test_matrix = [11, 12, 13, 14, 15;
21, 22, 23, 24, 25;
31, 32, 33, 34, 35;
41, 42, 43, 44, 45];

fprintf('原始矩阵:\n');
disp(test_matrix);

% 单个元素索引
element = test_matrix(2, 3); % 第2行第3列
fprintf('第2行第3列的元素:%d\n', element);

% 整行或整列
row2 = test_matrix(2, :); % 第2行所有元素
col3 = test_matrix(:, 3); % 第3列所有元素
fprintf('第2行:'); disp(row2);
fprintf('第3列:'); disp(col3');

% 子矩阵提取
submatrix1 = test_matrix(1:2, 2:4); % 前两行,第2到4列
submatrix2 = test_matrix([1,3], [2,4,5]); % 第1、3行,第2、4、5列

fprintf('子矩阵1:\n'); disp(submatrix1);
fprintf('子矩阵2:\n'); disp(submatrix2);

% 逻辑索引
logical_matrix = test_matrix > 25;
elements_gt_25 = test_matrix(logical_matrix);
fprintf('大于25的元素:'); disp(elements_gt_25');

% 线性索引(将矩阵按列展开的索引)
linear_idx = sub2ind(size(test_matrix), 2, 3); % 转换为线性索引
element_linear = test_matrix(linear_idx);
fprintf('线性索引%d对应的元素:%d\n', linear_idx, element_linear);

% 修改矩阵元素
modified_matrix = test_matrix;
modified_matrix(2, 3) = 999; % 修改单个元素
modified_matrix(1, :) = 0; % 修改整行
modified_matrix(:, 5) = [100; 200; 300; 400]; % 修改整列

fprintf('修改后的矩阵:\n');
disp(modified_matrix);

向量和矩阵运算

基本算术运算

MATLAB支持两种类型的运算:矩阵运算和元素运算。

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
% ===== 基本算术运算示例 =====

% 创建示例矩阵
A = [1, 2, 3; 4, 5, 6];
B = [7, 8, 9; 10, 11, 12];
C = [1, 2; 3, 4; 5, 6];

fprintf('矩阵A:\n'); disp(A);
fprintf('矩阵B:\n'); disp(B);
fprintf('矩阵C:\n'); disp(C);

% 矩阵加法和减法
addition = A + B;
subtraction = A - B;
fprintf('A + B:\n'); disp(addition);
fprintf('A - B:\n'); disp(subtraction);

% 矩阵乘法(线性代数意义)
matrix_mult = A * C; % 2x3 × 3x2 = 2x2
fprintf('A * C(矩阵乘法):\n'); disp(matrix_mult);

% 元素级运算(点运算)
element_mult = A .* B; % 对应元素相乘
element_div = A ./ B; % 对应元素相除
element_power = A .^ 2; % 每个元素平方

fprintf('A .* B(元素相乘):\n'); disp(element_mult);
fprintf('A ./ B(元素相除):\n'); disp(element_div);
fprintf('A .^ 2(元素平方):\n'); disp(element_power);

% 标量运算
scalar_mult = A * 3; % 每个元素乘以3
scalar_add = A + 10; % 每个元素加10
scalar_power = A .^ 0.5; % 每个元素开平方

fprintf('A * 3:\n'); disp(scalar_mult);
fprintf('A + 10:\n'); disp(scalar_add);
fprintf('A .^ 0.5:\n'); disp(scalar_power);

矩阵函数运算

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
% ===== 矩阵函数运算示例 =====

% 创建示例数据
angle_matrix = [0, pi/4, pi/2; pi, 3*pi/4, 2*pi];
positive_matrix = [1, 4, 9; 16, 25, 36];

% 三角函数
sin_result = sin(angle_matrix);
cos_result = cos(angle_matrix);
tan_result = tan(angle_matrix);

fprintf('角度矩阵:\n'); disp(angle_matrix);
fprintf('sin函数结果:\n'); disp(sin_result);
fprintf('cos函数结果:\n'); disp(cos_result);

% 指数和对数函数
exp_result = exp([1, 2, 3]); % e的幂
log_result = log(positive_matrix); % 自然对数
log10_result = log10(positive_matrix); % 常用对数
sqrt_result = sqrt(positive_matrix); % 平方根

fprintf('指数函数结果:'); disp(exp_result);
fprintf('自然对数结果:\n'); disp(log_result);
fprintf('平方根结果:\n'); disp(sqrt_result);

% 取整函数
decimal_matrix = [1.2, 2.7, -1.3; -2.8, 3.1, 4.9];
floor_result = floor(decimal_matrix); % 向下取整
ceil_result = ceil(decimal_matrix); % 向上取整
round_result = round(decimal_matrix); % 四舍五入
fix_result = fix(decimal_matrix); % 向零取整

fprintf('原始矩阵:\n'); disp(decimal_matrix);
fprintf('向下取整:\n'); disp(floor_result);
fprintf('向上取整:\n'); disp(ceil_result);
fprintf('四舍五入:\n'); disp(round_result);
fprintf('向零取整:\n'); disp(fix_result);

线性代数运算

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
% ===== 线性代数运算示例 =====

% 创建方阵进行线性代数运算
square_matrix = [4, 2, 1; 2, 5, 3; 1, 3, 6];
vector_b = [1; 2; 3];

fprintf('方阵A:\n'); disp(square_matrix);
fprintf('向量b:\n'); disp(vector_b);

% 矩阵转置
transpose_A = square_matrix';
fprintf('A的转置:\n'); disp(transpose_A);

% 矩阵行列式
det_A = det(square_matrix);
fprintf('A的行列式:%.4f\n', det_A);

% 矩阵的逆
if det_A ~= 0
inv_A = inv(square_matrix);
fprintf('A的逆矩阵:\n'); disp(inv_A);

% 验证逆矩阵
identity_check = square_matrix * inv_A;
fprintf('A * inv(A)(应为单位矩阵):\n'); disp(identity_check);
end

% 矩阵的秩
rank_A = rank(square_matrix);
fprintf('A的秩:%d\n', rank_A);

% 矩阵的迹(对角元素之和)
trace_A = trace(square_matrix);
fprintf('A的迹:%.4f\n', trace_A);

% 特征值和特征向量
[eigenvectors, eigenvalues] = eig(square_matrix);
fprintf('特征值:\n'); disp(diag(eigenvalues));
fprintf('特征向量:\n'); disp(eigenvectors);

% 解线性方程组 Ax = b
solution_x = square_matrix \ vector_b; % 等价于 inv(A) * b
fprintf('线性方程组的解:\n'); disp(solution_x);

% 验证解
verification = square_matrix * solution_x;
fprintf('验证Ax(应等于b):\n'); disp(verification);

高级矩阵操作

矩阵分解

矩阵分解是线性代数中的重要概念,在数值计算和数据分析中有广泛应用。

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
% ===== 矩阵分解示例 =====

% 创建测试矩阵
A = [4, 2, 1; 2, 5, 3; 1, 3, 6];
fprintf('原始矩阵A:\n'); disp(A);

% LU分解
[L, U, P] = lu(A);
fprintf('L矩阵(下三角):\n'); disp(L);
fprintf('U矩阵(上三角):\n'); disp(U);
fprintf('P矩阵(置换矩阵):\n'); disp(P);
fprintf('验证PA = LU:\n'); disp(P*A - L*U);

% Cholesky分解(适用于正定矩阵)
if all(eig(A) > 0) % 检查是否为正定矩阵
R = chol(A);
fprintf('Cholesky分解R:\n'); disp(R);
fprintf('验证A = R''*R:\n'); disp(A - R'*R);
end

% QR分解
[Q, R] = qr(A);
fprintf('Q矩阵(正交矩阵):\n'); disp(Q);
fprintf('R矩阵(上三角矩阵):\n'); disp(R);
fprintf('验证A = Q*R:\n'); disp(A - Q*R);

% 奇异值分解(SVD)
[U, S, V] = svd(A);
fprintf('U矩阵:\n'); disp(U);
fprintf('S矩阵(奇异值):\n'); disp(S);
fprintf('V矩阵:\n'); disp(V);
fprintf('验证A = U*S*V'':\n'); disp(A - U*S*V');

% 特征值分解
[V_eig, D_eig] = eig(A);
fprintf('特征向量矩阵V:\n'); disp(V_eig);
fprintf('特征值对角矩阵D:\n'); disp(D_eig);
fprintf('验证A*V = V*D:\n'); disp(A*V_eig - V_eig*D_eig);

矩阵变换和操作

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
% ===== 矩阵变换和操作示例 =====

% 创建示例矩阵
original_matrix = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12];
fprintf('原始矩阵:\n'); disp(original_matrix);

% 矩阵重构
reshaped = reshape(original_matrix, 2, 6); % 重构为2x6
fprintf('重构为2x6:\n'); disp(reshaped);

% 矩阵旋转
rotated_90 = rot90(original_matrix); % 逆时针旋转90度
rotated_180 = rot90(original_matrix, 2); % 旋转180度
fprintf('旋转90度:\n'); disp(rotated_90);
fprintf('旋转180度:\n'); disp(rotated_180);

% 矩阵翻转
flipped_lr = fliplr(original_matrix); % 左右翻转
flipped_ud = flipud(original_matrix); % 上下翻转
fprintf('左右翻转:\n'); disp(flipped_lr);
fprintf('上下翻转:\n'); disp(flipped_ud);

% 矩阵排序
unsorted_matrix = [3, 1, 4; 2, 5, 1; 6, 2, 3];
sorted_each_col = sort(unsorted_matrix); % 按列排序
sorted_each_row = sort(unsorted_matrix, 2); % 按行排序
[sorted_vals, indices] = sort(unsorted_matrix(:)); % 全矩阵排序

fprintf('原始矩阵:\n'); disp(unsorted_matrix);
fprintf('按列排序:\n'); disp(sorted_each_col);
fprintf('按行排序:\n'); disp(sorted_each_row);

% 矩阵循环移位
shifted_matrix = circshift(original_matrix, [1, 2]); % 向下1行,向右2列
fprintf('循环移位:\n'); disp(shifted_matrix);

% 矩阵块操作
block_matrix = blkdiag([1,2; 3,4], [5,6; 7,8], 9); % 块对角矩阵
fprintf('块对角矩阵:\n'); disp(block_matrix);

稀疏矩阵

对于大部分元素为零的矩阵,使用稀疏矩阵可以节省内存和提高计算效率。

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
% ===== 稀疏矩阵示例 =====

% 创建稀疏矩阵
i = [1, 2, 3, 4, 5]; % 行索引
j = [1, 3, 2, 4, 1]; % 列索引
s = [10, 20, 30, 40, 50]; % 非零元素值
sparse_matrix = sparse(i, j, s, 5, 5);

fprintf('稀疏矩阵:\n');
disp(full(sparse_matrix)); % 转换为完整矩阵显示

% 稀疏矩阵信息
fprintf('非零元素个数:%d\n', nnz(sparse_matrix));
fprintf('稀疏度:%.2f%%\n', (1 - nnz(sparse_matrix)/numel(sparse_matrix)) * 100);

% 从完整矩阵创建稀疏矩阵
full_matrix = [1, 0, 0, 4; 0, 2, 0, 0; 0, 0, 3, 0; 5, 0, 0, 6];
sparse_from_full = sparse(full_matrix);
fprintf('从完整矩阵创建的稀疏矩阵:\n');
disp(full(sparse_from_full));

% 稀疏矩阵运算
A_sparse = sparse([1,2,3], [1,2,3], [1,2,3], 3, 3);
B_sparse = sparse([1,2,3], [3,2,1], [3,2,1], 3, 3);

sum_sparse = A_sparse + B_sparse;
mult_sparse = A_sparse * B_sparse;

fprintf('稀疏矩阵A:\n'); disp(full(A_sparse));
fprintf('稀疏矩阵B:\n'); disp(full(B_sparse));
fprintf('A + B:\n'); disp(full(sum_sparse));
fprintf('A * B:\n'); disp(full(mult_sparse));

% 查找非零元素
[rows, cols, vals] = find(sparse_matrix);
fprintf('非零元素位置和值:\n');
for k = 1:length(vals)
fprintf('(%d,%d) = %.1f\n', rows(k), cols(k), vals(k));
end