Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 21

74 DSP Using MATLAB and Wavelets

function min_val = mymin(x)

% Get an initial guess for the min


min_val = x(1);

% Now go through the rest of the array,


% 1 element at a time
for k=2:length(x)
% if the value at the current offset
% is smaller than our current min, if
(x(k) < min_val)
% ..then update our current min.
min_val = x(k);
end
end

% "min_val" will be returned automatically.

Finally, we can test these solutions.

>> mymin(x1)

ans =

-2

>> mymin(x2)

ans =

-2.6992

>> mymax(x1)

ans =

2
MATLAB 75

>> mymax(x2)

ans =

4.5000

4. Find y1[n] = x1[n] :9x1[n 1], using x1 from above.


Plot y1 (adjusting t as needed).

Answer:
Array t does not need to be adjusted, but we have to be careful about n.
That is, x1[n 1] does not exist when n = 1 (MATLAB will not let us index an
array at location 0). Therefore, we have to start n at 2, so that n 1 is a valid
array value. Also, notice that we use parentheses for MATLAB code, in
place of the square brackets.

for n=2:length(x1)
y1(n) = x1(n) - .9 * x1(n-1);
end
plot(y1)

5. Create y2[n] to be the average of the current and previous two values of
x2[n]. Plot y2.

Answer:
We have to be careful with our starting value for n, as in the problem above.

for n=3:length(x2)
y2(n) = (x2(n) + x2(n-1) + x2(n-2))/3;
end
plot(y2)

6. Create y3[n] = x2[n] y3[n 1].


Plot y3.
What will happen as n approaches in nity?
76 DSP Using MATLAB and Wavelets

Answer:
You have to give y3 an initial value to use.

y3(1) = 0;
for n=2:length(x2)
y3(n) = x2(n) - y3(n-1);
end
plot(y3)

To see what happens when n approaches in nity, we will calculate more


values of y3, past the end of x2's input.

for n=length(x2)+1:200
y3(n) = 0 - y3(n-1);
end
plot(y3)

We see from the plot that it repeats as a sinusoid forever.

7. Make a random function that returns an array of m pseudorandom integers


between a low and high value speci ed. Use the rand function in your
function, and call your solution \myrand." Notice that \myrand" should have
three parameters: the size of the array to return (m), the lowest integer
value it should return, and the highest integer value it should return.

Answer:
From the help rand function, we can see how to use the rand function. For
example, rand(1,8) returns 8 random values between 0 and 1 as an array.
The numbers should range from low to high, so we multiply the values by
(high low). Next, we add low to the results.

low = 10; hi = 90; n = 8;


round(rand(1,n)*(hi-low) + low)

Now we will test it out:

>> x = round(rand(1,100)*(hi-low) + low);


>> plot(x)
>> min(x)
MATLAB 77

ans =

10

>> max(x)

ans =

90

Now we will put it in a function:

%
% Return a vector of m random values
% between low and high.
%
% Usage: result = myrand(low, high, m)
%
function result = myrand(low, hi, m)

result = round(rand(1,m)*(hi-low) + low);

8. With an array of 8 values between 0 and 99 (use \myrand"), write a function


to return the values in sorted order, from lowest to highest.

Answer:

%
% mysort.m
%
% Given an array of numbers, sort them.
% (Use a bubble-sort since it is simple).
%
function sorted = mysort(unsorted)

sorted = unsorted;
done = false;
78 DSP Using MATLAB and Wavelets

while (~done)
done = true;
% Go through the whole array,
% until no switches are made. for
k=2:length(sorted)
% check the current value
% to its left neighbor
if (sorted(k-1) > sorted(k))
% Switch the two temp =
sorted(k); sorted(k) =
sorted(k-1); sorted(k-1) =
temp; done = false;

end
end
end

>> unsorted = myrand(0, 99, 8)

unsorted =

93 91 41 88 6 35 81 1

>> mysort(unsorted)

ans =

1 6 35 41 81 88 91 93

9. Calculate the average from an array, and call your function \average."

Answer:
Yes, this could be done easily with the following one line command:

>> sum(unsorted)/length(unsorted)

ans =
MATLAB 79

54.5000

But in the spirit of doing things for ourselves, here is an alternate solution.

%
% average.m
%
% Find the average of an array of numbers.
%
function avg = average(x)

mysum = 0;
for k=1:length(x)
mysum = mysum + x(k);
end
avg = mysum/k;

10. Write a function to determine if the number passed to it is even or odd.


Your function \evenodd" should print the result to the screen.

Answer:
The ceil and floor functions both return an integer value. If a value divided
by 2 is the same as the ceil or floor of that number divided by 2, then it
must be even.

%
% evenodd.m
% Print whether a number is even or odd.
%
% Usage: evenodd(unsorted_array)
%
function evenodd(value)

if ((value/2) == floor(value/2))
% The number is even.
disp( even );
else
80 DSP Using MATLAB and Wavelets

% The number is odd.


disp( odd );
end

A couple of tests for this function follow.

>> evenodd(7)
odd
>> evenodd(8)
even

One interesting variation on this problem is to try to have it return a boolean


value (true or false) instead of printing to the screen.

11. Find the median value from an array, and call this function \mymedian." (A
median is the value in the middle of a sorted array. If there are two values
in the middle, which happens when the number of elements is even, the
median should then be the average of those two numbers.)

