В 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 таким образом решит вашу проблему ...