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,

Другие вопросы по тегам