Doug's MATLAB Video Tutorials

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

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

Waggy,

How about this example?

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

-Doug

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

@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

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);
    addframe=0;
    for ycount=yfirst:ylast; 
        addframe=0;
        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!

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.

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

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?

Thanks for the advice.

John

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

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

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

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

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

@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

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?

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

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!

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

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

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

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)

Appreciate your help. Thanks!

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

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!

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 ?

@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

@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

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

would you please give me an obvious answer

@Elnaz,

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

Doug

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.

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.

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.

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.

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

@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

@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,
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

@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

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,

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

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

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

@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

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

Kwashie,

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

Doug

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.

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.

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!

Vishnu,

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

Doug

Add A Comment

What is 4 + 10?

Preview: hide

These postings are the author's and don't necessarily represent the opinions of MathWorks.