32位倍频程限制了阵列中的最大元素数。我从源代码重新编译(遵循https://github.com/calaba/octave-3.8.2-enable-64-ubuntu-14.04的脚本),现在有64位索引。
然而,当我尝试使用广播函数执行元素乘法时,我得到error: out of memory or dimension too large for Octave's index type
这是一个错误,还是一个没有记录的功能?如果它是一个错误,有没有人有一个合理有效的解决方法?
重现问题的最小代码:
function indexerror();
% both of these are formed without error
% a = zeros (2^32, 1, 'int8');
% b = zeros (1024*1024*1024*3, 1, 'int8');
% sizemax % returns 9223372036854775806
nnz = 1000 % number of non-zero elements
rowmax = 250000
colmax = 100000
irow = zeros(1,nnz);
icol = zeros(1,nnz);
for ind =1:nnz
irow(ind) = round(rowmax/nnz*ind);
icol(ind) = round(colmax/nnz*ind);
end
sparseMat = sparse(irow,icol,1,rowmax,colmax);
% column vector to be broadcast
broad = 1:rowmax;
broad = broad(:);
% this gives "dimension too large" error
toobig = bsxfun(@times,sparseMat,broad);
% so does this
toobig2 = sparse(repmat(broad,1,size(sparseMat,2)));
mult = sparse( sparseMat .* toobig2 ); % never made it this far
end
修改
好吧,我有一个效率低下的解决方法。它比使用bsxfun
要慢3倍(取决于具体细节)要慢,但它比排除库中的错误要好。希望有一天有人觉得这很有用。
% loop over rows, instead of using bsxfun
mult_loop = sparse([],[],[],rowmax,colmax);
for ind =1:length(broad);
mult_loop(ind,:) = broad(ind) * sparseMat(ind,:);
end
答案 0 :(得分:2)
不幸的答案是,这是一个错误。显然@bsxfun
和repmat
正在返回完整的矩阵而不是稀疏。 Bug已在此处提交:
http://savannah.gnu.org/bugs/index.php?47175