Matlab выделяет разреженной матрице больше памяти, чем требуется
Предположим, я создаю эту разреженную матрицу, где ненулевые элементы состоят из логических значений 'true':
s = разреженный ([3 2 3 3 3 3 2 34 3 6 3 2 3 3 3 3 2 3 3 6], [10235 11470 21211 33322 49297 88361 91470 127422 152383 158751 166485 171471 181211 193321 205548 244609 251470 283673 312384 318752] правда);
который содержит 20 элементов. Matlab должен выделять не более (4+4+1)*20 = 180 байт памяти (похоже, индексы имеют длину 4 байта). Еще
чья с
говорит, что матрица занимает 1275112 байт в памяти, что является проблемой, так как мне нужно хранить многие тысячи из них.
Есть идеи, почему это происходит?
Ура!
2 ответа
Формат хранения разреженной матрицы в MATLAB представляет собой плотный массив указателей столбцов. Указатель каждого столбца указывает на список ненулевых элементов, и каждому элементу нужен индекс и значение. Таким образом, формула
(max column num) x P + (num nonzero) x (P + S)
где P - размер указателя (8 байтов в 64-битной системе, 4 в 32-битной системе), а S - размер одного элемента. 1 для логического. За вашу проблему я получаю 1275108 или "достаточно близко".
Так что с этим делать? Обратите внимание на драйвер большой памяти: максимальное количество столбцов, из-за плотного массива указателей столбцов. В вашем случае, если вы измените порядок индексов и сохраните транспонирование матрицы, это займет всего 236 байтов (в вашей 32-битной системе).
Я не знаю, почему это происходит, но я знаю, как это исправить. Вот некоторый код, показывающий, что разреженная матрица линейно зависит от количества столбцов.
for k = 1:6
n = 10^k;
a = sparse(n, 100); % keep number of columns constant
tmp = whos('a');
fprintf('%1.0f bytes used\n', tmp.bytes);
end
который производит
416 bytes used
416 bytes used
416 bytes used
416 bytes used
416 bytes used
416 bytes used
сохраняя количество строк постоянным с a = sparse(n, 100);
вместо этого дает
56 bytes used
416 bytes used
4016 bytes used
40016 bytes used
400016 bytes used
4000016 bytes used
Таким образом, чтобы оптимизировать изменение кода s
из 34 x 318752
к 318752 x 34
матрица путем замены первых двух входов sparse
,