在我的模型中,要完成的最重复的任务之一是计算数组中每个元素的数量.计数来自一个闭集,所以我知道有X各种类型的元素,并且全部或部分元素填充数组,以及代表"空"单元格的零.数组没有以任何方式排序,并且可能相当长(大约1M个元素),并且在一次模拟期间(这也是数百次模拟的一部分),该任务完成了数千次.结果应该是r大小的向量,数组中的数量也是X如此.r(k)k
因为X = 9,如果我有以下输入向量:
v = [0 7 8 3 0 4 4 5 3 4 4 8 3 0 6 8 5 5 0 3]
Run Code Online (Sandbox Code Playgroud)
我想得到这个结果:
r = [0 0 4 4 3 1 1 3 0]
Run Code Online (Sandbox Code Playgroud)
请注意,我不希望计数零,并且未出现在数组中的元素(如2)0在结果向量(r(2) == 0)的相应位置具有a .
实现这一目标的最快方法是什么?
MATLAB的内置函数accumarray接受函数fun作为第四个参数.
A = accumarray(subs,val,sz,fun);
Run Code Online (Sandbox Code Playgroud)
这适用fun于val具有相同下标的元素的每个子集subs.但文件说明:
如果下标
subs未按其线性索引排序,则fun不应取决于其输入数据中值的顺序.
我们如何实现一个没有这个限制的稳定版本accumarray,但是会保证子集采用与给定的相同的顺序val?
例:
subs = [1:10,1:10];
val = 1:20;
accumarray(subs(:), val(:), [], @(x)x(end)).'
Run Code Online (Sandbox Code Playgroud)
这样做的预计产出将是11:20,如果accumarray是稳定的.实际上输出是:
ans =
11 12 13 14 5 6 7 18 19 20
Run Code Online (Sandbox Code Playgroud)
我们的实施应该产生:
accumarrayStable(subs(:), val(:), [], @(x)x(end)).'`
ans =
11 12 13 14 15 16 17 18 19 20
Run Code Online (Sandbox Code Playgroud)