2.9. Functions Operating on Vectors

2.9.1. Replacing Loops with Vectorized Code

As mentioned in For Loops and Vectors and Matrices in MATLAB, MATLAB can operate on whole vectors and matrices with a single arithmetic expression. Code that takes advantage of this feature is said to be vectorized. Such code has two benefits over code that uses loops to iterate over the elements of vectors. First and most importantly, writing vectorized code can be simpler and faster than writing code using loops. Secondly, vectorized code runs faster because MATLAB’s interpreter runs less, and optimized, compiled code runs more.

The functions tic and toc are used in the following example in the command window to measure execution times using a personal computer. Running the same experiment on MATLAB Online [1] yields faster results, but demonstrates a similar speed improvement for vectorized code compared to a for loop. More complex expressions yield more speed improvements for vectorized code.

>> y = zeros(1000);
>> tic; for i=1:1000, y(i) = 2^i; end; toc
Elapsed time is 0.043286 seconds.
>> i = 1:1000;
>> tic; y = 2.^i; toc
Elapsed time is 0.003956 seconds.
>> tic; y = 2.^[1:1000]; toc
Elapsed time is 0.000215 seconds.

2.9.2. Vectors as Input Variables

Functions that you write should assume that they may be called with vectors as input variables, even if you intend that they will work with scalar inputs. Thus, unless the function is performing matrix operations or working with a scalar constant, use element-wise operators (Element-wise Arithmetic).

2.9.3. Logical Vectors

Logical vectors are formed by testing a vector with a logical expression. The resulting vector is true 1 (1) where the logical expression is true and false (0) in the other positions. Notice the single & symbol used as an AND operator between logical vector expressions. The symbol is the logical vector OR operator.

>> A = 1:10
A =
    1   2   3   4   5   6   7   8   9  10
>> A > 3 & A < 8
ans =
  1x10 logical array
   0   0   0   1   1   1   1   0   0   0

Next, we use a logical vector to modify the vector A. The mod function gives the result of modulus division (the remainder after integer division). The first expression below shows a logical true (1) where the vector is odd and a false (0) where it is even. The second expression sets A to 0 for each odd value. It does so by first creating a temporary logical vector. Then, each element in A where the logical vector is true is given the new value of 0.

>> mod(A,2) == 1
ans =
  1×10 logical array
   1   0   1   0   1   0   1   0   1   0
>> A(mod(A,2) == 1) = 0
A =
    0   2   0   4   0   6   0   8   0  10

Function

Purpose

Output

any

Are any of the elements true?

true/false

all

Are all the elements true?

true/false

nnz

How many elements are true?

double

find

What are the true indices of the elements?

double

find

The find function takes a logical vector as input and returns a vector holding the indices where the logical vector is true.

The following example uses an integer random number generator to make the sequence of numbers.

>> A
A =
    8   4   6   2   7   3   7   7   8   5
>> find(A > 6)
ans =
    1   5   7   8   9
nnz

Use the function nnz to count the number of true values in a logical array.

>> nnz(A > 6)
ans =
    5

2.9.4. Sinc Revisited

When we looked at the sinc function in Example Control Constructs—sinc, we commented that it would be better to use vectorized code. Notice how a logical vector is used in sinc2 to index row vector t.

% File: sinc2.m
% Sinc function using a logical vector to prevent divide by 0.

t = linspace(-4*pi,4*pi,101);
t(t == 0) = eps;
y = sin(t)./t;
figure, plot(t, y)
hold on
plot([-4*pi 4*pi],[0 0], 'r')
xticks(linspace(-4*pi,4*pi, 9))
xticklabels({'-4\pi','-3\pi','-2\pi','-\pi','0',...
     '\pi','2\pi','3\pi','4\pi'});
title('Sinc Function')
axis tight
hold off
Sinc function (\sin(x)/x) with logical vector indexing

Fig. 2.6 Sinc function (\(\sin(x)/x\)) with logical vector indexing

Footnote: