在MATLAB中稳定准确的
 MATLAB的内置函数accumarray接受函数fun作为第四个参数。 
 A = accumarray(subs,val,sz,fun); 
 这对val中每个具有相同下标的元素的子集适用fun 。 但是文件指出: 
如果
subs中的下标不是按照它们的线性索引进行sorting的,fun不应该依赖于其input数据中值的顺序。
 我们怎样才能实现稳定的accumarray版本,它没有这个限制,但是会保证子集采用与val给出的相同的顺序? 
例:
 subs = [1:10,1:10]; val = 1:20; accumarray(subs(:), val(:), [], @(x)x(end)).' 
 如果accumarray是稳定的话,预期的输出是11:20 。 其实输出是: 
 ans = 11 12 13 14 5 6 7 18 19 20 
我们的实施应该产生:
 accumarrayStable(subs(:), val(:), [], @(x)x(end)).'` ans = 11 12 13 14 15 16 17 18 19 20 
	
 我们可以使用sortrows作为预处理步骤,首先对索引和相应的值进行sorting,如其文档所述: 
SORTROWS使用一个稳定版本的quicksort。
 由于子索引中的下标应该按照它们的线性索引进行sorting,所以我们需要按照逆向词典顺序对它们进行sorting。 这可以通过在使用sortrows之前和之后翻转列顺序来sortrows 。 
 这给了我们一个稳定版本的accumarray的以下代码: 
 function A = accumarrayStable(subs, val, varargin) [subs(:,end:-1:1), I] = sortrows(subs(:,end:-1:1)); A = accumarray(subs, val(I), varargin{:}); 
替代scheme:
 正如路易斯·门多 ( Luis sortrows所build议的那样,也可以用下标来生成线性索引,而不是使用sort 。 
 function A = accumarrayStable(subs, val, varargin) if numel(varargin)>0 && ~isempty(varargin{1}) sz = varargin{1}; else sz = max(subs,[],1); end [~, I] = sort(subs*cumprod([1,sz(1:end-1)]).'); A = accumarray(subs(I,:), val(I), sz, varargin{:}); 
 请注意,我们应该使用1+(subs-1)*cumprod([1,sz(1:end-1)]).' 用于转换为线性索引。 我们省略了+1和-1 , sort的结果仍然是一样的; 这节省了我们几个周期。 
上述哪一种解决scheme更快取决于你的机器和MATLAB版本。 你可以testing例如通过:
 A = randi(10, 1e4, 5); timeit(@()accumarrayStable(A(:,1:end-1), A(:,end), [], @(x)x(1))