1
votes

I'm new to Matlab but I have trawled the documentation and cannot find an answer for what I am looking for.

I've done a number of calculations on a matrix and I have ended up with a list of indices and a list of values which should go in those indices.

for example:

Data =

         0         0         0         0         0         0
    3.7417    3.7417    3.7417    7.0711    3.3166    3.3166
    4.2426    4.2426    3.7417    7.0711    5.3852    7.0711
    7.0711    6.0828    5.3852    7.4833    6.0828    7.6158
    7.1414    7.4833    7.8740    8.7750    7.1414    7.8740

and

Indices =

     1     2     3     4     5     6
     3     3     1     1     6     5
     2     1     2     6     3     4
     4     5     5     2     2     2
     5     4     6     5     1     3

What I want to be able to do is construct a square matrix (of size n based on the largest valued index found in the indices matrix), such that the first column of Indices is used to index the first row of the Result matrix, and the values of Data are put in the corresponding locations of the Result matrix with all places not indexed with data set to 0.

I.e. with the data and indices matrices from above I want the final matrix to look like:

Result =
          0   4.2426    3.7417    7.0711    7.1414         0
     4.2426        0    3.7417    7.4833    6.0828         0
     3.7417   3.7417         0         0    5.3852    7.8740 
     7.0711   7.4833         0         0    8.7750    7.0711
     7.1414   6.0828    5.3852         0         0    3.3166
          0   7.6158    7.8740    7.0711    3.3166         0

(There may be some mistakes with the above as I did it by hand but it should provide an idea of what I'm wanting to do)

Is there a quick an easy way in Matlab to do this? Many function return the indices and I was hoping there would be an easy way to update/construct a matrix using these indices.

Thanks,

Greg

3

3 Answers

3
votes

What you are describing is accomplished like this:

[II,JJ]=meshgrid(1:size(Data,2),1:size(Data,1));
Result = zeros(size(Data,2));
Result(sub2ind(size(Result),II(:),Indices(:))) = Data(:);

Note that getting II through the meshgrid statement is equivalent to II=repmat(1:size(Data,2),size(Data,1),1);.

3
votes

The cleanest way I know how to do it is by creating a sparse matrix based on your data and indices:

[M,N] = size(Indices); indmax = max(Indices(:));
Result = sparse(repmat(1:N,M,1),Indices,Data,indmax,indmax);

Hopefully someone comes along and shows us an even cleaner method.

2
votes

This solution, based on bsxfun, seems to be a little faster that those by @nispio and @chappjc:

S = max(Indices(:));
Result = zeros(S);
Result(bsxfun(@plus, (Indices-1)*S, 1:S)) = Data;