unexpected accumarray behavior

1 回表示 (過去 30 日間)
Jonathan
Jonathan 2011 年 9 月 29 日
I recently discovered the function accumarray. Example 2 in the doc for this function produced a counter-intuitive answer for me prompting me to investigate. This example is repeated below.
Example 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
Intuitively, the nonzero values should have the same sign. I was surprised to find that this is a built-in function, thus I was unable to inspect the code directly to determine the source of this behavior. I have a more illuminating example (below) that points to the source of the behavior in question but does not fully explain it.
val = [1 2 3 4];
subs1 = [1 2; 1 2; 2 1; 2 1];
subs2 = [1 1; 1 1; 2 2; 2 2];
func = @(x)x(1);
A = accumarray(subs1,val,[],func)
A =
0 2
3 0
B = accumarray(subs2,val,[],func)
B =
1 0
0 3
This shows that, for the subs1 call, the bin for position (1,2) is [2 1] when func is called, while, for the subs2 call, the bin for position (1,1) is [1 2] when func is called.
My Questions: Why is the order in which entries of val are accumulated into bins dependent on the bin location? How can I predict the accumulation order? Can a more consistent behavior be forced?

採用された回答

Oleg Komarov
Oleg Komarov 2011 年 9 月 29 日
From the documentation of accumarray:
Note If the subscripts in subs are not sorted, fun should not depend on the order of the values in its input data.
EDIT
[trash,idx] = sort(sub2ind([4,4],subs(:,1),subs(:,2)));
B = accumarray(subs(idx,:),val(idx),[],@(x)sum(diff(x)));
  4 件のコメント
Oleg Komarov
Oleg Komarov 2011 年 9 月 29 日
See my edit with the example.
Jonathan
Jonathan 2011 年 9 月 29 日
Thank you for your help. I tried this on my example with the results you predicted. I now understand (correctly, I hope) that for the subscripts in subs to be sorted they have to be sorted in ascending order _with respect to linear indices_. this was not at all clear to me before.
Thank you!

サインインしてコメントする。

その他の回答 (1 件)

the cyclist
the cyclist 2011 年 9 月 29 日
Looking at the documentation example (but not yours, yet), it seems to me there is a typo in the documentation. I get B(1,2) = 1, not -1, when I do that accumarray(). That is also the value I expect.
In your example, I do not get the same result for "A" that you do. I get
A = [0 1
3 0];
This is just as I expect. The (1,2) element is the "accumulation" of the values [1 3], where you have defined the accumulation function to be the first element of the vector. Similarly, A(2,1) is the "accumulation" of [3 4]. Again, because you have defined the accumulation function to be taking the first element, that value is "3".
Does that help?
  3 件のコメント
Jonathan
Jonathan 2011 年 9 月 29 日
When I just tried the same on Redhat Linux with 64-bit R2010b, my A and B matrices both show a 1 in the first row. I should note that in my above comment R2010a is 32-bit and R2010b is 64-bit. So, both of the Windows XP tries give a 2 in the first row, while the Redhat try gives a 1 in the first row.
the cyclist
the cyclist 2011 年 9 月 29 日
I get the results I mentioned for both R2011a and R2011b, on Mac OS X (10.6.8).

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeVariables についてさらに検索

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by