Search All of the Math Forum:
Views expressed in these public forums are not endorsed by
NCTM or The Math Forum.


dpb
Posts:
9,254
Registered:
6/7/07


Re: I'm dense, but...somebody 'splain accumarray() please?
Posted:
Jul 8, 2013 4:45 PM


On 7/8/2013 10:42 AM, Steven_Lord wrote: ...
> Have you used the accumulation behavior of SPARSE in the past?
Nope; I've _rarely_ even used sparse as my problems generally didn't fit that space...
Thanks for the notes, Steven; I'll study them at length and maybe the lightbulb will come on.
BTW, I'm beginning to get mind around accumarray, cellfun, bsxfun and friends but they're all also new toys w/ the release 2012b that didn't have access to before. Plus, of course, anonymous functions and all that entails... :) And, since day job is farming and this is just playing, the amount of time to really devote isn't great...
It does seem to me that the amount of basic explanatory text in relation to the specific syntax has dropped significantly w/ the new help documentation combined w/ the explosion in functionality. It seems like the "Getting Started" documentation could/(should?) probably grow by order of magnitude for such features.
> rows = [1; 1; 1; 2; 3]; > cols = [1; 1; 2; 3; 3]; > values = [1; 2; 3; 4; 5]; > A = full(sparse(rows, cols, values)) > > You'll note that element A(1, 1) is 3 = 1+2. The two elements of values > corresponding to rows == 1 & cols == 1 are added by SPARSE and stored in > A(1, 1). > > http://www.mathworks.com/help/matlab/ref/sparse.html > > "Any elements of s that have duplicate values of i and j are added > together." > > The simplest syntax for ACCUMARRAY does basically the same thing, modulo > specifying rows and columns as a matrix instead of two vectors (since > ACCUMARRAY can create ND arrays out of indices matrices with N columns > while SPARSE is limited to 2D matrices.) > > B = accumarray([rows, cols], values) > > B should be the same as A (since I converted A from sparse to full.) > > When you specify a FUN input to ACCUMARRAY, ACCUMARRAY will use that > function instead of (essentially) using @sum to accumulate the values. > > C = accumarray([rows, cols], values, [], @mean) > > C(1, 1) will be mean([1 2]) in this case, unlike B(1, 1) which was > sum([1 2]). > >> b) I was trying to build an index array of the vector 1:k, w/ each row >> 1:n being one greater than that in the preceding row. I bruteforced >> it w/ repmat() and cumsum() but seems like accumarray ought to be the >> tool. > > Actually, for this I'd use BSXFUN instead of ACCUMARRAY if I understand > what you're describing. > > k = 3; > n = 6; > D = bsxfun(@plus, (1:k), (1:n).') > > D(r, c) is the rth element of (1:n).' plus the cth element of (1:k), > computed without explicitly blowing up (1:k) and (1:n).' into nbyk > matrices. > >> But, all my efforts were totally unsuccessful (and for the most part I >> couldn't even precisely decipher why got what did get)... >> >> So, how to build the following, say... >> >> [1 2 3; 2 3 4; 4 5 6; ...] > > With the correction from your later post, see above. > > As an application example for ACCUMARRAY, let's say you measured a > specific quantity (volume of a song) and binned it into discrete levels. > > n = 100; > stateVector = randi([1 10], [n 1]); % This does NOT go to 11 ;) > > You want to identify how many times the song goes from volume x to > volume y. > > first = (1:n1).'; > second = first+1; > coordinates = stateVector([first, second]); > transitions = accumarray(coordinates, ones(n1, 1)); > > Element (r, c) of transitions will indicate how many times stateVector > contained the vector [r; c], since we'll add the corresponding elements > of ones(n1, 1) together to form that element of transitions. To check, > find those transitions: > > locateTransitions = @(r, c) find(stateVector(first) == r & > stateVector(second) == c); > > The output of locateTransitions(r, c) should be of length transitions(r, > c). >