Answer:

%
% mymedian.m
% Return the median value of an array
%
% Usage: m = mymedian(unsorted_array)
%
function m = mymedian(unsorted)

% Sort the array


sorted = mysort(unsorted);
L = length(sorted);
k = ceil(L/2);

% Check to see if there are an even


% or odd number of array elements if
(k == L/2)
% There are an even number.
% Average the middle two numbers
MATLAB 81

m = (sorted(k) + sorted(k+1))/2;
else
% There are an odd number.
% Just get the middle number m
= sorted(k);
end

12. Use the disp and sprintf functions as needed to print the time in a nice
format.

Answer:

time = clock;
disp(sprintf( Current time %2d:%2d:%2d , ...
time(1,4), time(1,5), round(time(1,6))))

2.13 Other Useful MATLAB Commands


Below are some other MATLAB commands that are worth experimenting with.

sprintf( text. integer %d float %f , 3, 2.7)

(Notice that there is no semicolon after sprintf since we want it to appear on the
screen.)

plot(1:length(x), x, r)
break
return
close all
clear all
who
whos
save
load
zplane
fir1
vpa
82 DSP Using MATLAB and Wavelets

Command for a 3D surface plot:

surf

Commands that work with les:

fopen
fread
fwrite
fprintf
fprintf(1, text for a file );
fscanf
fclose

To nd the magnitude and angle of a complex number (convert to polar):


abs (gives magnitude)
angle (gives phase angle)

Commands for working with images:


x = imread( lena.tif , tif );
figure(1)
colormap(gray(256))
image(x)

rgb2hsv() converts Red-Green-Blue to Hue-Saturation-Intensity

Commands to work with sound:


audiorecorder
wavrecord
wavread
wavplay
sound
wavwrite

Time-related functions:

tic / toc
clock
cputime

Wavelet-related commands:
MATLAB 83

wfilters
wavedec
dwt / idwt
dwt2 / idwt2

2.14 Summary
This chapter presents an overview of MATLAB, and demonstrates some useful
com-mands. Matrix operations are important to DSP. In fact, we can implement
trans-forms with matrix multiplications.

2.15 Review Questions


All questions should be answered with MATLAB, unless otherwise noted.

1. Write a MATLAB function to sort an array of numbers in descending order


(highest to lowest).

2. Write a MATLAB function that removes duplicate numbers. That is, given
an array [5, 2, 2, 1, 4, 4, 4], it should return [5, 2, 1, 4]. Assume that the rst
occurrence of a number is kept, such as in the case of the array [7, 3, 8, 3,
7], where your function should return [7, 3, 8].

3. If x = f121, 145, 167, 192, 206g, what is y = 3x 4? Is sum(y) the same value
as 3sum(x) 4?

4. Use the plot command to graph x and y from above. Both x and y should
appear on the same graph.

5. Using MATLAB, plot the sinusoid 2 cos(2 1500t + =2), starting at t = 0 sec-
onds. Be sure to use enough points to make a smooth graph, and only
show a few repetitions.

6. Write a MATLAB function called \myfun" to compute


2
2N 4N + 6
84 DSP Using MATLAB and Wavelets

for any value N . What will be the result if N is an array? If your function
does not work when N is an array, modify it so that it will. It should return
an array of the same length.

7. Floating-point (real) numbers are stored in binary with nite precision on


computers.
a. Using MATLAB, what is the smallest number that we can store? In other
n
words, we can store 1=(2 ) in a variable when n is small, but how large can n
be before the variable is considered zero? (Use the default precision.)
b. What is the largest number that we can store? In other words, we can store
n
2 in a variable, but how big can n be? What happens when n is too large?
c. What about the number 1 + 1=(2n ), how large can n be? Is your answer
the same as in part a? Why or why not?

