Vectors and matrices are at the heart of any Matlab program. Matlab is extremely efficient at doing any operation with these. Vectorizing is the art of transforming a calculation done element by element into an operation on vectors. Here I start a serie of posts on how to vectorize your code.
I had a very good teacher in chemistry when I was in college. He used to say something like this :
To understand chemistry is easy, you just have to understand the very few building blocks on which all this science is based upon. And they don’t take more space than a metro ticket…
Programming is similar, I believe. They are some important principles and all the rest is just addon knowledge built on these principles. If you were to ask me, vectorizing is one of the few Matlab core principles that should sit on this metro ticket. Some day I will make a post to actually draw this metro ticket in detail…
They are many ways to process data in blocks and I want to cover all the tips and tricks I have used in my Matlab life so I will make as many posts as needed on this.
But I guess to start, we should talk about what I consider the most important Matlab operator : the point.
Such a small thing and yet I remember my first days with Matlab. This point was not intuitive. Part of the reason is because I was not taught Mathematic this way.
Let’s assume you have two matrices A and B of the same size. There are two ways to multiply them element by element :
A=rand(100,1); B=rand(100,1); for i=1:100 C(i)=A(i)*B(i); end
Or you could use the magical . operator. The point actually modify the multiplication operator so that it operates element by element, instead of doing a complicated matrix multiplication.
A=rand(100,1); B=rand(100,1); C=A.*B;
Please note that the small point. A.*B is not equal to A*B. Here A*B will give you an error because you are not using properly the matrix multiplication (mathematically correct operations would be A’*B or A*B’ here where ‘ is the transpose). So the point MODIFIES the definition of * to make a multiplication of the entire A and B, element by element.
If you were to ask me, I believe this should be the default behavior of matrix multiplication but I can’t restart Mathematic history…
The point is (I couldn’t resist…) that this is EXTREMELY usefull and is probably one of the simplest form of vectorization you could do. The vectorize version A.*B is much faster than the for loop as Matlab operates on the entire matrix at once via its built-in routines.
In the same way, you can modify the behavior of mathematical operators like / 0r ^.
So you could equally do A./B to divide element by element and A.^B to take the power of each element of A with the corresponding element in B.
Already you can do a lot with this.
Vectorizing is more or less the art of getting rid of for loops. With this point operator, there is a type of for loops that you can easily simplify.
For instance let’s assume you are doing the following :
A=rand(100,1); B=rand(100,1); for i=1:100 if B(i)>0.5 C(i)=A(i)^2; else C(i)=exp(B(i)); end end
Vectorizing this is straight forward if you make use of the point and create an intermediate boolean matrix D.
A=rand(100,1); B=rand(100,1); D=(B>0.5); C=D.*(A.^2)+(~D).*exp(B);
Here D is a matrix of 1 and 0 of the same size of B. For each element in B that is superior to 0.5, there is a 1 or true in the corresponding element in D (and vice versa).
~ is the logical not operator so it is the exact opposite of D.
C is the sum of two matrix which are filled with A(i)^2 when D(i) is 1 or exp(B(i)) when ~(D(i)) is 1.