I am going to talk about arrays today. I know most of you know all about this, but keep reading. The beginning is for beginners but in the end I will talk about some advanced optimization you can do when using Arrays.

One of the first thing you will do in Matlab is to create an array. One can type in :

X=[1 2 3 4 5]

This will create a line or a ROW element.

You can also create a COLUMN of elements this way :

Y=[1;2;3;4;5]

Now, even if X and Y are 1D elements, they can be accessed through their 2D coordinates, because X is a ROW and Y is a COLUMN.

In 2D matrices, to access elements, you just need to type in X(1,2) where 1 is the ROW number and 2 the COLUMN number.

This is why X(1,2) will work whereas X(2,1) will kick you out. Similarly Y(2,1) will work and Y(1,2) not.

Let’s now suppose we have a real full 2D matrix like :

Z=[1 3 5;2 34 9;4 90 1]

Z is a 3 by 3 matrix so you can access, for instance, 4 using Z(3,1). If you remember my crash course on Matlab, lesson 1, you know that you can access a complete row using the colon, like so :

Z(2,:)

To get a column, just do :

Z(:,3)

So far, so good. There are some important things to know about 2D Matrix (or higher dimensions). The rows and columns are NOT equivalent stricly speaking. Indeed when you create a 2D array in C, you need to reference each element to its memory address. As a result, for a 2D array, you need to allocate MxN elements in memory (where M is the number of rows and N of columns). Since memory is a linear object, you need to choose how you organize these elements. You have two options “Row major order” or “Column major order”. Matlab, as a faithfull son of Fortran, chose the Column major order option.

You can actually see this in action by doing :

Z(:)

Here you are asking matlab to spit out all the elements of Z in their native order. Matlab should tell you :

>> Z(:) ans = 1 2 4 3 34 90 5 9 1

First, please note that we have a column here. Expected, I told you Matlab was a Column major. Then you will notice for sure that, Matlab has ordered all the elements along the columns first. This means that if you were to draw the real object number, you would write this way :

1 4 7

2 5 8

3 6 9

In effect, this means that Z(3,1) is contiguous to Z(1,2) in memory exactly as Z(2,1) is contiguous to Z(1,1).

The first thing to remember from this is that this can be quite handy to vectorize your code. All arrays can be seen as a single column of numbers.

But what happen with 3D matrix?

Let’s find it out.

>> R=rand(2,2,2) R(:,:,1) = 0.1190 0.9597 0.4984 0.3404 R(:,:,2) = 0.5853 0.7513 0.2238 0.2551 >> R(:) ans = 0.1190 0.4984 0.9597 0.3404 0.5853 0.2238 0.7513 0.2551

rand is a convenient function that create a random matrix. rand(2,2,2) is a 2x2x2 3d matrix.

As you can see, Matlab first go along the column, then along the row and then go to the third dimension. I am sure you can generalize to higher dimensions yourself.

Now that we know how arrays are organized in memory, I just need to tell you one last thing but an important one. It is actually faster to successively access elements that are contiguous in memory. In other words, this :

X=rand(100,100,2000); for i=1:100 for j=1:100 X(i,j,:)=10*X(i,j,:); end end

is much slower than this :

X=rand(100,100,2000); for j=1:100 for i=1:100 X(i,j,:)=10*X(i,j,:); end end

I will let you all try it out with the profiler. But it is 2 times faster on my machine. Why is this useful instead of just vectorizing your code?

Sometimes, you can’t vectorize. And when dealing this movies, for instance, this technique can be worth the try.

Definitely did not know about this! I’ll have to try it the next time I need to code an i + j for loop! THANKS!

As a consequence would you model a set of time signals as a T*K matrix or a K*T matrix where T is the number of time frames and K is the number of signals?

Is there a nice little rule derived from the fact that Matlab works with column major order?

It depends how you need to access it. If you need to access it along time, than K*T is probably better as you would always get entire column at a time which are contiguous in memory.

This is awesome. I am currently working on a stochastic reaction-diffusion simulation which requires a lot of calculations. Using this approach increased the execution speed of my code by approximately 75%.

Thank you for your great blog

woops. I meant to say that the execution time was 75% faster

.

Great last tip. Sounds promising and makes sense. However, did not show significant differences in my matlab test. Any clue? Did matlab do some optimization automatically?

Possibly, Matlab is a moving target. Did you try with very large arrays?

I reproduced “much slower” on R2016a with your X. And I added a third case, which is still faster.

See http://uk.mathworks.com/matlabcentral/answers/301008-vectorized-code-slower-than-loops#answer_233665

Thanks for all the tips along this amazing blog !

I think there is a mistake here :

“As you can see, Matlab first go along the column, then along the row and then go to the third dimension. I am sure you can generalize to higher dimensions yourself.”

Matlab seems to be a ‘last dimension major’. In the 3D cases, the operator ‘:’ is equivalent to

for k=1:…

for j=1:…

for i=1:…

A(i,j,k)

end

end

end

And I have checked with the profiler (thanks a lot for this tool !), it’s faster to scan the 3D-array in this order than any other order.