Эффективное умножение очень больших матриц в MATLAB
У меня недостаточно памяти, чтобы просто создать диагональную матрицу D-by-D, так как 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)
![alt text]()
Ответы
Ответ 1
Один из вариантов, который должен решить вашу проблему, - это разреженные матрицы. Вот пример:
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
Другим вариантом будет репликация элементов D по главной диагонали B
для создания матрицы M-by-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
И еще одним вариантом было бы использовать функцию BSXFUN:
result = bsxfun(@times,A.',diagB)*A; %'# An M-by-M result
Ответ 2
Может быть, у меня здесь немного мозгового мозга, но вы не можете превратить свою матрицу DxD в матрицу DxM (с M копиями вектора, который вы указали), а затем. * последние две матрицы, а не умножьте их (а затем, конечно, обычно умножайте первую на найденную величину продукта)?
Ответ 3
-
Вы получаете "вне памяти", потому что MATLAB не может найти кусок памяти, достаточно большой для размещения всей матрицы. Существуют различные способы избежать этой ошибки, описанной в документации MATLAB.
-
В MATLAB вам явно не нужно программировать явные петли в большинстве случаев, потому что вы можете использовать оператор *
. Существует метод ускорения матричного умножения, если это делается с явными циклами, здесь пример в С#. У него есть хорошая идея, как (потенциально большая) матрица может быть разбита на более мелкие матрицы. Чтобы содержать эти меньшие матрицы в MATLAB, вы можете использовать клеточную матрицу. Гораздо более вероятно, что система найдет достаточное количество ОЗУ для размещения двух меньших субматриц, а затем получившейся большой матрицы.