わかりましたいくつかのテストを行いましたが、引用の「ソート」は線形インデックス付けの意味であると思います。(それが重要な場合、私はR2013aを使用しています)
accumarray
指定された関数がどのように呼び出されるかを理解するために、適用される関数として指定することで値を cellarray にグループ化するトリックを使用します。fun = @(x) {x}
1) 1D インデックス
まず、いくつかの添え字と値を作成しましょう
N = 10; sz = 4;
subs = randi([1 sz], [N 1]);
vals = (1:N)'*100;
次に、ソートされていないインデックスで ACCUMARRAY を呼び出します (複数回)
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs, vals, [], @(x){x});
end
関数に渡される値の順序は任意ですが、複数回実行しても一貫しています。
>> assert(isequal(C{:}))
>> celldisp(C{1})
ans{1} =
800
900
700
ans{2} =
300
ans{3} =
1000
200
100
ans{4} =
400
600
500
fun
これが、渡された値の順序に依存してはならないことをドキュメントが警告する理由です。
ここで、添字を事前にソートすると、次のようになります。
[~,ord] = sort(subs);
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs(ord), vals(ord), [], @(x){x});
end
assert(isequal(C{:}))
celldisp(C{1})
値がソートされた関数に渡されることがわかります。
ans{1} =
700
800
900
ans{2} =
300
ans{3} =
100
200
1000
ans{4} =
400
500
600
2) 2D インデックス
2D添え字インデックスの場合も同じことを試しました。まず、ランダム データから始めます。
%# some 2d subscripts and corresponding values
N = 10; sz = 2;
subs = randi([1 sz], [N 2]);
vals = (1:N)*100;
ソートされていないインデックスの場合は次のとおりです。
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs, vals, [], @(x){x});
end
assert(isequal(C{:}))
celldisp(C{1})
「行による並べ替え」を試みたときは次のとおりです。
[~,ord] = sortrows(subs, [1 2]);
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs(ord,:), vals(ord), [], @(x){x});
end
assert(isequal(C{:}))
celldisp(C{1})
そして最後に、 「線形インデックス」でソートすると次のようになります。
[~,ord] = sort(sub2ind([sz sz], subs(:,1), subs(:,2)));
C = cell(5,1);
for i=1:5
C{i} = accumarray(subs(ord,:), vals(ord), [], @(x){x});
end
assert(isequal(C{:}))
celldisp(C{1})
長い出力は省略し、値が関数 orders に渡された最後のケースのみを報告します。したがって、「ソートされた」基準は線形インデックスに基づいていると結論付けています。
ans{1,1} =
[]
ans{2,1} =
200
600
700
ans{1,2} =
100
300
400
500
1000
ans{2,2} =
800
900
ボーナス:
代わりに次の関数を使用してみてください。
function out = fun(x)
out = {x};
disp('[')
disp(x)
disp(']')
end
関数が予測できない方法で呼び出されていることがわかります。このような動作を確認するには、データのサイズを大きくする必要があるかもしれません...
下位互換性に関する限り、ドキュメントでは、このメモは MATLAB R14sp3までさかのぼって言及されていますが、 R14sp2では言及されていません。2005 年以降に文書化されているという事実を考えると、この機能に頼っても安全だと思います (このような古いバージョンを使用している人は、新しいコードがとにかく機能することを期待しているとは思えません!)