2

This is a question about incrementing one value of a MATLAB array multiple times in the same statement, without having to use a for loop.

I set my array as:

>> A = [10 20 30];

And then run:

>> A([1, 1]) = A([1, 1]) + [20 3]

A =

    13    20    30

Clearly the 20 is ignored. However, i would like it to be included, so that:

>> A = [10 20 30];
>> A([1, 1]) = A([1, 1]) + [20, 3]

would give:

A =

    33    20    30

Is there a function to allow this to be done in a nice, vectorised fashion?

(In reality, the indexing to the array would include multiple indexes, so it could be [1 1 2 2 1 1 1 1 3 3 3] etc., with an array of numbers to increment by (the [20, 3] above) of the same length.)

2 Answers 2

11

What you want to do can be done using the function ACCUMARRAY, like so:

A = [10 20 30];            %# Starting array
index = [1 2 2 1];         %# Indices for increments
increment = [20 10 10 3];  %# Value of increments
A = accumarray([1:numel(A) index].',[A increment]);  %'# Accumulate starting
                                                      %#   values and increments

And the output of this example should be:

A = [33 40 30];


EDIT: If A is a large array of values, and there are just a few increments to add, the following may be more computationally efficient than the above:

B = accumarray(index.',increment);  %'# Accumulate the increments
nzIndex = (B ~= 0);               %# Find the indices of the non-zero increments
A(nzIndex) = A(nzIndex)+B(nzIndex);  %# Add the non-zero increments
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I've got that first one working a treat. I believe there's a transpose symbol missing on the SUBS though - I could only make A = accumarray([1:numel(A) index]',[A increment]); work. I'll do some speed comparisons for the second suggestion once my data's populated.
@Bill: You're right. I forgot that the first input has to be a column vector in this case. In general, the first input has to be an M-by-N matrix where M is the number of values being accumulated and N is the number of subscripts (1 in this case, but more for multidimensional indexing).
@Adrien: Don't be surprised. @gnovice is the only user with a golden Matlab badge. That means that he's both fast and right.
@Jonas: ... or thoroughly addicted to SO. ;)
1

Maybe there's something I don't quite get here, but you're basically trying to add 23 to the first element of A, right? So you can write:

A([1, 1]) = A([1, 1]) + sum([20 3])

Also, if you have an index array, you can write

indexArray = [1 2 2 3 1 1 2 1];
toAdd = [20 3];
A = [10 20 30];

A(indexArray) + sum(toAdd)

ans =
33    43    43    53    33    33    43    33

3 Comments

@Oli Charlesworth: Not sure whether it does now, but I've edited the question right while you were writing the comment.
I think the general case has toAdd the same length as indexArray. So if the contents of indexArray were unique, you'd just do A(indexArray) + toAdd.
@Oli Charlesworth: Ah, ok. Yes, that would make sense as well. I'll update my answer with your comment when it becomes clear that this is what the OP wanted, rather than what @gnovice suggests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.