m_power
m_power

Reputation: 3204

Create array of ones in specified order

I have a position matrix:

positionMatrix = [1 2 3; 1 3 2; 2 1 3];

I want a simple implementation (no for loop) that would generates arrays as follow:

% there are 3 lines in positionMatrix, so it should generates 3 arrays of ones
array 1 should be [1 0 0; 0 1 0; 0 0 1] %from positionMatrix 1 2 3 
array 2 should be [1 0 0; 0 0 1; 0 1 0] %from positionMatrix 1 3 2
array 3 should be [0 1 0; 1 0 0; 0 0 1] %from positionMatrix 2 1 3

The positionMatrix could be M x N (with M not equal to N).

Upvotes: 2

Views: 92

Answers (4)

Luis Mendo
Luis Mendo

Reputation: 112699

It can also be done with ndgrid:

positionMatrixTr = positionMatrix.';
[M N] = size(positionMatrixTr);
L = max(positionMatrixTr(:));
[jj kk] = ndgrid(1:M,1:N);
array = zeros(M,L,N);
array(sub2ind([M L N],jj(:),positionMatrixTr(:),kk(:))) = 1;

As the other answers, this gives the result in a 3D array.

Upvotes: 2

chappjc
chappjc

Reputation: 30579

Here I go with accumarray again. Actually, this one is quite intuitive with accumarray if you consider that the locations in the output are assigned as follows,

  • Column: The values in positionMatrix.
  • Row: The column in positionMatrix.
  • Slice: The row in positionMatrix.

If we call the output matrix map, this is how to apply accumarray:

[slices,rows] = ndgrid(1:size(positionMatrix,1),1:size(positionMatrix,2));
map = accumarray([rows(:) positionMatrix(:) slices(:)],ones(1,numel(rows)))
map(:,:,1) =
     1     0     0
     0     1     0
     0     0     1
map(:,:,2) =
     1     0     0
     0     0     1
     0     1     0
map(:,:,3) =
     0     1     0
     1     0     0
     0     0     1

If needed, you can put the three slices side by side with map = reshape(map,size(map,1),[],1);.

Upvotes: 2

Shai
Shai

Reputation: 114826

Generating the output as a single 3D array

 [M N] = size( positionMatrix );
 mx = max(positionMatrix(:)); % max column index
 out = zeros( [N mx M] );
 out( sub2ind( size(out), ...
         repmat( 1:N, [M 1] ),...
         positionMatrix, ...
         repmat( (1:M)', [1 N] ) ) ) = 1;
out(:,:,1) =
 1     0     0
 0     1     0
 0     0     1
out(:,:,2) =
 1     0     0
 0     0     1
 0     1     0
out(:,:,3) =
 0     1     0
 1     0     0
 0     0     1

if you want each output matrix as a different cell you can use mat2cell

>> mat2cell( out, N, mx, ones(1,M) )

Upvotes: 2

Dennis Jaheruddin
Dennis Jaheruddin

Reputation: 21563

Not sure if it is exactly what you need, but here is something that comes close to the requirements:

positionMatrix = [1 2 3; 1 3 2; 2 1 3];

myArray = [positionMatrix == 1, positionMatrix == 2, positionMatrix == 3]   

This of course assumes that your positionMatrix will grow in the amount of rows, but not (much) in the amount of columns.

Upvotes: -1

Related Questions