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 に答える