# Reshape a matrix without using a for loop70

Posted by Doug Hull,

RESHAPE is a very useful function, but it is something that a lot of MATLAB users do not discover until someone is looking at their code and says “Why are you using a for loop for that?” If you know how to use RESHAPE, there is not much to be learned from this video. If you do not know about RESHAPE, well consider me that person looking over your shoulder saying “Why are you…”

Waggy replied on : 1 of 70

Doug,

I have a quick question which is very much pertinent to your phrase “why are you using a for loop for that?” – I may be about to be on the receiving end of that statement!

I have a cell of 10000 strings of which i am identifying relevant strings using strmatch. This returns me the row numers of each match. However i require a logic return of equal dimension (1 = match). The only way i can acheieve this is using a for loop that;

a = strmatch(‘abc’, data, ‘exact’)

for loop = 1:10
b(a(loop)) = 1
end

Problem is, with a huge data set this can take a long time!! Can i speed this process up??

Many thanks,

Waggy

Doug replied on : 2 of 70

Waggy,

list = {‘a’,’b’,’c’,’a’,’b’}
a = strmatch(‘a’,list,’exact’)
b = zeros(size(list))
b(a) = 1

-Doug

Waggy replied on : 3 of 70

Doug,

That’s such a simple way of speeding up the process, thanks!! I have a similar issue involving the HUGE delays of ‘For Loops’. I have a date,hr,min,sec column of data however as it is in the format eg ’04 134911′ xlsread imports as a string. I therefore have to str2num, which give a double eg [04,134911]. I only require the hr,min,sec so i then assign the (1,2) double to my data set. This works fine however is very slow with a 1:3000 ‘for loop’!! Is there a similar method that would improve the efficiency of my code??

Many thanks,

Waggy

dhull replied on : 4 of 70

@Waggy,

Look at the profiler for your code. You may find it is not the FOR loop that is slowing things, but specific functions in the FOR loop.

Please show a simple version of your code, I bet we can figure it out if you do.

Doug

John S replied on : 5 of 70

I have a similar problem as mentioned above: my for loops appear to be really slow. I’ve read online that for loops in matlab are “slow” and “not elegant”. I’ll paste some simplified text below, but essentially I have a video (~20-30 images long) of 512×512 pixel images and want to test each pixel for certain constraints and then save data on the pixels I like. As it is it takes around 30 minutes to go through a 30-frame movie. I have 2 nested for loops doing this:


function d= get_frames(im, startframe)

for frame=framefirst:framelast;

data = get_frames(handles.im, frames);
for ycount=yfirst:ylast;
for xcount=xfirst:xlast;

while dwellcheck==1;

%calculate ~10 parameters (means and stds and such)

if spot>=parameter1 & spot>=parameter2 & spot>constant



after this i check to see if the same spot (x,y) in the next frame (data = get_frames(handles.im, frames+addframe);) also meets these parameters.

when checked all frames, then save spot and go back to searching for next x,y spot.

then go to next startframe.

Any advice? Or am I stuck with the speed? Thanks a lot!

John S replied on : 7 of 70

Ok sweet, I played with the profiler for a while and was able to cut the program time to about half what it was (now it takes about 75 seconds to run through each image of a movie). It turns out having to do the following calculations at each point in a 512×512 pixel image take up all the time (duh):

accstdev = std([datamatrixacc(1,1:5)...
datamatrixacc(2,1) datamatrixacc(2,5)...
datamatrixacc(3,1) datamatrixacc(3,5)...
datamatrixacc(4,1) datamatrixacc(4,5)...
datamatrixacc(5,1:5)]);  %takes up 32% of the time
donstdev = std([datamatrixdonor(2, 2:4) datamatrixdonor(3,2:4) datamatrixdonor(4,2:4)]); %takes up 30% of the time
spotmean3 = mean2(datamatrixacc(2:4, 2:4)); %each of these take up about 5% of the time
spotmean4 = mean2(datamatrixacc(1:5, 1:5));
spotmean1 = mean2(datamatrixdonor(2:4, 2:4));
spotmean2 = mean2(datamatrixdonor(1:5, 1:5));


