问题描述
|
我创建一个3560 x 3560的稀疏矩阵,0ѭ。然后创建两个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向量将恰好达到我的极限,因此我认为(或更准确地说,希望是)以某种方式不能很好地进行串联...
我是对的还是没有希望(除了优化代码中的其他部分)?
编辑:
应yoda的要求,我正在发布完整代码。
基本上,它要做的是在图的节点之间获得边缘权重的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;
解决方法
编辑:
正如您说的那样,在此操作之前您已经使用了相当多的资源,当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]
应该给您一个错误:
???使用==> vertcat时出错
CAT参数尺寸不一致。
因此,您必须做其他事情。串联不会改变矩阵的稀疏度,即不会从稀疏切换为满。
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
此外,双打的“ 13”矩阵只有〜97 MB,这不会给您“内存不足”错误。
, 处理大型矩阵时:
对于完整矩阵,最好预先分配内存以避免扩展期间的内存复制。请查看原因
稀疏情况更复杂,效率甚至可能比全矩阵扩展要低,因为元素是以压缩方式存储的。设置一个“内部”条目可能会导致大的内存覆盖(请看这里)。
因此,最好事先编辑所有条目并使用sparse()函数创建,而不要调用sparse()然后填充数据。