Stuart’s MATLAB Videos

Watch and Learn

Reshape a matrix without using a for loop 70

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…”

70 CommentsOldest to Newest

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, How about this example? 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 512x512 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(, 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(, 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!
dhull replied on : 6 of 70
John, Please check this video: It is important to find out where your bottleneck really is. then it can be diagnosed at the line level. Doug
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 512x512 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 5x5 matrix around each spot and accessing that instead of the entire 512x512 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 5x5 matrix around each individual pixel taken from the entire 512x512 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? Thanks for the advice. 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 118x9. each row represent a particular time/frame.i want to construct a rotation matrix by extracting every row,reshaping the row into a 3x3 matrix for each row.anybody with an idea. cheers
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
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 3x354 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' 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 1x116 matrix.any ideas?
dhull replied on : 24 of 70
@ Charles, Since MATLAB is matrix based, you do not need a for loop to do this. You need array multiplication and array division: x = ((a.*b)-(c.*d))./e Notice the ".*" and "./" instead of "*" and "/". See this video for more info: I just put it up last week. What timing! Doug
Faisal replied on : 26 of 70
dear all i am a beginner in matlab, i have some problem. i have matrix with 500x500 dimension, i want to partition in each have 20x20 dimension so there is have 25 groups matrix. what the code looping in matlab. thx
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 1000x40 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) Appreciate your help. Thanks!
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

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 9511x2, 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!
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
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
        for i=i1:i2
            for j=j1:j2
                if (a==u)
would you please give me an obvious answer
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
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???! thanks in advance.
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 , 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.
dhull replied on : 46 of 70
@elnaz, Let's keep these comments focused on the topics of the video. There are better forums for these questions. http:// Doug
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.
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. How about this modification: 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. How about this modification:


Daniel replied on : 52 of 70
@dhull, Hi Doug, thanks for your quick reply. 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)
without the loop. 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
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
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.
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.
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