I saved a lot of time by creating a new 5×5 matrix around each spot and accessing that instead of the entire 512×512 matrix. Any other recommendations? Thanks again.

dhull replied on : 8 of 70

John,

I am glad the profiler is working as you need. Assuming that datamatrixacc is changing each time through the loop (no sense doing those calculations over and over on static data…) I think that things look good here.

In the profiler, it should say how many times each line is being executed. I think that each of these calculations is very quick, but you are doing them an extraordinarily large number of times.

-Doug

John S replied on : 9 of 70

Yeah the “datamatrixacc” is a 5×5 matrix around each individual pixel taken from the entire 512×512 matrix of the image while I run through multiple for loops (“for x=1:512” and “for y=1:512”).

When I googled “how to make matlab faster” one thing they recommended was using vectorization instead of for loops (I guess instead of “for x=1:512” do something like “x=1:512” and call it each time as x(1), x(2), etc.). Will that really make anything faster, or is it going to take a while when I’m going through ~250000 pixels/frame no matter what?

John

dhull replied on : 10 of 70

John,

It is going to take a while. The idea that vectorization is faster than for loops was once true, but with the JIT accelerator, it is mostly stylistic choice at this point.

I do not see a more clever way of doing this kind of operation. Some things are just computationally expensive.

-Doug

dross replied on : 11 of 70

Hi,
i have a concantenated matrix of 118×9. each row represent a particular time/frame.i want to construct a rotation matrix by extracting every row,reshaping the row into a 3×3 matrix for each row.anybody with an idea.
cheers

dhull replied on : 12 of 70

@dross,

Loop through each row, use reshape.

Doug

dross replied on : 13 of 70

i try doing that and it says to me and it gives me this error:
>> for t=1:118;
x(t)=[i_twalk(t,:) j_twalk(t,:) k_twalk(t,:)];

A=reshape (x(t),3,3);
end
??? In an assignment A(I) = B, the number of elements in B and
I must be the same.
i do not know what is wrong.help

dhull replied on : 14 of 70

Dross,

Take a look at this similar problem,

m = rand(3,9)
for i = 1:3
a(:,:,i) = reshape(m(i,:),3,3);
end

a

Notice how a is becoming a 3 dimensional matrix, storing each in its own layer?

Doug

dross replied on : 15 of 70

hello,
is there anyway i can change the dimension of my 3x3x118 rotation array so that i have a 3×354 array but with the elements in the same order ie;for every 3x3x1 element followed by 3x3x2….till 3x3x118? squeeze or reshape??help.
thanks

dhull replied on : 16 of 70

@dross,

This works,

a = rand(3,3,118);
b = reshape(a,[3 354])

You will need to be more clear with the ordering of the elements to explain more. A for loop will certainly work if reshape can not be convinced to.

Doug

dross replied on : 17 of 70

Doug,
thanks a lot for your replies,they are very helpful. i want to calculate the norm for mxn matrix? i have a concantenated matrix which i have to get the norm of each row. any help?

dhull replied on : 18 of 70

dross,

If you have a matrix:

A = [1 2 3; 1 2 3; 1 2 3];
You can get the sub matrices

JustOnes = A(:,1)

Then you can do what ever operations you want with that.

Doug

Karen replied on : 19 of 70

Hello,
I’m a bit of a matlab beginner and I’m hoping someone can help me. I am trying to find a way to change the ordering of where reshape puts the elements when I am going from a single row vector of many elements into an array. This may be one of those cases where I have to use a forloop instead of reshape…

Say I have vector A which is [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]

If I do reshape(A,4,4,1) I get:

1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
But I want to reshape my vector into a matrix in a zig-zag (or snaking) pattern, instead of always starting at the top and moving down. For example, I want to “reshape” (or use some other code) to yield:

1 8 9 16
2 7 10 15
3 6 11 14
4 5 12 13