8. The following MATLAB code should return the magnitudes and phases for
an array of complex numbers. The line marked \problem" actually has two
problems with it.

% This function should return the magnitude and phase.


%
function [mag, phi] = my_function(y)
% input Y is an array of complex numbers

yr = real(y);
yi = imag(y);
for i=1:length(yr)
phi(i) = atan(yi(i)/yr(i)); % problem
mag(i) = sqrt(yr(i)*yr(i)+yi(i)*yi(i));
end

a. The rst problem is the ambiguity discussed in Chapter 1, \Introduction."


Explain what this problem is, and demonstrate it via examples.
b. For the second problem, consider what happens when it processes the
following code, which makes it crash! What is the problem?

y = [ 1+2j, 3j, 4+5j ];


[xm, xp] = my_function(y);
Chapter 3

Filters

We are often interested in manipulating a signal. For example, you might turn up
the volume on a stereo system, boost the bass (low-frequency sounds), or adjust
sounds in other frequency ranges with the equalizer. These examples are not neces-
sarily digital signal processing, since they can also be done with analog parts, but
they do serve as examples of ways we might want to change a signal. Filters allow
us to change signals in these ways. How does a lter function? Architecturally, how
do we make a lter? We will examine these questions and more in this chapter.
Figure 3.1 (top) shows an example signal, the low temperatures from Chapter 1,
\Introduction." In the middle, we see the output from a lowpass lter, i.e., a lter that
keeps the low-frequency information. Notice how much it looks like the original. Also,
you may see that the ltered version has one more value than the original, owing to
the e ect of the lter (the number of lter outputs equals the number of inputs plus the
number of lter coe cients minus one). The bottom graph on this gure shows the
output from a highpass lter, which allows the rapidly changing part of the signal
through. We see that most of the points are around zero, indicating little change.
However, a visible dip around output 5 shows how the big change between input
samples 4 and 5 becomes encoded here.
Shown in Figure 3.2 is the original frequency content of the example input
signal (top). The distinctive pattern seen here owes its shape to the sharp drop
between the end of the input signal and zeros used to pad the signal. The sinc
function can be used to model this phenomenon, and often windows are used to
minimize this e ect by allowing the signal to gradually rise at the beginning, then
slowly taper o at the end. A triangle function is one example of such a window.
In the middle of Figure 3.2, the lowpass impulse response appears, which gives
us an idea of how the lter will a ect our signal. The low frequencies will get through it
well, but the higher frequencies will be attenuated (zeroed out). For example, an

85
86 DSP Using MATLAB and Wavelets

Original
75

70

65

60

550 5 10 15
Lowpass filtered
75

70

65

600 2 4 6 8 10 12 14 16
Highpass filtered
5

100 2 4 6 8 10 12 14 16

Figure 3.1: An example signal, ltered.


Filters 87

input frequency of 60 Hz will still be present in the output, but only at about 10%
of its original strength. We can see this by looking at the spot marked 60 along
the x-axis, and looking up to see the lowpass impulse response is right around
the 10% mark on the y-axis.
The bottom plot on Figure 3.2 has the highpass impulse response, showing the
opposite e ect of the plot above it. This one will allow the high-frequency content
through, but attenuate the low-frequency content. Note that both lters here are not
ideal, since they have a long, slow slope. We would expect that a good lter would
have a sharper cuto , and appear more like a square wave. These lters were made
using only 2 lter coe cients, [0.5, 0.5] for the lowpass lter, and [0.5, -0.5] for the
highpass lter. These particular values will be used again, especially in Chapter 9,
\The Wavelet Transform." For the moment, su ce it to say that having few lter coe
cients leads to impulse responses like those seen in Figure 3.2.

Original frequency magnitude response


1

0.5

0
10 20 30 40 50 60
Lowpass impulse response
1

0.5

00 10 20 30 40 50 60
Highpass impulse response
1

0.5

00 10 20 30 40 50 60

Figure 3.2: The frequency content of the example signal, and low/highpass lters.

Finite Impulse Response (FIR) lters are a simple class of lters that perform
much of the work of digital signal processing. They are composed of multipliers,
88 DSP Using MATLAB and Wavelets

