Matlab - присвоение в массив приводит к ошибке: «Превышен максимально допустимый размер программы» - PullRequest
3 голосов
/ 06 сентября 2011

Я запускаю скрипт, который создает много больших массивов. Все работает нормально до следующих строк:

%dist is a sparse matrix
inds=dist~=0;
inserts=exp(-dist(inds).^2/2*sig_dist);
dist(inds)=inserts;

Последняя строка вызывает ошибку: ??? Maximum variable size allowed by the program is exceeded.

Я не понимаю, как последняя строка может увеличить размер переменной - обратите внимание, я вставляю в матрицу dist только в тех местах, которые не были нулевыми для начала. Так что здесь происходит?

Ответы [ 3 ]

1 голос
/ 07 сентября 2011

В MATLAB реализована модель «отложенного копирования при записи». Позвольте мне объяснить на примере.

Сначала создайте действительно большой вектор

x = ones(5*1e7,1);

Теперь, скажем, мы хотели создать еще один вектор такого же размера:

y = ones(5*1e7,1);

На моей машине произойдет сбой со следующей ошибкой

??? Недостаточно памяти. Введите HELP MEMORY для ваших вариантов.

Мы знаем, что y потребует 5*1e7*8 = 400000000 bytes ~ 381.47 MB (что также подтверждается which x), но если мы проверим количество свободной свободной памяти:

>> memory
Maximum possible array:             242 MB (2.540e+008 bytes) *
Memory available for all arrays:    965 MB (1.012e+009 bytes) **
Memory used by MATLAB:              820 MB (8.596e+008 bytes)
Physical Memory (RAM):             3070 MB (3.219e+009 bytes)

*  Limited by contiguous virtual address space available.
** Limited by virtual address space available.

мы видим, что оно превышает 242 MB доступное.

С другой стороны, если вы назначите:

y = x;

это удастся почти мгновенно. Это связано с тем, что MATLAB фактически не выделяет другой кусок памяти того же размера, что и x, вместо этого он создает переменную y, которая использует те же базовые данные, что и x (фактически, если вы снова вызовете memory вы почти не увидите разницы).

MATLAB будет пытаться сделать еще одну копию данных только после изменения одной из переменных, поэтому, если вы попробуете этот довольно невинный оператор присваивания:

y(1) = 99;

он выдаст ошибку, жалуясь, что ей не хватило памяти, что, как я подозреваю, происходит в вашем случае ...


EDIT:

Мне удалось воспроизвести проблему в следующем примере:

%# a large enough sparse matrix (you may need to adjust the size)
dist = sparse(1:3000000,1:3000000,1);

Сначала давайте проверим состояние памяти:

» whos
  Name            Size                    Bytes  Class     Attributes

  dist      3000000x3000000            48000004  double    sparse    

» memory
Maximum possible array:             394 MB (4.132e+008 bytes) *
Memory available for all arrays:   1468 MB (1.539e+009 bytes) **
Memory used by MATLAB:              328 MB (3.440e+008 bytes)
Physical Memory (RAM):             3070 MB (3.219e+009 bytes)

*  Limited by contiguous virtual address space available.
** Limited by virtual address space available.

скажем, мы хотим применить функцию ко всем элементам, не равным нулю:

f = @(X) exp(-X.^2 ./ 2);

достаточно странно, если вы попытаетесь нарезать / назначить, то произойдет сбой:

» dist(dist~=0) = f( dist(dist~=0) );
??? Maximum variable size allowed by the program is exceeded.

Однако следующее назначение не выдает ошибку:

[r,c,val] = find(dist);
dist = sparse(r, c, f(val));

У меня до сих пор нет объяснения, почему в первом случае выдается ошибка, но, возможно, использование функции FIND таким образом решит вашу проблему ...

1 голос
/ 07 сентября 2011

Я не уверен, почему вы видите эту ошибку.Однако я предлагаю вам использовать функцию Matlab spfun, чтобы применить функцию к ненулевым элементам в разреженной матрице.Например:

>>dist = sprand(10000,20000,0.001);
>>f = @(x) exp(-x.^2/2*sig_dist);
>>dist = spfun(f,dist)
0 голосов
/ 06 сентября 2011

Как правило, переназначение не разреженных элементов не меняет объем памяти матрицы.Вызовите whos до и после назначения для проверки.

dist = sparse(10, 10);
dist(1,1) = 99;
dist(6,7) = exp(1);
inds = dist ~= 0;
whos
dist(inds) = 1;
whos

Без воспроизводимого примера трудно определить причину проблемы.Может случиться так, что происходит какое-то промежуточное назначение, которое не является редким.Или у вас есть что-то конкретное в вашей проблеме, которого мы не видим здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...