marcman
marcman

Reputation: 3383

repmat and/or transpose into singleton dimensions

Let's say I have a non-empty vector z.

I would like to replicate and shape this vector into a matrix with dimensions [r, c, length(z)].

For example:

z = 1:5;
r = 3;
c = 3;

I am looking for a function that gives me:

ans(:, :, 1) =
    [ 1 1 1 ]
    [ 1 1 1 ]
    [ 1 1 1 ]

ans(:, :, 2) =
    [ 2 2 2 ]
    [ 2 2 2 ]
    [ 2 2 2 ]

...

ans(:, :, 5) =
    [ 5 5 5 ]
    [ 5 5 5 ]
    [ 5 5 5 ]

NOTE: Doing something like

tmp = zeros(r,c,length(z));
tmp = repmat(z, 3, 3, 1);

doesn't work. Instead it returns a 15x15 matrix as

tmp = 
[ 1:5, 1:5, 1:5 ]
[ 1:5, 1:5, 1:5 ]
[ 1:5, 1:5, 1:5 ]

which is not what I want.

Transposing z first doesn't work either.

The only solution I know is to initially set z to be the 3rd dimension of a vector:

z(1,1,:) = 1:5;

Is there more efficient way to do this? Or is this the most effective approach?

COROLLARY: Is there a "transpose"-like function that transposes a vector into singleton dimension? That is, if transpose() shapes row vectors into column vectors and vice versa, is there a function that shapes a row/column vector into singleton dimensions and back?

Thanks in advance!

Upvotes: 2

Views: 336

Answers (2)

Dan
Dan

Reputation: 45752

You can generate that using ndgrid

z = 1:5;
r = 3;
c = 3;
[~,~,out]=ndgrid(1:r,1:c,z)

or using bsxfun and permute

out = bsxfun(@plus,permute(z,[3,1,2]),zeros(r,c));

Upvotes: 3

rayryeng
rayryeng

Reputation: 104504

First permute the vector so that it's a single 3D vector, then use repmat:

z = permute(1:5, [1 3 2]);
r = 3; c = 3;
out = repmat(z, [r c]);

We get:

>> out

out(:,:,1) =

     1     1     1
     1     1     1
     1     1     1


out(:,:,2) =

     2     2     2
     2     2     2
     2     2     2


out(:,:,3) =

     3     3     3
     3     3     3
     3     3     3


out(:,:,4) =

     4     4     4
     4     4     4
     4     4     4


out(:,:,5) =

     5     5     5
     5     5     5
     5     5     5

permute works by shuffling the dimensions of the input vector around. What we're doing here is that we are switching the column values so that they appear in slices of a single 3D vector. We then replicate this 3D vector for as many rows and as many columns as you want.

If permute is confusing, then assuming z hasn't been allocated, you can also do this:

z(1,1,:) = 1:5;

You can then go ahead and use this z with the same repmat syntax that I talked about before.

Upvotes: 3

Related Questions