adders, and delay elements. In diagrams showing lters, we show a plus sign
within a circle. Strictly speaking, this is a summation whenever the number of
inputs is greater than two. Architecturally, the summation can be implemented
with an adder tree.
Multipliers are rather complex parts, so sometimes they may be replaced by
simpler parts. For example, to multiply by 8, it is easier to shift the number three
places to the left (since 23 = 8). Of course, the drawback here is that a shift
register is not as exible as a multiplier, and this would only work if the value-to-
multiply-by is always a power of 2.
The delay elements can be thought of as registers, in fact, since registers are
used to store a value for a short period of time, a register actually implements a
delay element. Having two registers in a row has the e ect of delaying the signal by
two time units. In Figure 3.3, we show this for the general case. The output from the
delay unit(s) appears as a time-shifted version of the input. When the second input
value enters a single delay unit, the rst input value would exit, leading to x[n] entering
on the left and x[n 1] exiting on the right. If we consider a group of
k delay units, x[n k] would exit as x[n] enters.

x[n] x[n1]
Delay

x[n] x[n1] x[n2]


Delay Delay

Figure 3.3: A digital signal, delayed, appears as a time-shifted version of itself.

The name \Finite Impulse Response" comes from the way the lter a ects a
signal. An impulse function is an interesting input, where the signal is 0
everywhere, except for one place where it has the value of 1 (a single unit). An
FIR lter's response to this input is nite in duration, and thus it bears the name
Finite Impulse Response lter.

unit impulse function x[n] = 1, when n = 0 x[n] = 0,


when n =6 0
Filters 89

3.1 Parts of a Filter


As mentioned above, there are only a few types of di erent parts that go to make
lters. These are adders (including summations), multipliers, and delay units. In
fact, the In nite Impulse Response (IIR) lter is also made of these basic parts.
To see how lters work, we will start with an adder, Figure 3.4, then work with
a multiplier, Figure 3.5. Think of the adder or multiplier as working on one value
per signal at a time. The index is very important, and being o by one position a
ects the outputs. We will come back to this idea, since a delay unit has this e ect
on the index.

Example:
If a = [1, 2, 3, 4] and b = [2, 1, 2, 1], what is c? See Figure 3.4.

b[n]

a[n] c[n]

Figure 3.4: An adder with two signals as inputs.

Answer:
c[0] = a[0] + b[0], c[1] = a[1] + b[1], c[2] = a[2] + b[2], c[3] = a[3] + b[3]
c[0] = 1 + 2, c[1] = 2 + 1, c[2] = 3 + 2, c[3] = 4 + 1
c = [3, 3, 5, 5]
Thus, we conclude that c[n] = a[n] + b[n].

Example:
If a = [1, 2, 3, 4] and b = [2, 1, 2, 1], what is c? See Figure 3.5.

b[n]

a[n] c[n]

Figure 3.5: A multiplier with two signals as inputs.

Answer:
c[0] = a[0] b[0], c[1] = a[1] b[1], c[2] = a[2] b[2], c[3] = a[3] b[3]
90 DSP Using MATLAB and Wavelets

c[0] = 1 2, c[1] = 2 1, c[2] = 3 2, c[3] = 4 1 c = [2,


2, 6, 4]
Thus, we conclude that c[n] = a[n] b[n].

Example:
If a = [1,2,3,4] and b = [2,1,2,1], what is c? See Figure 3.6.

0.5

a[n] c[n]

0.5

b[n]

Figure 3.6: An example FIR lter with coe cients 0.5 and -0.5.

Answer:
c = [1 0:5 2 0:5; 2 0:5 1 0:5; 3 0:5 2 0:5; 4 0:5 1 0:5]
c = [-0.5, 0.5, 0.5, 1.5]
We see that c[n] = 0:5 a[n] 0:5 b[n].

The delay unit shifts a signal. We assume that any signal value outside of our
index's range is 0, so if a signal is delayed by one unit, we can insert a 0 at the
beginning of it. For example, if we delay signal x by one unit to form signal y,
Figure 3.7, and signal x = [1, 3, 5], then signal y = [0, 1, 3, 5]. How do these two
signals relate mathematically?

x[-1] = 0, y[0] = 0,
x[0] = 1, y[1] = 1,
x[1] = 3, y[2] = 3,
x[2] =5 y[3] = 5
Clearly, y[n] = x[n 1].
Delay units are sometimes shown with \z 1" in place of the \D." The reason
for this will have to wait until Chapter 8, \The z-Transform," but for now, just treat
the two as equivalent.
Filters 91

x[n] D y[n]

Figure 3.7: Signal y is a delayed version of x.

