matlab: недостаточно памяти при конкатенации разреженной матрицы с вектором - PullRequest
1 голос
/ 12 июня 2011

Я создаю разреженную матрицу 3560 x 3560, A. Затем я создаю два вектора 1 X 3560, S и T. Когда я запускаю следующий код (который объединяет S и T как строки в A, а затем также как столбцы в A)

A=[A;S;T];
S=[S 0 0];
T=[T 0 0];
A=[A, S', T'];

Последняя строка выдает ошибку out of memory. Я предполагаю, что у меня заканчивается память, так как у меня хранятся другие переменные, но мне кажется странным, что добавление двух векторов 3560 будет точкой, в которой я точно достигну своего предела, поэтому я думаю (или, точнее, желаю думать) что каким-то образом конкатенации не сделаны умным способом ... Я прав или нет надежды (кроме оптимизации других частей моего кода)?


EDIT: По просьбе йоды выкладываю полный код. По сути, он получает N X N матрицу весов ребер между узлами графа и добавляет два вектора, которые будут действовать как источник и приемник при вычислении максимального потока.

nbr_sim(nbr_sim<0.8)=0;
A=sparse(size(nbr_sim,1)+2,size(nbr_sim,2)+2);
nelements=size(nbr_sim,1);
A(nbr_sim>0)=nbr_sim(nbr_sim>0);
clear nbr_sim;

S=abs([1 0 0]*n);
T=abs([0 1 0]*n);


A(1:nelements,end-1)=S';
A(1:nelements,end)=T';
A(end-1,1:nelements)=S;
A(end,1:nelements)=T;

Ответы [ 2 ]

2 голосов
/ 12 июня 2011

РЕДАКТИРОВАТЬ:

Поскольку вы говорите, что перед этой операцией вы использовали значительные ресурсы, вполне вероятно, что вы близки к критической точке, когда MATLAB выдает ошибку нехватки памяти.

Помните, что когда вы нарастаете матрицы на лету либо путем конкатенации, либо путем индексации вне диапазона, MATLAB создает копию матрицы в памяти.Таким образом, вы используете не только ресурсы для этой дополнительной строки, но и копию всей матрицы!

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

clear
a=rand(2*10^9+1,1); %#create a large array
whos a
  Name               Size                  Bytes  Class     Attributes

  a         2000000001x1             16000000008  double 

%#Now repeat the same, but by growing the array by one element
clear
a=rand(2*10^9,1);
a=[a;0];

??? Error using ==> vertcat
Out of memory. Type HELP MEMORY for your options.

Итак, вы видите, что, хотя MATLAB может создавать матрицу из 2*10^9+1 элементов за один раз, при попытке создать массив одинакового размера, добавив один элемент к 2*10^9 элемент вектора, ему не хватает памяти.


Если S и T, как вы говорите, являются векторами столбцов, то A=[A;S;T] должно выдать ошибку:

???Ошибка при использовании ==> измерений аргументов CAT vertcat не согласованы.

Так что вы должны делать что-то еще.Конкатенация не изменит разреженность матрицы, т. Е. Она не переключится с разреженной на полную.

A=sprand(3560,3560,0.01); %#test matrices
S=rand(3560,1);
T=rand(3560,1);

B=[A,S,T]; %#join the columns
issparse(B)

ans =

     1

Более того, матрица двойных чисел 3560x3560 составляет всего ~ 97 МБ, что не должно давать вамошибка "недостаточно памяти" ...

0 голосов
/ 11 марта 2014

При работе с большой матрицей:

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

Разреженный случай более сложен и может быть даже менее эффективен, чем расширение в полной матрице, поскольку элементы хранятся в сжатом виде. Установка «внутренней» записи может вызвать большие перезаписи памяти ( смотрите здесь ).

Так что вам лучше отредактировать все записи заранее и создать с помощью функции sparse (), а не вызывать sparse (), а затем дополнить данные.

...