在Matlab中理解accumarray

时间:2013-11-01 06:07:33

标签: matlab accumarray

我需要了解accumarray来编写我真正需要的代码。

我试图了解http://www.mathworks.co.kr/kr/help/matlab/ref/accumarray.html

大多数例子都很清楚。

然而,在例2的第一个例子中,我想

(1,2)B的元素应为1

因为

(1,2) = 1st, 2nd of subs
1st, 2nd of vals = 101, 102
sum(diff([101,102]))=1

另外,在例2的第2例中,我想

(1,2)B1的元素应为2而不是-2

,因为

(1,2) = 1st, 3rd of subs
1st, 3rd of vals = 101, 103
sum(diff([101,103]))=2

我也想过

(4,1)B1的元素应该是1而不是-1

因为

(4,1) = 5,6th of subs
5,6th of vals = 105,106
sum(diff([105,106]))=1

我错过了什么?

请更正,我需要深入了解accumarray以编写我自己的代码。

2 个答案:

答案 0 :(得分:2)

我认为意外的值是因为您期望值以与相关索引出现在sub中相同的顺序传递给匿名函数。

然而,accumarray的文档说:

  

注意如果未对subs中的下标进行排序,则乐趣不应该依赖   在输入数据中的值的顺序。

这意味着subs(1 2; 1 2;)的开始可以导致102 101或101 102被传递给匿名函数(因为文档说乐趣不应该依赖于值的顺序。

sum(diff([102 101]))是-1,这是在示例中写入元素1,2的值

val = 101:106;
subs=[1 2; 1 2; 3 1; 4 1; 4 4; 4 1];
B = accumarray(subs,val,[],@(x)sum(diff(x)))

B =

     0    -1     0     0
     0     0     0     0
     0     0     0     0
     2     0     0     0

我不确定为什么当diff的结果明显依赖于传递给它的值的顺序时,为什么Mathworks会选择在示例中使用diff函数。

看起来这个输入值排序是其他输出值与您的期望不同的原因。

答案 1 :(得分:1)

为什么在grantnz的回答中,这里是如何获得可预测的行为。

正如文档所说,"如果subs中的下标没有排序,fun不应该依赖于其输入数据中值的顺序。"因此,为了从accumarray中获得可预测的行为,必须对子进行排序。

对于矩阵中表示(行,列)位置的下标,的含义是,必须根据线性索引对下标点进行排序的元素。因此,对"排序"在2D下标中,您需要对等效的线性索引进行排序。然后,您需要将该订单应用于vals,否则您已将数据加扰。

val = 101:106;
subs = [1 2; 1 2; 3 1; 4 1; 4 4; 4 1];

% convert the subscripts to linear inds and sort them
inds = sub2ind([4 4],subs(:,1),subs(:,2));
[indsSorted,sortingInds] = (sort(inds));

% apply the sorting to val
valsSorted = val(sortingInds);

% convert inds back to subs
[iiS jjS] = ind2sub([4 4],indsSorted);
subsSorted = [iiS jjS];

B = accumarray(subsSorted,valsSorted,[],@(x)sum(diff(x)))

B =

     0     1     0     0
     0     0     0     0
     0     0     0     0
     2     0     0     0

至少它会看到这就是文档中的说明。