3.2 FIR Filter Structures


Now that we have seen how the parts make a lter, we will demonstrate some FIR
lters and discuss some important characteristics: describing FIR lters by
equations, and how the unit impulse function works with them. The FIR lter
structure is quite regular, and once the numbers corresponding to the multipliers
are known, the lter can be completely speci ed. We call these numbers the lter
coe cients. One unfortunate use of the terminology is to call the lter's outputs
coe cients as well. In this book, \coe cients" will be used to denote the lter coe
cients only.
In Figure 3.8, we see an example FIR lter. Notice that the arrows show
direction as left to right only, typical of FIR lters. Sure, an arrow points from the
input down to the delay unit, but signi cantly no path exists from the output side
back to the input side. It earns the name feed-forward for this reason.
Suppose Figure 3.8 has an input x[n] = [1; 0]. The outputs would be [0:5; 0:5],
and zero thereafter. We nd these outputs by applying them, in order, to the lter
structure. At time step 0, x[0] appears at the input, and anything before this is
zero, which is what the delay element will output. At the next time step,
everything shifts down, meaning that x[0] will now be output from the delay
element, meanwhile x[1] appears as the current input.
0.5

x[n] y[n]

D 0.5

Figure 3.8: FIR lter with coe cients f0.5, 0.5g.

How would you express y[n] as an equation? As we observe from calculating


y[0] and y[1], we really have the same pattern:

y[0] = 0:5x[0] + 0:5x[ 1]


92 DSP Using MATLAB and Wavelets

y[1] = 0:5x[1] + 0:5x[0]:


This generalizes to:
y[n] = 0:5x[n] + 0:5x[n 1]:
A nite and discrete signal's support is simply its index range. Think of a
signal's support as the amount of samples where the signal has a de ned value
(which could also include zero). Suppose that you measure the low temperature
over a week in winter, in degrees Celsius. If the temperatures measured are f2,
1, 0, 1, 0, 2, 0g, the support would be still be 7, even though some of the values
were 0. For analysis, we might assume that all values before the rst sample and
after the last sample are 0.

Example:
For Figure 3.9, if x = f1g, what is y? Express y as an equation.

0.6

x[n] y[n]

D 0.2

Figure 3.9: An example FIR lter with coe cients 0.6 and 0.2.

Answer:
It is easy to see that for an input of 1, the output is 0:6. But we must not stop
there, since this 1 will be the delay unit's output on the next time step. We can
(and should) assume that all future inputs outside of the ones given are zero. On
the next time step, we compute y[1] = 0:2. For the following time step, notice that
the last nonzero input (i.e., 1) no longer appears, and we can stop here.

y = [0:6; 0:2]

To nd the equation, we observe that for input n we have output of 0:6


(current input) + 0:2 (previous input), leading to the generalization:

y[n] = 0:6x[n] + 0:2x[n 1]:


Filters 93

Figure 3.10 shows the general form of the FIR lter, for K + 1 lter coe cients.
(There are K + 1 of them because we start at 0 and count to K.) The number of
lter coe cients is also called the number of taps. By convention, the number of
taps equals the number of lter coe cients. So a lter with coe cients fb0, b1, ...
, bK g has K + 1 taps, since there are K + 1 total lter coe cients. However, it is
said to be of order K. In other words, the order of the lter and the taps express
the same idea, but with a di erence of 1.
With the structure of Figure 3.10 [11], it is possible to determine the output. It
is also possible to determine an equation for the output, which is

y[n] = b[0]x[n 0] + b[1]x[n 1] + b[2]x[n 2] + ::: + b[K]x[n K]:

Notice that whatever index is used for b[ ] is also used in x[n ]. This means we
can represent everything on the righthand side of the equation as a summation.

K
X

y[n] = b[k]x[n k]
k=0

Example:
Given b = [0:1; 0:2; 0:3] and x = [1; 0; 0; 2; 0; 1; 4; 3], what is y?
Answer:
y[n] = x[n 2]b[2] + x[n 1]b[1] + x[n]b[0]
This can be found by noting the above equation, then making a chart.

y[0] = 0 b[2] + 0 b[1] + x[0]b[0]


y[1] = 0 b[2] + x[0]b[1] + x[1]b[0]
y[2] = x[0]b[2] + x[1]b[1] + x[2]b[0]
y[3] = x[1]b[2] + x[2]b[1] + x[3]b[0]
etc.

Plugging in the values of x[n] to form columns multiplied by a scalar:

You might also like