MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn moreOpportunities for recent engineering grads.

Apply Today
Asked by matthew arnott on 22 Apr 2013

I have a matrix lets call it AAA (n by 3 matrix) it looks a bit like the first one below called AAA - the important bit is coloumn 1 which contains numbers between say 1 and 20 such numbers can repeat.

AAA =

1 100 102 4 55 58 11 339 341 3 55 56 2 50 53 11 123 127 14 55 59

I have a second matrix lets call it BBB (20 by 2 coloumn 2 is all zero's for the moment)where I have populated only the first coloumn with the numbers 1 through 20.

BBB =

1 0 2 0 3 0 4 0 ... 20 0

I want to loop through matrix AAA and populate coloumn 2 in matrix BBB with the number in coloumn 2 from matrix AAA next to its appropirate number. At each update I will sum up coloumn 2 in matrix BBB (which i can obviously handle). So in the above example after the first loop matrix BBB will have the number 100 in row 1 coloumn 2. After the second loop it will have the number 55 in coloumn 2 of row 4 after the next loop it will have 339 in coloumn 2 of row 11. As mentioned I will do something after each loop or update but that bit I can handle.

So it will start with something like this

[rows cols] = size(AAA) for i = 1:rows "then not sure if i should be using something like a string compare or a map.objects or what the most appropriate way to continue is"

*No products are associated with this question.*

Answer by Cedric Wannaz on 22 Apr 2013

Edited by Cedric Wannaz on 22 Apr 2013

Accepted answer

If elements of column 1 of `AAA` are really positive integers, you can create `BBB` as a vector and index the element in `BBB` with elements from column 1 of `AAA`. Example:

[rows cols] = size(AAA) ; BBB = zeros(max(AAA(:,1)), 1) ; for k = 1 : rows id = AAA(k,1) ; BBB(id) = BBB(id) + AAA(k,2) ; end

After running this with the `AAA` that you provided, you get

BBB = 100 50 55 55 0 0 0 0 0 0 462 0 0 55

In this code, the line

BBB = zeros(max(AAA(:,1)), 1) ;

preallocates memory (and initializes it to 0's) for a number of elements given by the max value present in column 1 of `AAA`.

Then, the lines

id = AAA(k,1) ; BBB(id) = BBB(id) + AAA(k,2) ;

uses element `(k,1)` of `AAA` as an index in `BBB`. It adds `AAA(k,2)` to the value present at this index in `BBB`. In this solution, the fact that you use elements of the first column of `AAA` as indices in `BBB` makes it so there is no need to have these values stored in a first column of `BBB`. To illustrate, it is enough that row 11 of `BBB` is 462 to get this sum: you can get is as `BBB(11)`; there is no need to have `B(11,:)=[11, 462]`.

I can update this solution if you really need to store elements of column 1 of `AAA` in column 1 of a 2D `BBB`. You would need this if elements of column 1 of `AAA` could not be used as indices, but it would complicate a little the approach, because you would have to find relevant rows in `BBB` using a test and logical indexing or FIND.

matthew arnott on 25 Apr 2013

Thanks - I am not actually accumulating or adding the new numbers on I am just replacing them however there is enough here for me to do what I need. Many thanks

Answer by Teja Muppirala on 22 Apr 2013

There is also the very useful ACCUMARRAY command:

AAA = [ 1 100 102 4 55 58 11 339 341 3 55 56 2 50 53 11 123 127 14 55 59];

N = 20; % Or whatever size you want BBB BBB = [(1:N)' accumarray(AAA(:,1),AAA(:,2),[N 1])]

matthew arnott on 25 Apr 2013

## 0 Comments