I need code that will perform this operation on vectors that have many, many elements. Thanks!

dhull replied on : 20 of 70

We were just solving this problem internally for a contest!

Here is the solution:

n = 4
a = reshape(1:n^2,n,n)’
a(2:2:end,:) = fliplr(a(2:2:end,:));
a=a’

http://en.wikipedia.org/wiki/Boustrophedon

Enjoy,
Doug

Charles replied on : 21 of 70

Doug,

I just can’t seem to find any help on ‘for’ loops that actually help, would please take a look at the following and see what help you can offer?

I have 5 [1X1270] matrices that I need to perform the following equation with at each timestep:

x=((a*b)-(c*d))/e

I know it takes a for loop but I can’t get one to work. Matlab gives me an error everytime.

Charles

dross replied on : 22 of 70

hello all,
i have a multidimensional array,1x1x116 and i want to re-arrange it into a 1×116 matrix.any ideas?

dhull replied on : 23 of 70

@dross,

Use the function SQUEEZE to do this.

Doug

Charles replied on : 25 of 70

Doug,

Appreciate your help and I’ll have a looksy at the video.

Thanks again

Faisal replied on : 26 of 70

dear all

i am a beginner in matlab, i have some problem. i have matrix with 500×500 dimension, i want to partition in each have 20×20 dimension so there is have 25 groups matrix. what the code looping in matlab. thx

dhull replied on : 27 of 70

@Faisal,

What is a “groups matrix”?

Doug

asad replied on : 28 of 70

i am the matlab beginer.i have to convert any n*n matrix into a single row vector.plz help

dhull replied on : 29 of 70

M = magic(4)
M(:)’

Doug

crazee replied on : 30 of 70

Hi Doug,

I have a question. I have a 4-D matrix like 1000x2x2x10. I reshape it to a 2-D 1000×40 matrix using:
newmatrix = reshape(oldmatrix,1000,2*2*10)

I wanted to know how is the reshape working? Basically I wanted to know what are the 40 columns in the new matrix corresponding to the original dimensions (2x2x10) of my old matrix. Does it go like:
newmatrix(:,1) = oldmatrix(:,1,1,1)
newmatrix(:,2) = oldmatrix(:,1,1,2)
.
.
newmatrix(:,11) = oldmatrix(:,1,2,1)
.
.
newmatrix(:,21) = oldmatrix(:,2,1,1)
.
.
newmatrix(:,31) = oldmatrix(:,2,2,1)
.
.
newmatrix(:,40) = oldmatrix(:,2,2,10)

dhull replied on : 31 of 70

@”Crazee”

When I am faced with a problem like this, I make a simple test case and see what happens. Look at this:

a = [1 2; 3 4]
A(:,:,1) = a
A(:,:,2) = a+4
A(:,:,:,2) = A + 10
reshape(A,[2,8])

a =

1     2
3     4

A =

1     2
3     4

A(:,:,1) =

1     2
3     4

A(:,:,2) =

5     6
7     8

A(:,:,1,1) =

1     2
3     4

A(:,:,2,1) =

5     6
7     8

A(:,:,1,2) =

11    12
13    14

A(:,:,2,2) =

15    16
17    18

ans =

1     2     5     6    11    12    15    16
3     4     7     8    13    14    17    18

Carolyn replied on : 32 of 70

Hey everyone. I am having a problem that ‘kind of’ relates to this. I have a mtx that is 9511×2, and I am trying to break it up according to the value in the second column, into smaller matrices for each value. for example i have

345 2
367 2
122 2
12 2
345 3
12 3
34 3

i want to end up with a mtx
345 2
367 2
122 2
12 2

and another
345 3
12 3
34 3

etc

so that I can use the each on its own for further manipulation. I’ve tried to used if else statements and such to delete rows, etc. but it is slow, not working, and I keep making loops that run forever (and I’m on a mac so I’m pretty sure I don’t have a break key). I know there has to be an easy way to do this, please help!

