四个矩阵连乘的计算复杂度
参考知乎回答
https://www.zhihu.com/question/390206363
假设这四个矩阵的维度分别为
A
(
m
×
n
)
\mathbf{A}(m \times n)
A(m×n)、
B
(
n
×
p
)
\mathbf{B} (n \times p)
B(n×p)、
C
(
p
×
q
)
\mathbf{C} (p \times q)
C(p×q) 和
D
(
q
×
r
)
\mathbf{D} (q \times r)
D(q×r),那么它们的连续相乘 ABCD 的计算复杂度为:
O ( m n p + m p q + m q r ) \mathcal{O}\left( m n p + m p q + m q r\right) O(mnp+mpq+mqr)
调换矩阵乘法的顺序对之有影响。
克罗内克积的计算复杂度
A
∈
C
m
×
n
\mathbf{A} \in \mathbb{C}^{m \times n}
A∈Cm×n
C
∈
C
p
×
q
\mathbf{C} \in \mathbb{C}^{p \times q}
C∈Cp×q
A ⊗ C \mathbf{A} \otimes \mathbf{C} A⊗C 的理论计算复杂度为 O ( m n p q ) \mathcal{O}\left( m n p q\right) O(mnpq)
特征值分解,奇异值分解,矩阵求逆的计算复杂度
假设对 A ∈ C m × m \mathbf{A} \in \mathbb{C}^{m \times m} A∈Cm×mEVD或SVD或求逆(伪逆),其理论计算复杂度为 O ( m 3 ) \mathcal{O}\left( m^3 \right) O(m3)
列向量乘以行向量与行向量乘以列向量的对比
size= 1000;
% 生成列向量和行向量
column_vector = randn(size, 1); % 1000行1列的列向量
row_vector = randn(1, size); % 1行1000列的行向量
% 计时开始 - 列向量乘以行向量
tic;
result_col_times_row = column_vector * row_vector;
elapsed_time_col_times_row = toc;
% 计时开始 - 行向量乘以列向量
tic;
result_row_times_col = row_vector * column_vector;
elapsed_time_row_times_col = toc;
fprintf('列向量乘以行向量的运行时间:%f 秒\n', elapsed_time_col_times_row);
fprintf('行向量乘以列向量的运行时间:%f 秒\n', elapsed_time_row_times_col);
发现一个很奇怪的现象:当代码中size < 1000时,运算时间基本一致,而当代码中size > 1000时,列乘行的复杂度是行乘以列的10倍以上。
克罗内克积与直接乘积的计算复杂度对比
frame = 100
size = 100
A = randn(size, size); %
B = randn(size, size); %
time_kron = 0;
time_direct = 0;
time_eig = 0;
for i = 1:frame
% 计算克罗内克积
tic;
C_kron = kron(A, B);
time_kron = time_kron + toc;
% 直接乘积
tic;
C_direct = A .* B; % 或者使用 C_direct = A * B,因为两个矩阵的大小相同
time_direct = time_direct + toc;
% 计算特征值分解
tic;
C_eig = eig(A);
time_eig = time_eig + toc;
end
fprintf('克罗内克积的运行时间:%f 秒\n', time_kron);
fprintf('直接乘积的运行时间:%f 秒\n', time_direct);
fprintf('特征值分解的运行时间:%f 秒\n', time_eig);
克罗内克积的运行时间:28.547411 秒
直接乘积的运行时间:0.011416 秒
特征值分解的运行时间:0.264713 秒
差距巨大