在accumarray()
关于'subs'的第一个注释,首先出现在MATLAB R14sp3 docs中,说:
注意如果未对subs中的下标进行排序,则乐趣不应取决于其输入数据中值的顺序。
我不清楚什么被认为是分类的。假设:
subs = [1 1
2 1
1 2
2 2];
subs
应按issorted(subs,'rows')
或...... issorted(sub2ind([2 2],subs(:,1), subs(:,2)))
我想依靠:
accumarray(subs,val,[], @(x) x(end))
如果某人还可以提供旧版本的示例/测试(以检查向后兼容性),例如1)是假的,而2)是真的,那将是伟大的。
PS。我对accumarray
的替代品不感兴趣,除非非常简洁且使用相同的subs
和val
。
答案 0 :(得分:3)
好的,我做了一些测试,我认为quote中的“排序”是指 linear indexing 意义上的。 (如果重要的话,我在R2013a上)
要了解accumarray
如何调用指定的函数,我将使用trick将值分组到cellarray中,方法是将fun = @(x) {x}
指定为要应用的函数。
首先让我们创建一些下标和值
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
我在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})
这是我尝试"sorting by rows"的时候:
[~,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})
最后,我们按"linear index"排序:
[~,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})
我将省略长输出,并仅在最后一种情况下报告值已传递给函数 ordered 。所以我得出结论,“排序”标准是基于线性指数。
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以来已被记录,我认为依赖此功能是安全的(我怀疑任何使用这些旧版本的人都希望新代码能够正常工作!)