dhull replied on : 33 of 70
a  = [11 1; 12 1; 23 2; 24 2]

target = 2;
[vr, vc] = find(a(:,2) == target);

newMatrix = a(vr, :)

niken replied on : 34 of 70

I have a problem related to loop for string

how to make

y = havehavehave……

i used
n=1;
k=’used’;
while k=<5
disp(k)
n=n+1;
end

the result is
have
have
have
heve

how to make the result is y=havehavehavehave ?

dhull replied on : 35 of 70

@Niken,

Create the string and then display it at the end. DISP is going to automatically put a line feed carriage return in there.

Doug

Carolyn replied on : 36 of 70

Thanks Doug! This is exactly what I needed, I appreciate your help!

sangeeta angadi replied on : 37 of 70

i want to divide 16×18 matrix into smaller 3×3 matrices. how to do this

dhull replied on : 38 of 70

@sangeeta

This should show you what you need.

>> a = magic(6)

a =

35     1     6    26    19    24
3    32     7    21    23    25
31     9     2    22    27    20
8    28    33    17    10    15
30     5    34    12    14    16
4    36    29    13    18    11

>> b = a(1:3,1:4)

b =

35     1     6    26
3    32     7    21
31     9     2    22

elnaz replied on : 39 of 70

I have a problem with vectorizing the loops below:


for u=1:13
c=0;
for i=i1:i2
for j=j1:j2
a=I3(i,j);

if (a==u)
x=[i,j];
c=k(norm((x-center)./dim)^2)+c;
end
end
end
q(u)=c/f;
end


dhull replied on : 40 of 70

@Elnaz,

Why do you want to vectorize this? The code looks fine to me, why do you want to change it?

Doug

elnaz replied on : 41 of 70

I think that if I vectorize it, it would be faster.@dhull

dhull replied on : 42 of 70

Have you run it through the profiler to find out where the bottlenecks are? How long is it taking, what is your goal speed? Is this part of a larger project where a speed-up here will matter in the context of the whole project?

Please post code that can be copied and pasted and works so we can see it. Your code above is using variables of unknown composition, so we can not really do much with it.

elnaz replied on : 43 of 70

hi everyone.I have a problem . I have encountered with aproblem. I want to know how long it takes for a specified mfile to be executed so I use the ” tic toc” command but it does not give a correct result. I mean it is different from the time that I measure by my own watch. for example it takes less than a second according to my watch but the “tic toc” command gives 12 seconds.I am mixed up. can anyone explain this problem for me???!

dhull replied on : 44 of 70

@elnaz

Is your code short enough to be posted? If not please e-mail it to me so I can reproduce it.

Doug

elnaz replied on : 45 of 70

oh, I have another question ,too.do you know any command which draws a rectangle or square by using the center , length and width of the rectangle. I am working on object tracking so I need a simple command to plot a rectangle arround the object.

Obi replied on : 47 of 70

Hi Doug,
The reshape function when used to transform an n x m matrix to an (nm) x 1 vector reorders column-wise. How do i get it to perform the transformation row-wise?

if a = 1 2 3
4 5 6
I would like [1 2 3 4 5 6] rather than [1 4 2 5 3 6]

Thanks.

dhull replied on : 48 of 70

@obi,

Transpose first. (‘ after matrix transposes)

Doug

Daniel replied on : 49 of 70

Hi,
I have a vector x=[2 4 6].
How would you create a 3,3,3 matrix with
A(:,:,1)=[2 2 2; 2 2 2; 2 2 2]
A(:,:,2)=[4 4 4; 4 4 4; 4 4 4]
A(:,:,6)=[6 6 6; 6 6 6; 6 6 6]
Any hints?

Best wishes
Daniel

dhull replied on : 50 of 70

@Dabiel,

I think you just did.

A(:,:,1)=ones(3)*x(1);
A(:,:,2)=ones(3)*x(2);
A(:,:,6)=ones(3)*x(3);

Doug

dhull replied on : 51 of 70

@Dabiel,

