Vector addressing

1.5.1 Vector addressing

The actual trace clipping in Code Snippet 1.4.1is accomplished by three deceptively simple lines. These lines employ an important MATLAB technique called vector addressing that allows arrays to

be processed without explicit loop structures. This is a key technique to master in order to write efficient MATLAB code. Vector addressing means that MATLAB allows an index into an array to

be a vector (or more generally a matrix) while languages like C and Fortran only allow scalar indices. So, for example, if a is a vector of length 10, then the statement a([3 5 7])=[pi 2*pi sqrt(pi)] √ sets the third, fifth, and seventh entries to π, 2 ∗ π, and π respectively. In clip the function find performs a logical test and returns a vector of indices pointing to samples that satisfy the test. The next line creates the output trace as a copy of the input. Finally, the last line uses vector addressing to clip those samples identified by find.

Code Snippet 1.5.1.

A Fortran programmer new to MATLAB would probablycode clip in this way.

1 function trout=fortclip(trin,amp) 2

3 for k=1:length(trin)

4 if(abs(trin(k)>amp))

5 trin(k)=sign(trin(k))*amp;

6 end

7 end 8

9 trout=trin;

End Code

Code Snippet 1.5.2. This script compares the execution time of clip and fortclip

1 [r,t]=reflec(1,.002,.2); 2

3 tic

4 for k=1:100

5 r2=clip(t,.05);

10 for k=1:100

11 r2=fortclip(t,.05);

12 end

13 toc

End Code

In contrast to the vector coding style just described Code Snippet 1.5.1 shows how clip might be coded by someone stuck-in-the-rut of scalar addressing (a C or Fortran programmer). This code is logically equivalent to clip but executes much slower. This is easily demonstrated using MATLAB’s built in timing facility. Code Snippet 1.5.2 is a simple script that uses the tic and toc commands for this purpose. tic sets an internal timer and toc writes out the elapsed time since the previous tic . The loops are executed 100 times to allow minor fluctuations to average out. On the second execution of this script, MATLAB responds with

25 elapsed_time = 0.0500

1.5. PROGRAMMING FOR EFFICIENCY

elapsed_time = 1.6000 which shows that clip is 30 times faster than fortclip . (On the first execution, clip is only

about 15 times faster because MATLAB spends some time doing internal compiling. Run time tests should always be done a number of times to allow for effects like this.)

A simple blunder that can slow down fortclip even more is to write it like Code Snippet 1.5.3. An even slower version of fortclip

1 function trout=fortclip(trin,amp) 2

3 for k=1:length(trin)

4 if(abs(trin(k)>amp))

5 trout(k)=sign(trin(k))*amp;

6 end

7 end

End Code

This version of fortclip , still produces correct results, but is almost 50 times slower than clip . The reason is that the output trace, trout, is being addressed sample-by-sample but it has not been pre-allocated. This forces MATLAB to resize the vector each time through the loop. Such resizing is slow and may require MATLAB to make repeated requests to the operating system to grow its memory.

Exercise 1.5.1. Create a version of fortclip and verifythe run time comparisons quoted here. Your computer maygive different results. Show that the version of fortclip in Code Snippet 1.5.3 can be made to run as fast as that in Code Snippet 1.5.1 byusing the zeros function to pre-allocate trout .