2

请建议如何解决这个问题:

nNodes = 50400;
adj = sparse(nNodes,nNodes);

adj(sub2ind([nNodes nNodes], ind, ind + 1)) = 1; %ind is a vector of indices
??? Maximum variable size allowed by the program is exceeded.
4

2 回答 2

3

我认为问题与 32/64 位有关。如果你有一个 32 位处理器,你最多可以寻址

2^32 = 4.294967296e+09

元素。如果你有一个 64 位处理器,这个数字增加到

2^64 = 9.223372036854776e+18

不幸的是,由于对我来说充其量是模糊的原因,Matlab 没有使用这个完整的范围。要找出 Matlab 使用的实际范围,请发出以下命令:

[~,maxSize] = computer

在 32 位系统上,这给出

>> [~,maxSize] = computer
maxSize =
    2.147483647000000e+09
>> log2(maxSize)
ans =
    3.099999999932819e+01 

在 64 位系统上,它给出

>> [~,maxSize] = computer
maxSize =
    2.814749767106550e+14
>> log2(maxSize)
ans =
    47.999999999999993

显然,在 32 位系统上,Matlab 仅使用 31 位来寻址元素,这为您提供了上限。

如果有人能澄清为什么 Matlab 在 32 位系统上只使用 31 位,而在 64 位系统上只使用48位,那就太棒了:)

在内部,Matlab 总是使用线性索引来访问数组中的元素(它可能只是使用 C 风格的数组左右),这意味着您的adj矩阵它的最终元素是

finEl = nNodes*nNodes = 2.54016e+09

不幸的是,这大于 31 位可寻址的最大值。因此,在 32 位系统上,

>> adj(end) = 1;
??? Maximum variable size allowed by the program is exceeded.

而这个命令在 64 位系统上完全没有问题。

您必须在 32 位系统上使用解决方法:

nNodes = 50400;

% split sparse array up into 4 pieces
adj{1,1} = sparse(nNodes/2,nNodes/2);    adj{1,2} = sparse(nNodes/2,nNodes/2);
adj{2,1} = sparse(nNodes/2,nNodes/2);    adj{2,2} = sparse(nNodes/2,nNodes/2); 

% assign or index values to HUGE sparse arrays
function ret = indHuge(mat, inds, vals)

    % get size of cell
    sz = size(mat);

    % return current values when not given new values
    if nargin < 3
        % I have to leave this up to you...

    % otherwise, assign new values 
    else
        % I have to leave this up to you...

    end
end    

% now initialize desired elements to 1
adj = indHuge(adj, sub2ind([nNodes nNodes], ind, ind + 1),  1);

我只是想将所有这些转换成一个适当的类,这样你就可以使用更直观的语法......但这比我现在有时间要多得多:)

于 2012-11-08T06:41:01.557 回答
2
adj = sparse(ind, ind + 1, ones(size(ind)), nNodes, nNodes, length(ind));

这工作得很好......

而且,如果我们必须访问稀疏矩阵的最后一个元素,我们可以通过 adj(nNodes, nNodes) 访问,但是 adj(nNodes * nNodes) 会抛出错误。

于 2012-11-08T06:39:54.867 回答