I think you just did.


A(:,:,1)=ones(3)*x(1);
A(:,:,2)=ones(3)*x(2);
A(:,:,6)=ones(3)*x(3);



Doug

Daniel replied on : 52 of 70

@dhull,
Hi Doug,
Of course i do not want to write that explicitly. What if x is 1 by 10?
I hope there is a neat repmat/reshape combo which i can use.
Daniel

dhull replied on : 53 of 70

@Daniel,

I do not see the mapping from elements of x to a specific layer of A. They were going to layers 1,2 and 6. If there is no pattern, you have to do this manually.

Doug

Daniel replied on : 54 of 70

In other words:
I want

x=[2 4 6]
for k=1:numel(x)
A(:,:,k)=ones(numel(x)).*x(k);
end


without the loop.
Daniel

Daniel replied on : 55 of 70

Sorry, Doug!
I have a typo in #49, A(:,:,6) is A(:,:,3)
Daniel

dhull replied on : 56 of 70

@Daniel,

There might be some crazy, convoluted way to do this without a loop, but the loop is clear and efficient (especially if you pre-allocate) Why bother making something more obscure and hard to read?

Doug

Daniel replied on : 57 of 70

I think it looks sexier. :-)
Daniel

dhull replied on : 58 of 70

@Daniel

You can comment out something like this:

% A = reshape(reshape(transpose(magicalReshape(x,-4,3)),4,-10),-3,3.14);
% The above line works, but so that you Noobs can maintain this, I will write it out with a non-guru type of loop.

You get to feel clever and have maintainable code!

-Doug

david replied on : 59 of 70

how to convert [1 2 3 4] to
[1 1 3 3
2 2 4 4]?

Loren replied on : 60 of 70

David-

Something like this should work:

A = 1:4;
B = reshape(A,2,2)
C = B(:,[1 1 2 2])


–Loren

Jerry replied on : 61 of 70

Hi Doug,

I also have a question about row-wise transformation.
suppose a=[ 1 2 3 4; 5 6 7 8], if I want to get
b=[1 2; 5 6; 3 4; 7 8]. Is there a simple way of using reshape without for loop? Thanks in advance.

Jerry

dhull replied on : 62 of 70

@Jerry,

There might be some clever way to do this without for loops, but it would be confusing and non-intuitive. Just use a clear and easy loop to do this.

Doug

Kwashie replied on : 63 of 70

I have a 1 x 6 matrix which i need to add to a 1 x 12 matrix after which i have to multiply by a 1 x 18 matrix. Can you please guve me an idea on how i con do that. Thanks

dhull replied on : 64 of 70

Kwashie,

What does it even meant to do these operations? I can not understand what that would even look like.

Doug

dan replied on : 65 of 70

hello lets say i have
a = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
instead of reshape it up n down which will result to this
1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20

i want it to be like these
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20

is it possible? Thanks in advance.

dhull replied on : 66 of 70

@dan,

Transpose it first, then reshape.

Doug

dan replied on : 67 of 70

Do you mean this?

a = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
b = transpose(a);
c = reshape(b,2,10)

I still get the up and down result. Sorry I’m very new to matlab. Hope you can help.Many many thanks in advance.

dan replied on : 68 of 70

Hi, sorry to bother you i think i got it. Thank you for you wonderful tips!

Vishnu replied on : 69 of 70

Doug, I have a quick question, the answer to which I couldn’t find anywhere. Does reshape work the exact same way each time you do it? For example, I want to reshape a 3D matrix to a single vector. However, each dimension means something to me and I need to do this for many 3D matrices and want the entries in the final vector to correspond to the same dimensions. So does reshape go through the 3D matrix in the same order every time I reshape a 3D matrix? Sorry if this is a dumb question.. I’m a matlab beginner. Thanks for your time!

Doug replied on : 70 of 70

Vishnu,

There is no randomness in reshape. It is deterministic, and will always give the same results for the same inputs.

Doug

What is 4 + 5?

Preview: hide