MATLAB中非常大的矩阵的有效乘法

mat*_*eek 12 algorithm matlab linear-algebra octave matrix-multiplication

由于D很大,我没有足够的内存来简单地创建对角D-by-D矩阵.我不断收到"内存不足"的错误.

我没有在第一次乘法中执行M x D x D操作,而是执行M x D操作,但我的代码仍然需要很长时间才能运行.

任何人都可以找到一种更有效的方法来执行乘法运算A'*B*A吗?这是我到目前为止所做的尝试:

D=20000
M=25

A = floor(rand(D,M)*10);
B = floor(rand(1,D)*10);

for i=1:D
    for j=1:M
        result(i,j) = A(i,j) * B(1,j);
    end
end    

manual = result * A';
auto = A*diag(B)*A';
isequal(manual,auto)
Run Code Online (Sandbox Code Playgroud)

替代文字

gno*_*ice 12

应该解决您的问题的一个选项是使用稀疏矩阵.这是一个例子:

D = 20000;
M = 25;
A = floor(rand(D,M).*10);    %# A D-by-M matrix
diagB = rand(1,D).*10;       %# Main diagonal of B
B = sparse(1:D,1:D,diagB);   %# A sparse D-by-D diagonal matrix
result = (A.'*B)*A;         %'# An M-by-M result
Run Code Online (Sandbox Code Playgroud)

另一种选择是复制d元件沿主对角线的B使用函数来创建一个M-d矩阵REPMAT,然后使用逐元素乘法A.':

B = repmat(diagB,M,1);   %# Replicate diagB to create an M-by-D matrix
result = (A.'.*B)*A;    %'# An M-by-M result
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用BSXFUN功能:

result = bsxfun(@times,A.',diagB)*A;  %'# An M-by-M result
Run Code Online (Sandbox Code Playgroud)

  • 如果内存是个问题,`bsxfun`比`repmat`更受欢迎,因为它不会产生复制的矩阵.然而,`bsxfun`直到Matlab 2006左右才可用...... (2认同)