Эффективное умножение очень больших матриц в MATLAB - PullRequest
12 голосов
/ 12 декабря 2010

У меня недостаточно памяти, чтобы просто создать диагональную матрицу 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

Ответы [ 3 ]

12 голосов
/ 12 декабря 2010

Один из вариантов, который должен решить вашу проблему - это использование разреженных матриц . Вот пример:

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
3 голосов
/ 12 декабря 2010
  1. Вы получаете «недостаточно памяти», потому что MATLAB не может найти кусок памяти, достаточно большой, чтобы вместить всю матрицу.Существуют различные способы избежать этой ошибки, описанные в документации MATLAB .

  2. В MATLAB вам, очевидно, не требуется программировать явные циклы в большинстве случаев, поскольку вы можете использовать оператор *.Существует методика ускорения умножения матриц, если это делается с явными циклами, вот пример в C # .Хорошо известно, как (потенциально большие) матрицы можно разбить на более мелкие матрицы.Чтобы содержать эти меньшие матрицы в MATLAB, вы можете использовать ячейку матрицы.Гораздо более вероятно, что система найдет достаточно ОЗУ для размещения двух меньших подматриц, чем полученная большая матрица.

3 голосов
/ 12 декабря 2010

Может быть, у меня есть небольшой проблеск, но вы не можете превратить свою матрицу DxD в матрицу DxM (с M копиями вектора, который вам дан), а затем.умножьте их (а затем, конечно, обычно умножьте первое на найденное количество продукта)?

...