Sei sulla pagina 1di 122

Class 25 (Resampling)

Resampling Discrete-time signals


Overview
Across many situations in signal processing, controls, and communications, we may want to change the rate
at which we had originally sampled a discrete-time signal. We refer to this process as resampling. In this
lecture, we talk about downsampling (also known as decimation), decreasing the sampling rate by an
integer factor N, andupsampling (also known as interpolation), increasing the sampling rate by an integer
factor M.
Downsampling

Original signal x[n].

x[n] downsampled by 2.

x[n] downsampled by 3.

DTFT of x[n].

DTFT of x[n] downsampled by 2.

DTFT of x[n] downsampled by 3.

DTFT of x[n] downsampled by 3 (with anti-aliasing filter).

Downsampling by 2
The basic downsampling operation is downsampling by 2. Mathematically, downsampling a signal x[n] by
2 is defined by
xd[n]=x[2n].
Notice that this is essentially a ``time-shrinking'' of the discrete-time signal by 2 (and
dividing the amplitude by 2). The difference between this operation in discrete-time and
continuous-time though is that we must now throw away information. That is, we now
only take every other sample.

As with continuous-time signals, if we shrink in time, we will stretch in frequency (and devide the
amplitude by 2). However, since we work with discrete-time signals, we will ``periodically stretch'' in
frequency. That is, we will stretch the frequency content from to around =0, we will stretch the
frequency content from to 3 around 2, etc... Therefore, we will stretch each period in the frequency
domain signal around the points 2k, where k is some integer.
Downsampling by N
We can extend the concepts above to downsample by any integer number N. Downsampling a
signal x[n] by N is defined by
xd[n]=x[Nn].
That is, we keep only every N-th sample from x[n]. In frequency, we again see the same
``periodic stretching,'' except we now stretch by a factor of N(and we divide the
amplitude by N).
Aliasing from downsampling
As with regular sampling, we can experience aliasing from downsampling (reducing our sampling rate).
Graphically, if the frequency content is stretched too much, we will get overlap (aliasing) and we will no
longer be able to perfectly reconstruct the original signal. If the maximum frequecy stretches beyond =,
we will get aliasing.
For example, consider a signal x[n] (X() in the frequency domain) with a maximum frequency (within
the range of and ) equal is 3/4. If we downsample x[n] by 2, the new maximum frequency for the
period around =0 will be 3/2. Similarly the new minimum frequency for the period around =2 will
be /2. These frequency components will add together, distort the signal, and create aliasing.
Anti-Aliasing
To counter aliasing, signals are often filtered using an low-pass, discrete-time anti-alaising filter before
downsampling. To ensure that aliasing does not occur, the cut-off frequency of an ideal filter would have to
be c=/N, where N is the downsampling factor.

Upsampling

Original signal x[n].

x[n] upsampled by 2 (without


filtering).

x[n] upsampled by 2 (with

filtering).

DTFT of x[n].

DTFT of x[n] upsampled by 2 (without


filtering).

DTFT of x[n] upsampled by 2 (with filtering).

Upsampling by 2
Upsampling is the opposite of downsampling. The basic upsampling operation is upsampling by 2.
Mathematically, upsampling is a little more complicated than downsampling, but can be thought of as
"stretching" the signal in time (i.e., x[n/2]). The difference between this operation in discrete-time and
continuous-time though is that by "stretching" the signal, we now have more samples than we have data
points.

To handle this challenge, we follow two steps. First, we set any new samples to zero. That is, for
upsampling by 2, we add one zero between every sample in x[n]. This "stretches" the signal in time. As a
result, we "shrink" in frequency. However, since we work with discrete-time signals, we will ``periodically
shrink'' in frequency. When add a zero between every sample, two things happen.
1. First, the periodic frequency domain's period shrinks by a factor of 2. That is, if
the DTFT is periodic with a period of 2, the upsampled signal will have a period
of .
2. Second, the content in each period frequency-shrinks by a factor of 2.
After we add zeroes between every sample in x[n], we apply an discrete-time, ideal low-pass filter with a
cut-off of /2 and a gain of 2 to remove frequency content higher than =/2 (within the period
between and ). In frequency, filtering provides a now shrunken version of the original signal
between = and . In time, filtering determines the values for the zeros that we previously inserted into
the signal.
Note that if we now downsampled the result by 2, we would stretch the frequency domain and get the
original signal back.
Upsampling by M
We can extend the concepts above to upsample by any integer number M. When upsampling a
signal x[n] by M, we add M1 zeros between each sample. In frequency, we again see the same ``periodic
shrinking'' effect, except we now shrink by a factor of M. We then apply an ideal low pass filter of with cutoff of =/M and a gain of M. Downsampling the result by M yields the original signal.

Upsampling with an emphasis on the frequency


domain
By: Michael Deufel

1. Introduction
2. Derivation
3. Graphical Example in the Frequency Domain
4. Conclusion
5. Questions/ Comments

1. Introduction
The purpose of Upsampling is to manipulate a signal in order to artificially increase the sampling
rate. This is done by...

Discretize the signal


2.
Pad original signal with zeros
3.
Take the DTFT
4.
Send through a LPF (low pass filter)
5.
Take the inverse DTFT to return to the time
domain
1.

We will overview the whole process but focus on the effect upsampling has in the frequency domain

2. Derivation

x1[n]
now we "pad with zeros" to define x2[n]
x2[n]={x1[nD],0,ifnDZelsef
note: D must be an integer greater then one
x2[n] can also be defined by
x2[n]=kx1[k][nkD]
Taking the DTFT of x2[n]
X2()=n(kx1[k][nkD])ejn)
We will start with discrete signal

switching the order of the summations you can get

X2()=kx1[k](n[nkD])ejn)
where,

n[nkD])ejn=ejkD
therefor,

X2()=kx1[k]ejkD
This is just the DTFT of the original signal scaled by D

LPF with filter that has cutoffs at


Lastly to return to time domain take the Inverse DTFT of
signal

y2[n]

and

to get Y2()

Y2() to get your up sampled

3. Graphical Example in the Frequency Domain


Note: The gain in this example is 1

X1(w) which is periodic with period 2


The second graph shows the signal X2(W) which is also periodic with period 2 but contains
The first graph shows the signal

unwanted repetitions of the signal


The third graph shows the Final Signal after it has been passed through the LPF to remove the
unwanted repetitions
In the second graph it is obvious why the signal must pass through a LPF, because the expansion in
the time domain resulted in compression in the frequency domain and that has caused the signal to

repeat itself with in the range of

[,] and this would cause the reconstruction of the signal to

be inaccurate

4. Conclusion
Upsampling is an effective way to reduce time between samples of a signal without resampling the
original signal.

5. Questions/Comments
You can post questions and comments on this page, Thanks questions/comments

References
- ECE 438 Class notes Prof. Mireille Boutin

Introduction
With microprocessors becoming ever increasingly faster, smaller, and cheaper, it is preferable to use
digital signal processing as a way to compensate for distortions caused by analog circuitry. One area
that this can be applied is in signal reconstruction, where a low pass analog filter is used on the
output of a digital-to-analog converter to attenuate unwanted frequency components above the
Nyquist frequency.
The problem with analog low pass filters is that higher the order, the more resistors, capacitors, and
op-amps are required in its construction. More circuit components means more circuit board space,
which is a precious commodity with today's hand-held devices.
Here, it will be explained how up-sampling can be used to relax requirements on analog low pass
filter design while decreasing signal distortion.

A Representative DT Signal
For this discussion, a representative signal

x(t) will be used to demonstrate the process of signal

reconstruction. We will look at the signal in the frequency domain, as shown in the plot below:

X(f) has a triangular shape and is band-limited by fmax. By the


Nyquist-Shannon Sampling Theorem, the sampling frequency fs1 must be greater than 2fmax. For
this discussion, assume fs1 is just slightly greater than 2fmax.
Now, we are going to sample x(t) with an impulse train with period Ts1=1/fs1 and convert to a
discrete time signal. This has the affect of scaling the magnitude axis of X(f) by 1/Ts1 and the
frequency axis by 2Ts1, and then repeating the result every =2. This yields the following
plot Xd():
As seen in the plot, the signal

Without Up-sampling
First, consider the process of signal reconstruction without up-sampling. The following diagram
shows the process:

The first block is a digital-to-analog converter. This converts the discrete time signal to a continuous
time signal. This has the effect of scaling the magnitude axis by
This yields the following plot

Ts1 and the omega axis by 12Ts1.

W1(f):

The next step is to use an analog low pass filter to remove all frequency components above 12Ts1.

W1(f) is that the frequency gap for which the analog filter has to
transition from low attenuation to high attenuation is 1Ts12fmax.
The important note to take from

With Up-sampling
Now, consider the process of signal reconstruction with up-sampling. The following diagram shows
the process:

N operator, where NN. This inserts N1 zeros between each


point in the time domain. In the DTFT domain, this has the effect of scaling the omega axis by 1/N.
This yields the following plot U().
The first block is the up-sample by

N and cutoff
frequency fc=N. This removes all extra DTFT components not centered around 2k,kZ, and
scales the magnitude axis by N. This yields the following plot V():
The next block is an interpolator, which is a discrete-time low pass filter with gain

Next is the digital-to-analog converter. This is the same process as in the previous section, but now
the sampling period is

Ts2=Ts1N due to the up-sampler. This yields the following plot W2(f):

The final step is to use an analog low pass filter to remove all frequency components above 12Ts2.

W2(f) is that the frequency gap for which the analog filter has to
transition from low attenuation to high attenuation is now NTs12fmax.
The important note to take from

How Analog Filter Design is Affected


By comparing the results of the previous two systems (with and without the upsampler), it can be
seen that adding an up-sampler to the system increases the frequency gap for the analog low pass
filter from 1Ts12fmax to NTs12fmax. A larger N results in a wider frequency gap, which means
that the analog filter can be of a smaller order and still maintain minimal distortion. The advantage
of this method is that up-sampling and interpolation can be done in an existing microcontroller via
software, which requires virtually no extra circuit board space. This would prove especially
beneficial in devices such as high quality hand-held mp3/CD players.

Octave/Matlab - Signal Processing

Home : www.sharetechnote.com

In this page, I would post a quick reference for Matlab and Octave. (Octave is a GNU program which is designed to
provide a free tool that work like Matlab. I don't think it has 100% compatability between Octave and Matlab, but
noticed that most of basic commands are compatible. I would try to list those commands that can work both with
Matlab and Octave). All the sample code listed here, I tried with Octave, not with Matlab.

There are huge number of functions which has not been explained here, but I would try to list those functions whi
are most commonly used in most of matlab sample script you can get. My purpose is to provide you the set of bas
commands with examples so that you can at least read the most of sample script you can get from here and there
(e.g, internet) without overwhelming you. If you get familiar with these minimal set of functionality, you would ge
some 'feeling' about the tool and then you would make sense out of the official document from Mathworks or GNU
Octave which explains all the functions but not so many examples.

I haven't completed 'what I think is the minimum set' yet and I hope I can complete within a couple of weeks. Sta
tuned !!!
Signal Processing

Quantization - quantiz

Zero Stuffing

Sample and Hold

Sample and Hold and Moving Avg

Sample and Hold and Low Pass Filter

interpolation - interp
resample (upsample) - resample
resample (downsample) - resample
filter
fir1
fir2
freqz
Filter Design Tutorial
RRC (Root Raised Cosine) Filter

< Quantization >

Octave/Matlab - Communication System

Home : www.sharetechnote.com

In this page, I will go through Matlab/Octave functions for communication system within a context of a
whole process but in step-by-step manner. You would have seen many other resources elsewhere explaining
on these functions, but most of the material that I have seen was purely for showing the syntax of each
functions. So it was very hard for me to understand practical meaning of those functions within a whole
communication process.
Following functions are the functions that is the most commonly used in Communication System.
Basic Functions
o randi()
o bi2de()
o qammod()
o awgn()
o qamdemod()
o de2bi()
o biterr()
Basic Implementation of Communication Sytem.
o Creating Random BitStream
o

Coverting Bit Stream into Symbol Stream

Modulation-Mapping Symbols onto a Constellation

Adding Noise

Demodulation - Demapping a Constellation to a Symbol

Converting a Symbol to Bits

BER Calculation

AM Modulation/Demodulation

Encoding/Decoding
o Coding(Encode/Decode)

Galois Field

Examples of Channel Coding

Hamming

Cyclic

Linear

Convolutional Code

gfconv

Representation of Convolutional Code

Examples of Representation for Convolutional Code

Trellis - struct

Trellis - poly2trellis

Channel Modeling - Matlab comm object


o QPSKModulator
o rayleighchan
o ricianchan

Following illustrations shows a process of a very simple (probably the simplest) communication system. Before
jumping into matlab coding let's go through each steps of this process first. Before I say something, I would like e
of you to step through each stage and make some story out of it.

You see two tracks of the process. The upper track is 'transmission' side and lower track is 'reciever' side.

Let's look at the transmitter side first.


i) At first, you would have a digital data to transmit in the form of bits stream. (this bit stream can be one of your
or movie or sound file or anything else).
ii) Next step is to covert this bit stream into a stream of symbols. (If you are totally new to communication system
you may not be famililar to the term called 'symbol'. Everybody would assume that you know this term, but it may
not be such a simple concept. At least, it was very vague concept for me when I was first reading things about
communication.. try google and understand the meaning of symbol.)
iii) Next step is to map each of those symbols on a constellation. (meaning a dot on I-Q coordinate).
iv) Next step would be to load those dots on the constellation onto a RF carrier and transmit them into the space.
v) once the signal gets into the space various kinds of noise are added to the signal and other factors distorts the
signal. (The space, noise and other factors distorting the signal are called 'channel').
vi) Now the signal is received by the reciever antenna and it is down-converted and sampled. These sampled signa
can be plotted onto constellation as shown above if you like.
vii) Then each of the dots on the constellation is converted to symbols.
viii) Finally each of the symbols are converted into the bit stream. (This can be a file, movie or sound that was sen
transmitter).
Following is the list of steps that I implemented with Matlab/Oactive.
Creating Random BitStream

Coverting Bit Stream into Symbol Stream

Modulation-Mapping Symbols onto a Constellation

Adding Noise

Demodulation - Demapping a Constellation to a Symbol

Converting a Symbol to Bits

BER Calculation

AM Modulation/Demodulation

Now let's look into a more complicated phase in the communication system which is about encoding/decoding for
error correction. (For me, this part is the most complicated one).

Coding(Encode/Decode)
o

Galois Field

Examples of Channel Coding

Hamming

Cyclic

Linear

Convolutional Code

gfconv

Representation of Convolutional Code

Examples of Representation for Convolutional Code

Trellis - struct

Trellis - poly2trellis

< Creating Random BitStream >

This is the first step of transmission. As I briefly described above, in real communication this can be a meaningful
like file, movie etc.. but in most of simulations or even in real life test use a sequence of random numbers (random
bits) as an input data.

In Matlab/Octave, you can use any variations of rand() functions, but randint() would be the simplest one to gene
the random bit stream as shown below.
Ex)
Input

N = 1000; % number of data


mlevel = 4; % size of signal constellation
% This indicate how many constellation points you would have in I/Q plane
% QAM = 4, 16 QAM = 16 etc
% signal generation in bit stream
x = randint(N,1);
%plot first 50 bits
stem(x(1:50),'filled'); title('Signal Bit Stream'); xlabel('Bit Index'); ylabel('Binary Value');

Output

< Coverting Bit Stream into Symbol Stream >

Now we are converting a sequence of bits into a sequence of symbols. In this example, I will use QAM modulation
two bits will become one symbol. ( Bit 00 -> Symbol 0, Bit 01 -> Symbol 1, Bit 10 -> Symbol 2, Bit 11 -> Symbo

bi2de() function is doing this conversion. Basically it converts a sequence of bits into a corresponding decimal num
Example is shown below and compare the two plots at output.
Ex)
Input

N = 1000; % number of data


mlevel = 4; % size of signal constellation
k = log2(mlevel); % number of bits per symbol
% signal generation in bit stream
x = randint(N,1);
% convert the bit stream into symbol stream
xsym = bi2de(reshape(x,k,length(x)/k).','left-msb');
%plot first 50 symbols
subplot(2,1,1);stem(x(1:200),'filled'); title('Signal Bit Stream');
xlabel('Bit Index'); ylabel('Binary Value');
subplot(2,1,2);stem(xsym(1:50),'filled'); title('Signal Symbol Stream');
xlabel('Symbol Index'); ylabel('Integer Value');

Output

< Modulation - Mapping Symbols onto a Constellation >


Next step is to map each of the symbols onto constellation (dots on I/Q coordinate).

This conversion process is to create a complex number out of a symbol as shown below. It may not look intuitive w
the first look. Try plugging in some numbers (e.b, -2.*mod(1,2)+2-1) and see what you get until you get clear
understanding of this process.
Ex)
Input

N = 1000; % number of data


mlevel = 4; % size of signal constellation
k = log2(mlevel); % number of bits per symbol
% signal generation in bit stream
x = randint(N,1);
% convert the bit stream into symbol stream
xsym = bi2de(reshape(x,k,length(x)/k).','left-msb');
% modulation
b = -2.*mod(xsym,k)+k-1;
a = 2.*floor(xsym./k)-k+1;
xmod = a + i.*b;
%plot first 50 symbols
subplot(1,3,[1 2]); stem(xsym(1:50),'filled'); title('Signal Symbol Stream');
xlabel('Symbol Index'); ylabel('Integer Value');
subplot(1,3,3); plot(real(xmod),imag(xmod),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);

Output

< Adding Noise >

Next step is to transmit the modulated data into the space. But there is no specific mathematical process for this
transmission (even though in real system, this transmission itself also requires very complicated technology).
Once the signal gets into the space (channel), a variety of noise is added. For this part, you need to generate the
noise part and add the noise to the signal. This two process can be done by a single function called awgn() as sho
below. (You may find a lot of other sample matlab code from internet for this process in two separate steps.)

Ex)
Input

N = 1000; % number of data


mlevel = 4; % size of signal constellation
k = log2(mlevel); % number of bits per symbol
% signal generation in bit stream
x = randint(N,1);
% convert the bit stream into symbol stream
xsym = bi2de(reshape(x,k,length(x)/k).','left-msb');
% modulation
b = -2.*mod(xsym,k)+k-1;
a = 2.*floor(xsym./k)-k+1;
xmod = a + i.*b;
Tx_x = xmod;
% adding AWGN
SNR = 20;
Tx_awgn = awgn(Tx_x,SNR,'measured');
%plot constellation
subplot(1,2,1); plot(real(Tx_x),imag(Tx_x),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);
subplot(1,2,2); plot(real(Tx_awgn),imag(Tx_awgn),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);
SNR = 5;
Tx_awgn1 = awgn(Tx_x,SNR,'measured');

SNR = 10;
Tx_awgn2 = awgn(Tx_x,SNR,'measured');
SNR = 15;
Tx_awgn3 = awgn(Tx_x,SNR,'measured');
SNR = 20;
Tx_awgn4 = awgn(Tx_x,SNR,'measured');
%plot constellation
subplot(2,2,1); plot(real(Tx_awgn1),imag(Tx_awgn1),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);title('AWGN = 5dB');
subplot(2,2,2); plot(real(Tx_awgn2),imag(Tx_awgn2),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);title('AWGN = 10dB');
subplot(2,2,3); plot(real(Tx_awgn3),imag(Tx_awgn3),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);title('AWGN = 15dB');
subplot(2,2,4); plot(real(Tx_awgn4),imag(Tx_awgn4),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);title('AWGN = 20dB');
Output

Following is showing the signal with various strengh of noise (AWGN). Try with other values in th
script until you get the practical understanding of this noise level.

< Demodulation - Demapping a Constellation to a Symbol >

This step is for converting the received constellation into a symbol. Mathematically, it is to map a complex number
a corresponding symbol number. In case of QAM, qamdemod() function does this job.

Ex)
Input

N = 1000; % number of data


mlevel = 4; % size of signal constellation
k = log2(mlevel); % number of bits per symbol
% signal generation in bit stream
x = randi([0 1],N,1);
% convert the bit stream into symbol stream
xsym = bi2de(reshape(x,k,length(x)/k).','left-msb');
% modulation
xmod = qammod(xsym,mlevel);
Tx_x = xmod;
% adding AWGN
SNR = 5;
Tx_awgn = awgn(Tx_x,SNR,'measured');
% Received signal
Rx_x = Tx_awgn;
%demodulation
Rx_x_demod = qamdemod(Rx_x,mlevel);
%plot each steps
subplot(3,2,[1 2]);stem(xsym(1:50),'filled'); title('Transmitted Symbol');
subplot(3,2,3); plot(real(Tx_x),imag(Tx_x),'go','MarkerFaceColor',[0,1,0]);

axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);


subplot(3,2,4); plot(real(Rx_x),imag(Rx_x),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);
subplot(3,2,[5 6]);stem(Rx_x_demod(1:50),'filled'); title('Recieved Symbol');
Output

< Converting a Symbol to Bits >


This step is for converting the symbols into Bit stream. de2bi() function do this job.

Ex)
Input

N = 1000; % number of data


mlevel = 4; % size of signal constellation
k = log2(mlevel); % number of bits per symbol
% signal generation in bit stream
x = randi([0 1],N,1);
% convert the bit stream into symbol stream
xsym = bi2de(reshape(x,k,length(x)/k).','left-msb');
% modulation
xmod = qammod(xsym,mlevel);
Tx_x = xmod;
% adding AWGN
SNR = 5;
Tx_awgn = awgn(Tx_x,SNR,'measured');
% Received signal
Rx_x = Tx_awgn;
%demodulation
Rx_x_demod = qamdemod(Rx_x,mlevel);
z = de2bi(Rx_x_demod,'left-msb'); % Convert integers to bits.
% Convert z from a matrix to a vector.
Rx_x_BitStream = reshape(z.',prod(size(z)),1);

%plot each steps


subplot(5,2,[1 2]);stem(x(1:200),'filled'); title('Transmitted Bit Stream');
subplot(5,2,[3 4]);stem(xsym(1:50),'filled'); title('Transmitted Symbol');
subplot(5,2,5); plot(real(Tx_x),imag(Tx_x),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);
subplot(5,2,6); plot(real(Rx_x),imag(Rx_x),'go','MarkerFaceColor',[0,1,0]);
axis([-mlevel/2 mlevel/2 -mlevel/2 mlevel/2]);
subplot(5,2,[7 8]);stem(Rx_x_demod(1:50),'filled'); title('Recieved Symbol');
subplot(5,2,[9 10]);stem(Rx_x_BitStream(1:200),'filled'); title('Recieved BitStream');

Output

< BER Calculation >

Ex)
Input

N = 1000; % number of data


mlevel = 4; % size of signal constellation
k = log2(mlevel); % number of bits per symbol
% signal generation in bit stream
x = randi([0 1],N,1);
% convert the bit stream into symbol stream
xsym = bi2de(reshape(x,k,length(x)/k).','left-msb');
% modulation
xmod = qammod(xsym,mlevel);
Tx_x = xmod;
% adding AWGN
SNR = 5;
Tx_awgn = awgn(Tx_x,SNR,'measured');
% Received signal
Rx_x = Tx_awgn;
%demodulation
Rx_x_demod = qamdemod(Rx_x,mlevel);
z = de2bi(Rx_x_demod,'left-msb'); % Convert integers to bits.

% Convert z from a matrix to a vector.


Rx_x_BitStream = reshape(z.',prod(size(z)),1);
%Calculate BER
[number_of_errors,bit_error_rate] = biterr(x,Rx_x_BitStream)
Output

Coding
I recommend you to read Communication - Coding pages for overall concept(theoretical part) first if you are new
Coding.
< Galois field >
gfconv

gfconv(a,b,p) : a,b is a row vector representing a polynomial. p is a prime number. The result is a row vector with
integer between 0 and (p-1). For example, if p is 2, the result vector is made up of binary number.

Ex) This is an example showing the code generation method explained in "Code Generation by Generator Polynom
Input

Msg = [1 1 1 1];
GenPoly = [1 1 0 1];
codeWord = gfconv(Msg,GenPoly)

Output

codeWord =
1 0 0 1

< Encode/Decode - hamming >


Ex) This is an example showing the code reviewed in Overview section
Input

k = 4;
n = 7;
Msg =
1
0
1
0
1
0
1
0

[0 0 0 0;
0 0 0;
1 0 0;
1 0 0;
0 1 0;
0 1 0;
1 1 0;
1 1 0;
0 0 1;

1 0 0 1;
0 1 0 1;
1 1 0 1;
0 0 1 1;
1 0 1 1;
0 1 1 1;
1 1 1 1]
codeWord = encode(Msg,n,k,'hamming/binary')
decodedMsg = decode(codeWord,n,k,'hamming/binary')
Output

Msg
0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1

=
0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1

0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1

0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1

codeWord =
0 0 0 0
1 1 0 1
0 1 1 0
1 0 1 1
1 1 1 0
0 0 1 1
1 0 0 0
0 1 0 1
1 0 1 0
0 1 1 1
1 1 0 0
0 0 0 1
0 1 0 0
1 0 0 1
0 0 1 0
1 1 1 1
decodedMsg =

0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1

0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1

0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1

0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1

0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1

0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1

0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1

Ex)
Input

m = 4; n = 2^m-1; % Codeword length = 15


k = 11; % Message length
% Create 100 messages, k bits each.
Msg = randi([0,1],5,k)
codeWord = encode(Msg,n,k,'hamming/binary')
decodedMsg = decode(codeWord,n,k,'hamming/binary')

Output

Msg
1
1
0
0
0

=
1
0
1
1
0

1
1
1
1
1

1
1
1
0
0

0
1
0
1
1

1
0
0
0
1

1
0
0
1
0

1
1
0
1
1

0
1
0
0
1

0
1
1
0
0

1
0
1
0
1

codeWord =
0 0 0 1
1 0 1 1
1 0 1 0
0 1 1 0
1 1 0 1

1
1
0
0
0

1
0
1
1
0

1
1
1
1
1

1
1
1
0
0

0
1
0
1
1

1
0
0
0
1

1
0
0
1
0

decodedMsg =
1 1 1 1
1 0 1 1
0 1 1 1
0 1 1 0

0
1
0
1

1
0
0
0

1
0
0
1

1
1
0
1

0
1
0
0

0
1
1
0

1
0
1
0

1
1
0
1
1

0
1
0
0
1

0
1
1
0
0

1
0
1
0
1

< Encode/Decode - Cyclic >


Ex) This is an example showing the code reviewed in Overview section
Input

k = 4;
n = 7;
Msg = [0 0 0 0;
1 0 0 0;
0 1 0 0;
1 1 0 0;
0 0 1 0;
1 0 1 0;
0 1 1 0;
1 1 1 0;
0 0 0 1;
1 0 0 1;
0 1 0 1;
1 1 0 1;
0 0 1 1;
1 0 1 1;
0 1 1 1;
1 1 1 1]
codeWord = encode(Msg,n,k,'cyclic/binary')
decodedMsg = decode(codeWord,n,k,'cyclic/binary')

Output

Msg
0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1

=
0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1

0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1

0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1

codeWord =
0 0 0 0
1 1 0 1
0 1 1 0
1 0 1 1
1 1 1 0
0 0 1 1
1 0 0 0
0 1 0 1
1 0 1 0
0 1 1 1
1 1 0 0
0 0 0 1
0 1 0 0
1 0 0 1
0 0 1 0
1 1 1 1

0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1

0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1

0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1

decodedMsg =
0 0 0 0
1 0 0 0
0 1 0 0
1 1 0 0
0 0 1 0
1 0 1 0
0 1 1 0
1 1 1 0
0 0 0 1
1 0 0 1
0 1 0 1
1 1 0 1
0 0 1 1
1 0 1 1
0 1 1 1
1 1 1 1

Ex)
Input

m = 4; n = 2^m-1; % Codeword length = 15


k = 11; % Message length
% Create 100 messages, k bits each.
Msg = randi([0,1],5,k)
codeWord = encode(Msg,n,k,'cyclic/binary')
decodedMsg = decode(codeWord,n,k,'cyclic/binary')

Output

Msg
1
0
0
0
0

=
0
0
0
1
1

0
1
0
1
1

1
0
0
1
1

0
1
1
0
0

0
1
0
1
0

1
1
0
0
0

0
1
0
0
1

1
0
1
1
0

0
0
0
0
1

1
0
0
1
1

codeWord =
1 0 0 1
0 1 0 1
0 1 0 1
1 0 1 1
1 1 0 1

1
0
0
0
0

0
0
0
1
1

0
1
0
1
1

1
0
0
1
1

0
1
1
0
0

0
1
0
1
0

1
1
0
0
0

decodedMsg =
1 0 0 1
0 0 1 0
0 0 0 0
0 1 1 1
0 1 1 1

0
1
1
0
0

0
1
0
1
0

1
1
0
0
0

0
1
0
0
1

1
0
1
1
0

0
0
0
0
1

1
0
0
1
1

0
1
0
0
1

1
0
1
1
0

0
0
0
0
1

1
0
0
1
1

< Encode/Decode - linear >


Ex) This is an example of the codeword generation method explained in Generation by Generation Matrix
Input

k = 4;
n = 7;
m = log2(n+1);
Msg =
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1

[0 0 0 0;
0 0 0;
1 0 0;
1 0 0;
0 1 0;
0 1 0;
1 1 0;
1 1 0;
0 0 1;
0 0 1;
1 0 1;
1 0 1;
0 1 1;
0 1 1;
1 1 1;
1 1 1]

[parmat,genmat] = hammgen(m)
codeWord = encode(Msg,n,k,'linear/binary',genmat)
decodedMsg = decode(codeWord,n,k,'linear/binary',genmat)
Output

Msg
0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1

=
0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1

0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1

0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1

parmat
1 0
0 1
0 0

=
0
0
1

1
1
0

0
1
1

1
1
1

1
0
1

genmat
1 1
0 1
1 1
1 0

=
0
1
1
1

1
0
0
0

0
1
0
0

0
0
1
0

0
0
0
1

codeWord =
0 0 0 0
1 1 0 1
0 1 1 0
1 0 1 1
1 1 1 0
0 0 1 1
1 0 0 0
0 1 0 1
1 0 1 0
0 1 1 1
1 1 0 0
0 0 0 1

0
0
1
1
0
0
1
1
0
0
1
1

0
0
0
0
1
1
1
1
0
0
0
0

0
0
0
0
0
0
0
0
1
1
1
1

0
1
0
1

1
0
0
1

0
0
1
1

0
1
0
1

0
0
1
1

1
1
1
1

1
1
1
1

decodedMsg =
0 0 0 0
1 0 0 0
0 1 0 0
1 1 0 0
0 0 1 0
1 0 1 0
0 1 1 0
1 1 1 0
0 0 0 1
1 0 0 1
0 1 0 1
1 1 0 1
0 0 1 1
1 0 1 1
0 1 1 1
1 1 1 1

Ex) This is an example showing the way to generate arbitrary length of message and code word. This is an examp
(15,11) linear block code.
Input

m = 4; n = 2^m-1; % Codeword length = 15


k = 11; % Message length
m = log2(n+1);
% Create 5 messages, k bits each.
[parmat,genmat] = hammgen(m)
Msg = randi([0,1],5,k)
codeWord = encode(Msg,n,k,'linear/binary',genmat)
decodedMsg = decode(codeWord,n,k,'linear/binary',genmat)

Output

parmat
1 0
0 1
0 0
0 0

=
0
0
1
0

0
0
0
1

1
1
0
0

0
1
1
0

0
0
1
1

1
1
0
1

1
0
1
0

0
1
0
1

1
1
1
0

0
1
1
1

1
1
1
1

1
0
1
1

1
0
0
1

genmat
1 1
0 1
0 0

=
0
1
1

0
0
1

1
0
0

0
1
0

0
0
1

0
0
0

0
0
0

0
0
0

0
0
0

0
0
0

0
0
0

0
0
0

0
0
0

1
1
0
1
0
1
1
1

1
0
1
1
1
1
0
0

0
1
0
1
1
1
1
0

1
0
1
0
1
1
1
1

0
0
0
0
0
0
0
0

0
0
0
0
0
0
0
0

0
0
0
0
0
0
0
0

1
0
0
0
0
0
0
0

0
1
0
0
0
0
0
0

0
0
1
0
0
0
0
0

0
0
0
1
0
0
0
0

Msg
0
1
1
1
0

=
0
0
0
0
0

1
1
0
1
0

1
1
1
0
0

0
0
1
0
1

0
1
1
1
0

0
0
0
0
0

0
1
1
1
1

0
0
0
1
0

1
1
0
0
0

1
0
0
1
1

codeWord =
1 1 0 0
1 0 1 1
1 0 0 1
1 0 1 1
0 1 0 0

0
1
1
1
0

0
0
0
0
0

1
1
0
1
0

1
1
1
0
0

0
0
1
0
1

0
1
1
1
0

0
0
0
0
0

decodedMsg =
0 0 1 1
1 0 1 1
1 0 0 1
1 0 1 0
0 0 0 0

0
0
1
0
1

0
1
1
1
0

0
0
0
0
0

0
1
1
1
1

0
0
0
1
0

1
1
0
0
0

1
0
0
1
1

0
0
0
0
1
0
0
0

0
0
0
0
0
1
0
0

0
0
0
0
0
0
1
0

0
0
0
0
0
0
0
1

0
1
1
1
1

0
0
0
1
0

1
1
0
0
0

1
0
0
1
1

Convolutional Code

It is hard to cleary explain what is the convolutional code is, but you would get a rough image if you think about t
'convolution' that you learned in your engineering math.

One important criteria for convolutional code would be


Each bit on output stream is influenced not only by the current input bit but also influenced by the previous
output bits.
How to represent convolutional coding process ?
Representing the convolutional coding process is not simple and clearly explained in short space. So I created
aseparate page for this.

< Trellis - struct >


Ex) You need to know how to interpret and utilize the Trellis Diagram and then get back to this example.

Input

Trellis = struct(numInputSymbols,2,
numOutputSymbols,4,
numStates,4,
nextStates,[0 2;0 2;1 3;1 3],
outputs,[0 3;3 0;2 1;1 2])
code = convenc([1 1 0 1 1],trellis)

Output

code =
1
1

< Trellis - poly2trellis >

Input

trellis = poly2trellis([3],[7 5]);


code = convenc([1 1 0 1 1],trellis)

Output

code =
1
1

< QPSKModulator >

Matlab comm object has various Modulation functions and QPSKmodulator is one of them. But the QPSKModulator
itself does not directly generate I/Q data. You have to use step() function to generate I/Q data. and scatterplot() t
plot the IQ data
Input

data = randi([0 1],100,1);


hMod = comm.QPSKModulator('BitInput',true)
hMod.PhaseOffset = 0;
modData = step(hMod, data);
scatterplot(modData)

Output

System: comm.QPSKModulator
Properties:
PhaseOffset: 0.785398163397448
BitInput: true
SymbolMapping: 'Gray'
OutputDataType: 'double'

< rayleighchan >

The key function in this example is 'rayleighchan()' function. This function itself does not generate IQ data for the
channel. You have to use 'filter()' function and pass a input data and channel object into it to generate faded I/Q d
This examples is simple but shows almost the whole process from data generation to create faded I/Q data.
Followings are the two functions you have to know of
reyleighchan(samplingTime,
DopplerFrequencySpan,
[vector representing phase angle of each tap of the fader],
[vector representing phase gain of each tap of the fader])
filter(variable representing a channel, vector representing a list of I/Q data]
Input

data = randi([0 1],20000,1);


hMod = comm.QPSKModulator('BitInput',true)
hMod.PhaseOffset = 0;
modData = step(hMod, data);
channel = rayleighchan(1/1000,2,[0 2e-5 0],[0 -10 -30])
rcvData = filter(channel,modData);
% Pass signal through channel

% Plot power of faded signal, versus sample number.


range = 400:600;
subplot(3,2,1); plot(real(modData(range)),imag(modData(range)),'ro','MarkerFaceColor',[1 0 0])
axis([-4 4 -4 4]);
subplot(3,2,2); plot(real(rcvData(range)),imag(rcvData(range)),'ro','MarkerFaceColor',[1 0 0]);
axis([-4 4 -4 4]);
subplot(3,2,[3 4]); plot(20*log10(abs(modData)));
subplot(3,2,[5 6]); plot(20*log10(abs(rcvData)));

Output

< ricianchan >

The key function in this example is 'ricianchan()' function. This function itself does not generate IQ data for the
channel. You have to use 'filter()' function and pass a input data and channel object into it to generate faded I/Q d
This examples is simple but shows almost the whole process from data generation to create faded I/Q data.
Followings are the two functions you have to know of
ricianchan(samplingTime,
DopplerFrequencySpan,
K)
filter(variable representing a channel, vector representing a list of I/Q data]

Input

data = randi([0 1],20000,1);


hMod = comm.QPSKModulator('BitInput',true)
hMod.PhaseOffset = 0;
modData = step(hMod, data);
channel = ricianchan(1/1000,4,1.0)
rcvData = filter(channel,modData);

% Pass signal through channel

% Plot power of faded signal, versus sample number.


range = 400:600;
subplot(3,2,1); plot(real(modData(range)),imag(modData(range)),'ro','MarkerFaceColor',[1 0 0])
axis([-4 4 -4 4]);
subplot(3,2,2); plot(real(rcvData(range)),imag(rcvData(range)),'ro','MarkerFaceColor',[1 0 0]);
axis([-4 4 -4 4]);
subplot(3,2,[3 4]); plot(20*log10(abs(modData)));
subplot(3,2,[5 6]); plot(20*log10(abs(rcvData)));

Output

Simulink

Matlab - Simulink

Modulation/Demodulation - Example 4

< Model >

Home : www.sharetechnote.com

< Parameters >

< Result >

Matlab - Simulink

Modulation/Demodulation - Example 6

< Model >

Home : www.sharetechnote.com

< Parameters >

< Result >

Matlab - Simulink

Modulation/Demodulation - Example 7

< Model >

Home : www.sharetechnote.com

< Parameters >

< Result >

Matlab - Simulink

Modulation/Demodulation - Example 7

< Model >

Home : www.sharetechnote.com

< Parameters >

< Result >

Sum Of Times

Home : www.sharetechnote.com

I think one of the most common components of mathenatical equations being used in various engineering field wo
be as follows. (you will see specific examples later). I am pretty sure that almost all of you have seen this compon
in the mathematical models which you are working on now. So I thought it would be worthwhile looking into the
practical meaning of this component as the first topic of my course (at least in engineering mathematics).

Everybody would have different ways to understand a concept and you can interpret this in any way which is bette
for you. Personally, I am such a person who has difficulties to understand any concept that cannot be visualized. S
whenever I want to learn something, the first step is to try to visualize the basic concepts. Fortunately, I think mo
the concept in engineering can be visualized.

My visualization of this mathematical operation is as follows.

As you see in the mathmatical presentation, it has two component x and y. Judging from the fact that x and y has
subscript (i) which implies that x, y is not a single number. They are a sequence number. In computer programmin
concept, these x, y are a kind of 1 dimensional arrays.
Can I understand the operation of this mathematical presentation just by looking at the illustration above without
additional explanation ? I strongly hope so.
If I present this into a C language syntax which most of you are familiar with, it would be as follows.
sum = 0;
for (i = 0; i < n; i++) {
sum += x[i]*y[i];
}
In short, this operation can be summarized as following two steps.
i) multiply (times) each components of the sequence x, y
ii) sum all of the result of the multiplication.
This is why I put the title of this page as "Sum of Times" meaning "Sum of Multiplication".

Another widely used graphical representation of "Sum of Times" is as follows. You will often see this representatio
Neural Network.

Now let's think about why this mathematical operation is so important. I think it is because this mathmatical form
the most essential component of the following engineering tools which are most commonly used mathemtical tool
engineering area.

Correlation
Fourier Transform
Convolution
Vector Inner Product
Neural Network
Application
o Convolution - FIR - Low Pass Filter
o Convolution - Image Processing

Correlation (Correlation Coefficient)

There are many different variation of mathematical representation of Correlation Coefficient. One of examples is a
follows. It would look intimidatingly complicated, but the most important part of the equation is the part marked i
red rectangle. All the other parts are to make the result of the equation became between -1 and +1.

What is the meaning of the correlation coefficient ? Correlation Coefficient is a specific number that represent how
closely two sequence (data set) are (related) related.
What does it mean by "related" ?
My intuitive understanding about "being related" is "how can the two graph of the data set look similar". You may

another question saying "What do you mean by 'being similar' ?".


Let me give you my personal understanding as well for this term. 'Being Similar' can be an indicator to show "How
well the graph of the two data set can be overlapped without shifting any of the data set ?". Pay specific attention
"WITHOUT SHIFTING any of the data set". This is very important.
Now let's try visualize the meaning of the Correlation Coefficient. I want you to try to understand this intuitive
meaning as hard as possible since this concept will help you understand most of other tools that uses the 'sum of
times' component.

I created 6 different data sequence named as x1, x2, x3, x4, x5, x6 respectively. The graph of each data sequenc
are as follows.

Now let me ask you a question.


How similar the sequence x1 and x2 are to each other ? Do you think they are very closely related or very loosely
related ? I will give you 10 seconds to think about the answer.

Now let's figure out the correlation coefficient of x1 and x2 using a matlab function as follows. As you see, the
calculated coefficient of x1, x2 is 0.000. What does this mean ? It means these two sequences are not related to e
other at all. Is this answer close to what you intuitively thought ? It may be not for somebody. You may think "If y
shift x2 a little bit to the right or left, you would see x1 and x2 would exactly overlap each other. How come they a

not correlated at all ?". You are right, but as I explained earlier, 'Correlation Coefficient' is an indicator to show "H
well the graph of the two data set can be overlapped without shifting any of the data set ?". Do you see 'without
shifting any of the data' ? If you do the mathematical operation of correlation coefficient for x1 and x2 as it is, you
the value 0.000, which means 'no correlation'.
corrcoef(x1,x2) = 0.000
Now let's compare x1 with x3. What do you think about the correlation between these two data sets ? First you w
notice that these two data set would never overlap (superimpose) each other. So.. Should Correlation Coefficient b
'zero' ? Let's calculate the correlation coefficient using a matlab function and I got the following result. It's '-1'. Ho
do I interpret this ? Does this mean that there is even less correlation than 'zero correlation' ?
No. This means that if you mirror x3 along the horizontal axis, x1 and x3 overlap (superimpose) each other. This i
also an example of high correlation.
corrcoef(x1,x3) = -1.000
Let's move to the next comparison. Let's compare x1 and x4. First just look at the shape of the graph of x1 and x
Does it look identical ? No, if you look at them carefully, you would notice that x4 is a little bit of shifted version of
What would the correlation coefficient of these two data set be like ? The result is as follows. It shows pretty stron
correlation, but not as strong as '1' (100% correlation). Compare the set (x1,x4) and (x1,x2). (x1,x2) gave us zer
correlation but (x1,x4) gives us a certain degree of correlation. Both x2 and x4 are the shifted version of x1. Then
why do we have different result ? It is because the amount of shift is different. In case of (x1,x2), the shift is 90
degree (pi/2), but in case of (x1,x4) the shift is less than 90 degree.
corrcoef(x1,x4) = 0.705
Now let's look into the correlation coefficient of x1 and x5. The result is as follows. Do these two graphs superimp
each other ? NO. Then how come the correlation coefficient become 1.0 (100% correlation) ? Is it because the two
graph can superimpose if you change the magnitude of x5. (In this case, if you magnify x5 twice, the two graph
superimpose).
corrcoef(x1,x5) = 1.000
Now let's take a look at the last case - x1,x6. It would look like this set would be the least correlated to each othe
Let's take a correlation coefficient. The result is as follows. As we expected, the correlation is very low... but it is s
little higher than the set (x1, x2). Isn't this against your intuition ?
corrcoef(x1,x6) = -0.019
We have gone through several sets of data sets to give you some intuitive understanding of the correlation coeffic
But you would have noticed some of the cases which might go against your intuition. This kind of case can be a ris
using intuition or of just relying on visualization, but I think it still be a better way than totally relying on
mathematical equation and gets no clue of the real meaning of it.

Following is the Matlab/Octave script that would give you a series of plots as shown above. Try create any of the d
on your own and how the graph and correlation coefficient changes.
t=0:2*pi/100:10;
Nt = size(t,2);
x1=sin(2*pi*t);
x2=cos(2*pi*t);
x3=-sin(2*pi*t);
x4=sin(2*pi*t-pi/4.0);
x5=0.5.*sin(2*pi*t);
x6=2.*rand(1,Nt)-1;
subplot(6,1,1);plot(x1);ylabel('x1');axis([0,Nt,-1.1,1.1]);
subplot(6,1,2);plot(x2);ylabel('x2');axis([0,Nt,-1.1,1.1]);
subplot(6,1,3);plot(x3);ylabel('x3');axis([0,Nt,-1.1,1.1]);
subplot(6,1,4);plot(x4);ylabel('x4');axis([0,Nt,-1.1,1.1]);
subplot(6,1,5);plot(x5);ylabel('x5');axis([0,Nt,-1.1,1.1]);
subplot(6,1,6);plot(x6);ylabel('x6');axis([0,Nt,-1.1,1.1]);
fprintf('corrcoef(x1,x1) = %1.3f\n',corrcoef(x1,x1))

fprintf('corrcoef(x1,x2)
fprintf('corrcoef(x1,x3)
fprintf('corrcoef(x1,x4)
fprintf('corrcoef(x1,x5)
fprintf('corrcoef(x1,x6)

=
=
=
=
=

%1.3f\n',corrcoef(x1,x2))
%1.3f\n',corrcoef(x1,x3))
%1.3f\n',corrcoef(x1,x4))
%1.3f\n',corrcoef(x1,x5))
%1.3f\n',corrcoef(x1,x6))

Fourier Transform

Now we are going to look into such a famous tool, called "Fourier Transform". Here in this section, I would focus o
the mathematical meaning of the Fourier Transform (more specifically, Discrete Fourier Transform). See the Fourie
Transform page for its role as an engineering tool.

A typical mathematical presentation of Discrete Fourier Transform looks as follows. It may look a little bit complica
but if you wrap it up into proper chunks you would notice that this is also a kind of "Sum of Times" format.

As you learned in Correlation section (explained above), the most intuitive meaning of "Sum of Times" is a kind of
indicator showing the correlation between two data sequences.
So Fourier Transform is also based on calculating the two specified data sequence as follows.
xi = input data sequence for Fourier Transform
yi = e^(-i 2pi k n/N)
It means that Fourier Transform is indication of correlation between a given data sequence and "e^(-i 2pi k n/N)".
you studied "Exponential Form" or any material about Euler's formula, you would know e^(-i 2pi k n/N) is a cyclic
function. It is a cyclic function, the cycle of which is represented by the variable 'k'. Therefore, we can say "Fourie
Transform is a tool to show the correlation between a specified data sequence and muliples of cyclic data sequenc
with different cycle".

If I represent my explanation, Fourier Transform can depicted as follows. (In the following graph, "x1" is the input
data you want to do 'fourier transform', and the series of plots on right side is the multiple cyclic data sequence w
different cycles. The stem plot at the left bottom is the graph shows the forrelation coefficient of each data pair, i.
(x1, s1), (x1,s2), (x1, s3) and so forth.

If you convert this description into a mathematical forumula, Fourier Transform can be depicted as follows.

Following is Matlab/Octave script generating the sequence of graphs shown above. Try change the data for x1 in
various different way until you get your own intuition of this concept.
t=0:2*pi/400:3;
Nt = size(t,2);
x1 = sin(2*pi*2*t) + 0.3 * sin(2*pi*5*t) + 0.7*sin(2*pi*7*t);
s1=sin(2*pi*1*t);
s2=sin(2*pi*2*t);
s3=sin(2*pi*3*t);
s4=sin(2*pi*4*t);
s5=sin(2*pi*5*t);
s6=sin(2*pi*6*t);
s7=sin(2*pi*7*t);
s8=sin(2*pi*8*t);
s9=sin(2*pi*9*t);
s10=sin(2*pi*10*t);
corr_vec = [corrcoef(x1,s1) corrcoef(x1,s2) corrcoef(x1,s3) corrcoef(x1,s4) corrcoef(x1,s5) corrcoef(x1,s6
corrcoef(x1,s7) corrcoef(x1,s8) corrcoef(x1,s9) corrcoef(x1,s10)];
subplot(10,2,1);plot(x1);ylabel('x1');axis([0,Nt,-2.1,2.1]);
subplot(10,2,1*2);plot(s1);ylabel('s1(1Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,2*2);plot(s2);ylabel('s2(2Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,3*2);plot(s3);ylabel('s3(3Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,4*2);plot(s4);ylabel('s4(4Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,5*2);plot(s5);ylabel('s5(5Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,6*2);plot(s6);ylabel('s6(6Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,7*2);plot(s7);ylabel('s7(7Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,8*2);plot(s8);ylabel('s8(8Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,9*2);plot(s9);ylabel('s9(9Hz)');axis([0,Nt,-1.1,1.1]);

subplot(10,2,10*2);plot(s10);ylabel('s10(10Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,[13 15 17 19]);stem(abs(corr_vec));ylabel('corr');axis([0,10,0,1.0]);

Convolution

Convolution is an tool which is as widely used as Fourier Transform. When we "analyze" or "design" something (e.
Filter or Control System) we usually use Fourier Transform, but when we "implement" what we designed, we norm
use "convolution".
Fourier Transform is a tool which convert a time domain entity into a frequency domain entity. Convolution is a too
which manipulate a time domain entity as it is in time domain.
To be honest, I haven't heard the word 'Convolution' before I first started a filter design product around 20 years
and I haven't understood the real meaning of this tool for a couple of years even while I was using the tool very
heavily and even implemented it in my program. So don't get disappointed if you don't understand this right away
far as I exprienced, it took me take at least several month to understand the real meaning of any new concept ev
though it may look simple. The most important thing is to hold on to it without giving up until you grasp the real
understanding however long it would take.

Actually it is very difficult to understand the real/intuitive meaning of convolution without animation. (please refer
couple of links I listed below). But you should not rely on to the animated explation only. You would say "Ah Ha...
I think I understand this" when you see those animated ones, but your understanding would start fading a couple
days later. At some point, you have to directly attack the math itself and solidify your understanding.

I will try add a couple of more illustration later hoping it help more. For now, if I just describe it the process verba

Let's assume we have two data called 'f[m]', 'g[m]'. In convolution, these two data has two different role.. one is
data to be processed and the other one is what we call 'kernel'. Let's assume f[m] is the data to be processed and
g[m] as 'kernel'. Let's assume c[n] is the result data of the convolution. Usually f[] is much longer than g[]. We w
to take the convolution of these two data. Overall step goes like this.
i) Take the kernel data sequence (in this case, g[m]) and flip it around (revserse it). This gives you g[-m]
ii) Align f[m] and g[-m] to the left. Now the starting position of f[m] and g[-m] is same.
iii) Perform the "sum of times (sum of multiplication)" between f[m] and g[-m] from the first elements of g
m] to the last elements of g[-m] and put the result into the first element of c[] data.(It means the result g
into c[0]).
iv) Shift g[-m] data to the right by one step (this is called g[-(m-1)] or g[1-m]). Now the second data of f[
and first data of g[-(m-1)] is aligned.
v) Perform the "sum of times (sum of multiplication)" between f[] and g[] from the first elements of g[-(m
to the last elements of g[-(m-1)] and put the result into the first element of c[] data.(It means the result g
into c[1]).
iv) Shift g[-(m-1)] data to the right by one step (this is called g[-(m-2)] or g[2-m]). Now the second data
f[] and first data of g[-m] is aligned.
v) Perform the "sum of times (sum of multiplication)" between f[] and g[] from the first elements of g[-(m
to the last elements of g[-(m-2)] and put the result into the first element of c[] data.(It means the result g
into c[2]).
vi) Now you see any pattern. Do this pattern until g[] reaches to the end of f[].

For clearer understanding, I recommend you to try this whatever programing language (C, Java, Matlab, Octave e
you are familiar with. If you are not familiar with any of the programming language, Microsoft Excel would be an
excellent tool for you to try.

I hope following illustration would help you a little bit understand the mathematical component of the convolution.

One of the simplest and most common example of the convolution can be found in stock chart. In stock chart, you
would see 7 days moving average or 52 days moving everage etc. This kind of moving average is the most comm
example of convolution.
if you set the data as follows,
f[] = daily stock price data
g[] = [1/7 1/7 1/7 1/7 1/7

1/7

1/7]

If you take the convolution of f[] and g[], the result will give you 7 days moving average of the stock price data.
Following is a couple of links that you give you a couple of intuitive understanding of the convolution process.
Continous Convolution (http://jhu.edu/~signals/convolve/index.html)
Discrete Convolution(http://jhu.edu/~signals/discreteconv2/index.html)
Interactive Lecture Module: Continuous-Time LTI Systems and Convolution
(http://jhu.edu/~signals/lecture1/frames.html)

Vector Inner Product

I think you might have learned about a vector. (you may have learned this in high school in some country or learn
in Linear Algebra course in University). In the course, you may have learned an mathematical operator called 'inn
product' of vectors. '
If you define a two vector as follows,

The inner product of these two vectors are defined as follows. (What is practical meaning of "Inner Product"? I wo
try to explain on this in Vector page).

You would notice this is a straightforward example of "sum of times". This is why in many text book many authors
likes to this kind of 'vector inner product' notation for various "sum of times" operation. Once you see those proce
expressed as this kind of purely mathematical operation, you start feel dizzy and close the book. But it is more lik
psychogical effect. Just try to convert it into a form which gives you less psychological burden like "sum of times"
form and you can continue to read the book -:)

Neural Network
Just look at the following diagrams first and think on your own about how this can be related to the "sum of
times/sum of multiplication" process. Refer to Neural Network section in Matrix page.

Again, refer to Neural Network section in Matrix page to know how you can get the following representdation from
diagram above.

Again, refer to Neural Network section in Matrix page to know how you can get the following representdation from
diagram above.

Application - Convolution - FIR - Low Pass Filter

In a previous section, you understand how the process called "sum of times" is used for a complicated process cal
'Convolution'. This section would give you a example on how the process 'Convolution' is used in a engineering
application. This example shows you how covolution is used to implement a digital filter and of course, the
fundamental mathemtical process is "sum of times".
Most of digital filter (FIR filter in this case) is represented as follows. Take bi = g[] and x[] = f[] and read the
'convolution' section. then you would understand how this works. The only difference between this mathematical
representation and the one used in 'convolution' section is that in this case f[] is shifting at each iteration, but in
convolution section g[] was shifting at each iteration. But result is the same.

Following is the Matlab and Octave code you can try.

Fs=8e3;
Ts=1/Fs;
Ns=512;
t=[0:Ts:Ts*(Ns-1)];
f1=500;
f2=3200;
x1=sin(2*pi*f1*t);
x2=0.3*sin(2*pi*f2*t);
x=x1+x2;
b = fir1(48,0.35,'low');
y=conv(x,b);
subplot(5,1,1); plot(x1);ylabel('x1');axis([0,550,-1.5,1.5]);
subplot(5,1,2); plot(x2);ylabel('x2');axis([0,550,-1.5,1.5]);
subplot(5,1,3); plot(x);ylabel('x=x1+x2');axis([0,550,-1.5,1.5]);
subplot(5,1,4); plot(b);ylabel('b');axis([0,550,-0.5,0.5]);
subplot(5,1,5); plot(y);ylabel('y=conv(x,b)');axis([0,550,-1.5,1.5]);
Application - Convolution - Image Processing

I will not say much about the image processing here since this page is not for the theory of image processing even
though this is one of my favourite topics. If you are interested in the image process, I strongly recommend to refe
to this excellent presentation here.

Very briefly speaking, a lot of image processing techniq is implemented by Convolution and this convolution is don
2 D data (2 D array) as illustrated below. My point here is that you see the convolution and "sum of times" proces
this techniq as well.

Following is one example of the process that I mentioned here with Octave/Matlab. You would see the source code
the bottom. Enjoy !!!

img=imread('Lena.png');
imgBW = rgb2gray(img);
imshow(imgBW);
b=[0 0 0;0 1 0;0 0 -1]
pimg = conv2(imgBW,b);
figure;
imshow(pimg);

FFT (Fast Fourier Transform)

Probably Fourier Transform would be a mathematical tool which is the most widely used in engineer area. I would
explain in details how Fourier Transform works mathematically, you can have a lot of information from internet or
least you would go through at least a couple of month for this topic during your university course.
When I think about the word "Fourier" (Actually a person's name), I have two images as shown below. One is a

Fourier Series Expension and the other one is Fourier Transform. With Fourier Series expansion, you would have a
continous function made up of very simple components (sin() + cos()) for any data whether the data is continous
non-continous. I am pretty sure that you would learn how to create a sequence of (sin() + cos()) to approximate
computer clock-like rectangular pulse. (You could easily find tutorial or even many of Java application from interne

Another image that pops up in my mind when I think about 'Fourier' is 'Fourier Transform'. One of the most typica
usage (or purpose) of courier transform is to convert a time domain data into a frequency domain data and this
section will mostly focused on this 'Fourier Transform'. (I think I am hearing those questions from many reader...
saying ... "What is time domain data ? What is frequecy domain data ? why we want to convert the time domain d
into frequency domain data ?". All of these are very good question. Try very hard until you get your own answers
these questions -:)).

I would not explain much of the theory about FFT, you would already get too much of it from text book or from on
line. As in other pages in my site, I will put as much examples and plots as possible just to make you "feel" about
Of course, this pages would keep being extended as I find more examples that would help you with "intuitive"
understanding of FFT.
What is Fourier Transform
Zero Padding
Number of Period
Abrupt Changes in Time Domain Data
FFT for Complex Number
Phase of FFT
Effect of multiplying Exp(p i) to the signal
Effect of multiplying Exp(f t i) to the signal

What is Fourier Transform ?

Fourier Transform is a special kinds of mathematical series technology that can approximate a function or a data w
summation of sin() and cos() function. There are two kind of Fourier transform, one is continuous fourier transform
and the other is discrete fourier transform.
Basic principles are same, but in this section I will explain the concept of Fourier transform using a discrete transfo
since it is easy to visualize and less scary :)

A typical mathematical presentation of Discrete Fourier Transform looks as follows. It may look a little bit complica
but if you wrap it up into proper chunks you would notice that this is also a kind of "Sum of Times" format.

As you learned in Correlation section (explained above), the most intuitive meaning of "Sum of Times" is a kind of
indicator showing the correlation between two data sequences.
So Fourier Transform is also based on calculating the two specified data sequence as follows.
xi = input data sequence for Fourier Transform
yi = e^(-i 2pi k n/N)
It means that Fourier Transform is indication of correlation between a given data sequence and "e^(-i 2pi k n/N)".
you studied "Exponential Form" or any material about Euler's formula, you would know e^(-i 2pi k n/N) is a cyclic
function. It is a cyclic function, the cycle of which is represented by the variable 'k'. Therefore, we can say "Fourie
Transform is a tool to show the correlation between a specified data sequence and muliples of cyclic data sequence
with different cycle".

If I represent my explanation, Fourier Transform can depicted as follows. (In the following graph, "x1" is the input
data you want to do 'fourier transform', and the series of plots on right side is the multiple cyclic data sequence w
different cycles. The stem plot at the left bottom is the graph shows the forrelation coefficient of each data pair, i.e
(x1, s1), (x1,s2), (x1, s3) and so forth.

If you convert this description into a mathematical forumula, Fourier Transform can be depicted as follows.

Following is Matlab/Octave script generating the sequence of graphs shown above. Try change the data for x1 in
various different way until you get your own intuition of this concept.
t=0:2*pi/400:3;
Nt = size(t,2);
x1 = sin(2*pi*2*t) + 0.3 * sin(2*pi*5*t) + 0.7*sin(2*pi*7*t);
s1=sin(2*pi*1*t);
s2=sin(2*pi*2*t);
s3=sin(2*pi*3*t);
s4=sin(2*pi*4*t);
s5=sin(2*pi*5*t);
s6=sin(2*pi*6*t);
s7=sin(2*pi*7*t);
s8=sin(2*pi*8*t);
s9=sin(2*pi*9*t);
s10=sin(2*pi*10*t);
corr_vec = [corrcoef(x1,s1) corrcoef(x1,s2) corrcoef(x1,s3) corrcoef(x1,s4) corrcoef(x1,s5) corrcoef(x1,s6
corrcoef(x1,s7) corrcoef(x1,s8) corrcoef(x1,s9) corrcoef(x1,s10)];
subplot(10,2,1);plot(x1);ylabel('x1');axis([0,Nt,-2.1,2.1]);
subplot(10,2,1*2);plot(s1);ylabel('s1(1Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,2*2);plot(s2);ylabel('s2(2Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,3*2);plot(s3);ylabel('s3(3Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,4*2);plot(s4);ylabel('s4(4Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,5*2);plot(s5);ylabel('s5(5Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,6*2);plot(s6);ylabel('s6(6Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,7*2);plot(s7);ylabel('s7(7Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,8*2);plot(s8);ylabel('s8(8Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,9*2);plot(s9);ylabel('s9(9Hz)');axis([0,Nt,-1.1,1.1]);

subplot(10,2,10*2);plot(s10);ylabel('s10(10Hz)');axis([0,Nt,-1.1,1.1]);
subplot(10,2,[13 15 17 19]);stem(abs(corr_vec));ylabel('corr');axis([0,10,0,1.0]);

Zero Padding

See following plots. As you see in (a), (b), (c), (d), the length of the data for the signal are all the same. But leng
zero value being appended to the signal data are different resulting in different number of data for fft. Just try to '
or 'sense' the general trand. what kind of difference you see in the fft plot as the length of appended zero gets
increased ? Do you see the fft plot gets smoother as the length of trailing zeros (zero pad) gets longer ?

Try following Octave/Matlab code and play with following lines marked in blue.
n = [0:31];
x = cos(2*pi*n/10);
x1
x2
x3
x4

=
=
=
=

x;
[x zeros(1,64-length(x1))];
[x zeros(1,128-length(x1))];
[x zeros(1,256-length(x1))];

fft_x1
fft_x2
fft_x3
fft_x4

=
=
=
=

abs(fft(x1));
abs(fft(x2));
abs(fft(x3));
abs(fft(x4));

f1
f2
f3
f4

=
=
=
=

[0:length(fft_x1)-1]/length(fft_x1);
[0:length(fft_x2)-1]/length(fft_x2);
[0:length(fft_x3)-1]/length(fft_x3);
[0:length(fft_x4)-1]/length(fft_x4);

subplot(4,2,1);
plot(x1,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,2);
plot(f1,fft_x1);
subplot(4,2,3);
plot(x2,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,4);
plot(f2,fft_x2);
subplot(4,2,5);
plot(x3,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,6);
plot(f3,fft_x3);
subplot(4,2,7);
plot(x4,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,8);
plot(f4,fft_x4);

Number of Period

See following plots. As you see in (a), (b), (c), (d), the total of the fft data (signal + zero padding) are all the sam
But the number of cycles of the signal are different. Just try to 'feel' or 'sense' the general trand. what kind of
difference you see in the fft plot as the length of appended zero gets increased ? Do you see the peak gets higher
sharper as the number of signal cycles gets larger ?

Try following Octave/Matlab code and play with following lines marked in blue.
n = [0:29];
x = cos(2*pi*n/10);
x1
x2
x3
x4

=
=
=
=

[x
[x
[x
[x

fft_x1
fft_x2
fft_x3
fft_x4
f1
f2
f3
f4

=
=
=
=

=
=
=
=

zeros(1,256-1*length(x))];
x zeros(1,256-2*length(x))];
x x zeros(1,256-3*length(x))];
x x x zeros(1,256-4*length(x))];
abs(fft(x1));
abs(fft(x2));
abs(fft(x3));
abs(fft(x4));

[0:length(fft_x1)-1]/length(fft_x1);
[0:length(fft_x2)-1]/length(fft_x2);
[0:length(fft_x3)-1]/length(fft_x3);
[0:length(fft_x4)-1]/length(fft_x4);

subplot(4,2,1);
plot(x1,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,2);
plot(f1,fft_x1); axis([0 1 0 60]);
subplot(4,2,3);
plot(x2,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,4);
plot(f2,fft_x2); axis([0 1 0 60]);
subplot(4,2,5);
plot(x3,'r-'); axis([0 length(x4) -1.5 1.5]);

subplot(4,2,6);
plot(f3,fft_x3); axis([0 1 0 60]);
subplot(4,2,7);
plot(x4,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,8);
plot(f4,fft_x4); axis([0 1 0 60]);

Abrupt Changes in Time Domain Data

See following plots. As you see in (a), (b), (c), (d), the total of the fft data (signal + zero padding) are all the sam
But the number of cycles of the signal are also same. Then what is the difference ?
Comparing (a) and (b), you would notice a sudden phase change in the middle of the signal (b). This abrupt chang
created the distortion in fft as shown in (b_f).
Comparing (a) and (c), you would notice (c) is rectangular form of signal meaning that there are abrupt amplitude
changes at rising and falling edges of the pulses. But in this case, this abrupt change does not create any distortio
fft plot. In stead, it creates a couple of additional peaks in fft (c_f). If you study only a little bit of Fourier Series, y
would understand why these additional peaks show up.
Comparing (c) and (d), you would notice a sudden phase change in the middle of the signal (d). This abrupt chang
created the distortion in fft as shown in (d_f).

Try following Octave/Matlab code and play with following lines marked in blue.
n = [0:29];
x = cos(2*pi*n/10);
x1
x2
x3
x4

=
=
=
=

[x x zeros(1,256-2*length(x))];
[x -x zeros(1,256-2*length(x))];
[sign(x) sign(x) zeros(1,256-2*length(x))];
[sign(x) -sign(x) zeros(1,256-2*length(x))];

fft_x1
fft_x2
fft_x3
fft_x4
f1
f2
f3
f4

=
=
=
=

=
=
=
=

abs(fft(x1));
abs(fft(x2));
abs(fft(x3));
abs(fft(x4));

[0:length(fft_x1)-1]/length(fft_x1);
[0:length(fft_x2)-1]/length(fft_x2);
[0:length(fft_x3)-1]/length(fft_x3);
[0:length(fft_x4)-1]/length(fft_x4);

subplot(4,2,1);
plot(x1,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,2);
plot(f1,fft_x1); axis([0 1 0 40]);
subplot(4,2,3);
plot(x2,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,4);
plot(f2,fft_x2); axis([0 1 0 40]);
subplot(4,2,5);
plot(x3,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,6);
plot(f3,fft_x3); axis([0 1 0 40]);
subplot(4,2,7);
plot(x4,'r-'); axis([0 length(x4) -1.5 1.5]);
subplot(4,2,8);
plot(f4,fft_x4); axis([0 1 0 40]);

FFT for Complex Number


In all the examples described above, the signal (the input value to FFT process) was all real value. But in most of
situation, we use the signals presented as a sequence number of complex numbers.

In this section, we will see the difference between FFT for real values and FFT for complex values. First, I created
script for various experiments in this section. By changing a,b,p1,p2, I will create many different cases to think ab
n = [0:256];
a = 1.0;
b = 0.8;
p1 = 0.0;
p2 = 0.2*pi;
x = a*cos(2*pi*n/20+p1) + j*b*sin(2*pi*n/20+p2);

x1 = [real(x)];
x2 = [imag(x)];
x3 = [x];
fft_x1 = fft(x1);
fft_x2 = fft(x2);
fft_x3 = fft(x3);
fft_x1_abs = abs(fft_x1);
fft_x2_abs = abs(fft_x2);
fft_x3_abs = abs(fft_x3);
fft_x1_arg = arg(fft_x1);
fft_x2_arg = arg(fft_x2);
fft_x3_arg = arg(fft_x3);
f1 = [0:length(fft_x1)-1]/length(fft_x1);
f2 = [0:length(fft_x2)-1]/length(fft_x2);
f3 = [0:length(fft_x3)-1]/length(fft_x3);
subplot(4,3,1);
plot(x1,'r-'); axis([0 length(x3) -1.5 1.5]);
subplot(4,3,4);
plot(x1([1:length(x1)/8]),'r-'); axis([0 length(x1)/8 -1.5 1.5]);
subplot(4,3,7);
plot(f1,fft_x1_abs);axis([0 1 0 300]);
subplot(4,3,10);
plot(f1([1:length(x1)/8]),fft_x1_abs([1:length(x1)/8]));axis([0 1/8 0 300]);
subplot(4,3,2);
plot(x2,'b-'); axis([0 length(x3) -1.5 1.5]);
subplot(4,3,5);
plot(x2([1:length(x2)/8]),'b-'); axis([0 length(x2)/8 -1.5 1.5]);
subplot(4,3,8);
plot(f2,fft_x2_abs);axis([0 1 0 300]);
subplot(4,3,11);
plot(f2([1:length(x2)/8]),fft_x2_abs([1:length(x2)/8]));axis([0 1/8 0 300]);

subplot(4,3,3);
plot(real(x3),'r-',imag(x3),'b-'); axis([0 length(x3) -1.5 1.5]);
subplot(4,3,6);
plot(real(x3([1:length(x3)/8])),'r-',imag(x3([1:length(x3)/8])),'b-'); axis([0 length(x2)/8 -1.5 1.5]);
subplot(4,3,9);
plot(f2,fft_x3_abs);axis([0 1 0 300]);
subplot(4,3,12);

plot(f3([1:length(x3)/8]),fft_x3_abs([1:length(x3)/8]));axis([0 1/8 0 300]);


< Complex Number FFT - Example 1 >

First, I created a sample signal, the real part of which is cos() graph and the imaginary part of which is sin() curve
The a,b,p1,p2 value to create this example is as follows.

a = 1.0;
b = 1.0;
p1 = 0.0;
p2 = 0.0
You see three columns A,B,C. A is a real value sequence created by a*cos(2*pi*n/20+p1), B is also a real value
sequence created by b*sin(2*pi*n/20+p2) and C is a complex value sequence created by a*cos(2*pi*n/20+p1) +
j*b*sin(2*pi*n/20+p2). Since 'C' signal is made up of pure 'sin' (sin() with no phase shift) and pure cos (cos() wit
no phase shift) the arg of the complex value (the phase difference between the real part and imaginary part) is
exactly 90 degree (pi/4) as indicated as 'p' in Column 'C', row (c) plot.
Now the most important part is the graphs on row (c). What do you think the differences among the three graphs
row (c) ? At the first two graphs which are both the result of FFT of real value sequence, you see two peaks, but in
third graph which is the result of FFT of a complex value sequence, you see only one peak.
Is there any other differences except the number of peaks in FFT plot ? You can find another difference in graphs o
row (d). You will notice that the height of the peak of complex valued FFT is much greater than the height of the p
of real valued FFT. How big is it ? In conclusion, in this specific case the height of peak on (column C, row d) is twi
as high as (column A, row d) or (column B, row d).
Then you would have question that comes naturally. What is the meaning (implication) of these differences (i.e, si
of peak difference or number of peak differences) ? For now, I don't know how to explain this difference easily... b
will get back to this question later. How much 'later' ? I don't know for now -:). Try find your own answer in the
meantime -:)

< Complex Number FFT - Example 2 >

Now let me have a question. If a signal is made up of any form of complex numbers, does it produce only ONE pe
as we saw in previous example ?
Let's look at the following example to find the answer to this question. I set the variables for my script as follows.
(You would notice I set a non-zero value for p2).
a = 1.0;
b = 1.0;
p1 = 0.0;
p2 = 0.2*pi;
You see three columns A,B,C. A is a real value sequence created by a*cos(2*pi*n/20+p1), B is also a real value
sequence created by b*sin(2*pi*n/20+p2) and C is a complex value sequence created by a*cos(2*pi*n/20+p1) +
j*b*sin(2*pi*n/20+p2). Since 'C' signal is made up of pure 'sin' (sin() with no phase shift) and cos (in this case th
cos() has a phase shift defined by p2). Now the arg of the complex value (the phase difference between the real p
and imaginary part) is not exactly 90 degree (pi/4) as indicated as 'p' in Column 'C', row (c) plot.

Now let's look into the graphs on row (c). What do you think the differences among the three graphs on row (c) ?
Even though the phase of signal B has been changed, the fft graph for the data doesn't seem to be changed in an
way at least in terms of number of peaks or the height of the peak.
But you would notice a big difference between this example and previous example. It is that now even the fft of th
complex signal has another peak even though the size of the peak is much smaller than the first peak. You may
'sense' this second peak would be related to the arg changes of the complex value data. To have more concrete
'feeling', try change p1, p2 into various different value and run the script.

Is there any other differences except the number of peaks in FFT plot ? You can find another difference in graphs o
row (d). You will notice that the height of the peak of complex valued FFT is much greater than the height of the p
of real valued FFT. How big is it ? But in this case, the large peak of colum C does not seem to be exactly twice as
high as (column A, row d) or (column B, row d). If you compare the result of various trials of changing p1, p2, you
have some 'feeling' about the size of peak changes. I will leave this to you.

< Complex Number FFT - Example 3 >

Let's make another question. What if I change the amplitude of real or imaginary part of the complex signal witho
introducing any phase shift ?
My trial parameter is as follows. You should notice that a and b is not the same now.
a = 1.0;
b = 0.8;
p1 = 0.0;
p2 = 0.0;
You see three columns A,B,C. A is a real value sequence created by a*cos(2*pi*n/20+p1), B is also a real value
sequence created by b*sin(2*pi*n/20+p2) and now the amplitude of b*sin(2*pi*n/20+p2) is smaller than
a*cos(2*pi*n/20+p1). C is a complex value sequence created by a*cos(2*pi*n/20+p1) + j*b*sin(2*pi*n/20+p2)
signal is made up of pure 'sin' (sin() with no phase shift) and cos. Amplitude of real part and amplitude of imagina
part is not same as you see in m1,m2 in the graph (column C, row (b)). Now the arg of the complex value (the ph
difference between the real part and imaginary part) is not exactly 90 degree (pi/4) as indicated as 'p' in Column
row (c) plot.

Now let's look into the graphs on row (c). What do you think the differences among the three graphs on row (c) ?
Even though the phase of signal B has been changed, the fft graph for the data doesn't seem to be changed in an
way at least in terms of number of peaks or the height of the peak.
But you would notice a big difference between this example and previous example. It is that now even the fft of th
complex signal has another peak even though the size of the peak is much smaller than the first peak. You may
'sense' this second peak would be related to the arg changes of the complex value data. To have more concrete
'feeling', try change a, b into various different value and run the script.

Is there any other differences except the number of peaks in FFT plot ? You can find another difference in graphs o
row (d). You will notice that the height of the peak of complex valued FFT is much greater than the height of the p
of real valued FFT. How big is it ? But in this case, the large peak of colum C does not seem to be exactly twice as
high as (column A, row d) or (column B, row d). If you compare the result of various trials of changing a, b, you w
have some 'feeling' about the size of peak changes. I will leave this to you.

< Complex Number FFT - Example 4 >

In previous examples, we saw how separate changes in the amplitude and phase of the complex value data affect
result of FFT. Now let's change both amplitude and phase at the same time see how it influence fft result.
My trial parameter is as follows. You should notice that a and b is not the same now. p1 and p2 is not the same
either .
a = 1.0;
b = 0.8;
p1 = 0.0;
p2 = 0.2*pi;

You see three columns A,B,C. A is a real value sequence created by a*cos(2*pi*n/20+p1), B is also a real value
sequence created by b*sin(2*pi*n/20+p2) and now the amplitude of b*sin(2*pi*n/20+p2) is smaller than
a*cos(2*pi*n/20+p1). C is a complex value sequence created by a*cos(2*pi*n/20+p1) + j*b*sin(2*pi*n/20+p2)
signal is made up of pure 'sin' (cos() with no phase shift) and 'sin'(sin() with phase shift). Now the arg of the com
value (the phase difference between the real part and imaginary part) is not exactly 90 degree (pi/4) as indicated
'p' in Column 'C', row (c) plot. and Amplitude of real part and imaginary part is also different.
Now let's look into the graphs on row (c). What do you think the differences among the three graphs on row (c) ?

Even though the phase of signal B has been changed, the fft graph for the data doesn't seem to be changed in an
way at least in terms of number of peaks or the height of the peak.
But you would notice a big difference between this example and previous example. It is that now even the fft of th
complex signal has another peak even though the size of the peak is much smaller than the first peak. You may
'sense' this second peak would be related to the arg changes of the complex value data. To have more concrete
'feeling', try change a, b and p1,p2 into various different value and run the script.

Is there any other differences except the number of peaks in FFT plot ? You can find another difference in graphs o
row (d). You will notice that the height of the peak of complex valued FFT is much greater than the height of the p
of real valued FFT. How big is it ? But in this case, the large peak of colum C does not seem to be exactly twice as
high as (column A, row d) or (column B, row d). If you compare the result of various trials of changing a, b and p1
you will have some 'feeling' about the size of peak changes. I will leave this to you.

Phase of FFT

If you look carefully into the mathemtical formual for fourier transform, you would notice exp(-i t) part which is a
complex number) and this part applies to every point of the input data. Therefore, the result of FFT is always a
sequence of complex number regardless of whether the fft input is real number or complex number. It means each
data point (a complex number) in fft result has it's own magnitue and phase. All the fft graph shown in previous
sections is based on the magnitude of the fft result, but there are some cases where not only the magnitude part
also phase (arg or angle) part is important. (One example for this kind of case is 'filter design'). In this case, we
normaly use both magnitude plot and phase plot to characterize the fft result.
In this section, we would see how the phase value of fft can be represented. To see how most of the mathmatical
software represent phase (angle), let's start with a simple and rotating complex value sequence as shown below.

(a) shows the graph of the complex value sequence. Red curve represent the real part and blue curve represent th
imaginary part.
(c) shows the graph of the complex value in polar cordinate (or parametric coordinate). As you see, this complex
sequence continuously rotating. It means the angle part just keep increasing continuously. But if you plot the phas
(angle) in cartesian coordinate (rectangular) plot, you would see abrupt phase changes periodically as shown in (b
This is because of the way the computer software calcuate the phase (angle) of the complex number. So you shou
be careful about interpreting the phase values of the fft result. Especially when you see an abrupt phase changes
(discontinuity of the phase value), you have to think about whether it is the discontinuity from the nature of input
data or computer algorithm calculating the phase value.

For you intuitive understanding and various experiment, I wrote a small Octave (or Matlab) script as shown below
Just hange the value of a,b,p1,p2 and x (formula for signal generation) and see how the phase plot varies. As I al
say, try as much as possible and try to make your own understanding.
n = [0:256];
a = 1.0;
b = 1.0;
p1 = 0.0;
p2 = 0.0;
x = a*cos(2*pi*n/20+p1) + j*b*sin(2*pi*n/20+p2);
subplot(5,1,1);
plot(real(x),'r-',imag(x),'b-'); axis([0 length(x) -1.5 1.5]);
subplot(5,1,2);

plot(arg(x),'r-'); axis([0 length(x) -pi pi]);


subplot(5,1,[3 4]);
plot(real(x([1:21])),imag(x([1:21])),'b-',real(x([1:21])),imag(x([1:21])),'rx'); axis([-1.5 1.5 -1.5 1.5]);
subplot(5,1,5);
plot(arg(x([1:21])),'b-',arg(x([1:21])),'rx'); axis([0 21 -pi pi]);

Followings are just several examples that I tried and I would not explain much about this. Just take a look and ha
some feeling.

With the feeling (or some sense) you formed from previous example, let's see the result of the fft for the data we
used in previous sections. I added the phase plot of each fft. For now, just try to have some impressions here.. I h
I can explain the meaning of these type of phase changes in filter design session in the future.

Following is the script for the above plot.


n = [0:31];
x = cos(2*pi*n/10);
x1 = x;
x2 = [x zeros(1,64-length(x1))];
x3 = [x zeros(1,256-length(x1))];
fft_x1 = fft(x1);
fft_x2 = fft(x2);
fft_x3 = fft(x3);
fft_x1_abs = abs(fft_x1);
fft_x2_abs = abs(fft_x2);
fft_x3_abs = abs(fft_x3);
fft_x1_arg = arg(fft_x1);
fft_x2_arg = arg(fft_x2);
fft_x3_arg = arg(fft_x3);
f1 = [0:length(fft_x1)-1]/length(fft_x1);
f2 = [0:length(fft_x2)-1]/length(fft_x2);
f3 = [0:length(fft_x3)-1]/length(fft_x3);
subplot(5,3,1);

plot(x1,'r-'); axis([0 length(x3) -1.5 1.5]);


subplot(5,3,4);
plot(f1,fft_x1_abs);
subplot(5,3,7);
plot(f1,fft_x1_arg);axis([0 1 -pi pi]);
subplot(5,3,10);
plot(f1([1:length(f1)/4]),fft_x1_abs([1:length(f1)/4]));
subplot(5,3,13);
plot(f1([1:length(f1)/4]),fft_x1_arg([1:length(f1)/4]));axis([0 1/4 -pi pi]);
subplot(5,3,2);
plot(x2,'r-'); axis([0 length(x3) -1.5 1.5]);
subplot(5,3,5);
plot(f2,fft_x2_abs);
subplot(5,3,8);
plot(f2,fft_x2_arg);axis([0 1 -pi pi]);
subplot(5,3,11);
plot(f2([1:length(f2)/4]),fft_x2_abs([1:length(f2)/4]));
subplot(5,3,14);
plot(f2([1:length(f2)/4]),fft_x2_arg([1:length(f2)/4]));axis([0 1/4 -pi pi]);
subplot(5,3,3);
plot(x3,'r-'); axis([0 length(x3) -1.5 1.5]);
subplot(5,3,6);
plot(f3,fft_x3_abs);
subplot(5,3,9);
plot(f3,fft_x3_arg);axis([0 1 -pi pi]);
subplot(5,3,12);
plot(f3([1:length(f3)/4]),fft_x3_abs([1:length(f3)/4]));
subplot(5,3,15);
plot(f3([1:length(f3)/4]),fft_x3_arg([1:length(f3)/4]));axis([0 1/4 -pi pi]);

Effect of multiplying Exp(p i) to the signal

n = [0:31];
x = exp(j*2*pi*n/10);
x1 = [x zeros(1,256-length(x))];
x2 = x1 .* exp(j*0.25*pi);
x3 = x1 .* exp(j*0.5*pi);
fft_x1 = fft(x1);
fft_x2 = fft(x2);
fft_x3 = fft(x3);
fft_x1_abs = abs(fft_x1);
fft_x2_abs = abs(fft_x2);
fft_x3_abs = abs(fft_x3);
fft_x1_arg = arg(fft_x1);
fft_x2_arg = arg(fft_x2);
fft_x3_arg = arg(fft_x3);
f1 = [0:length(fft_x1)-1]/length(fft_x1);
f2 = [0:length(fft_x2)-1]/length(fft_x2);
f3 = [0:length(fft_x3)-1]/length(fft_x3);

subplot(5,3,1);
plot(real(x1),'r-',imag(x1),'b-'); axis([0 length(n) -1.5 1.5]);
subplot(5,3,4);
plot(f1,fft_x1_abs);
subplot(5,3,7);
plot(f1,fft_x1_arg);axis([0 1 -pi pi]);
subplot(5,3,10);
plot(f1([1:length(f1)/4]),fft_x1_abs([1:length(f1)/4]));
subplot(5,3,13);
plot(f1([1:length(f1)/4]),fft_x1_arg([1:length(f1)/4]));axis([0 1/4 -pi pi]);
subplot(5,3,2);
plot(real(x2),'r-',imag(x2),'b-'); axis([0 length(n) -1.5 1.5]);
subplot(5,3,5);
plot(f2,fft_x2_abs);
subplot(5,3,8);
plot(f2,fft_x2_arg);axis([0 1 -pi pi]);
subplot(5,3,11);
plot(f2([1:length(f2)/4]),fft_x2_abs([1:length(f2)/4]));
subplot(5,3,14);
plot(f2([1:length(f2)/4]),fft_x2_arg([1:length(f2)/4]));axis([0 1/4 -pi pi]);
subplot(5,3,3);
plot(real(x3),'r-',imag(x3),'b-'); axis([0 length(n) -1.5 1.5]);
subplot(5,3,6);
plot(f3,fft_x3_abs);
subplot(5,3,9);
plot(f3,fft_x3_arg);axis([0 1 -pi pi]);
subplot(5,3,12);
plot(f3([1:length(f3)/4]),fft_x3_abs([1:length(f3)/4]));
subplot(5,3,15);
plot(f3([1:length(f3)/4]),fft_x3_arg([1:length(f3)/4]));axis([0 1/4 -pi pi]);

Effect of Multiplying Exp(f t i) to the signal

n = [0:31];
x = exp(j*2*pi*n/10);
x1 = [x zeros(1,256-length(x))];
x2 = [x .* exp(j*0.1*pi*n) zeros(1,256-length(x))];
x3 = [x .* exp(j*0.2*pi*n) zeros(1,256-length(x))];
fft_x1 = fft(x1);
fft_x2 = fft(x2);
fft_x3 = fft(x3);
fft_x1_abs = abs(fft_x1);
fft_x2_abs = abs(fft_x2);
fft_x3_abs = abs(fft_x3);
fft_x1_arg = arg(fft_x1);
fft_x2_arg = arg(fft_x2);
fft_x3_arg = arg(fft_x3);
f1 = [0:length(fft_x1)-1]/length(fft_x1);
f2 = [0:length(fft_x2)-1]/length(fft_x2);
f3 = [0:length(fft_x3)-1]/length(fft_x3);
subplot(5,3,1);

plot(real(x1),'r-',imag(x1),'b-'); axis([0 length(n) -1.5 1.5]);


subplot(5,3,4);
plot(f1,fft_x1_abs);
subplot(5,3,7);
plot(f1,fft_x1_arg);axis([0 1 -pi pi]);
subplot(5,3,10);
plot(f1([1:length(f1)/4]),fft_x1_abs([1:length(f1)/4]));
subplot(5,3,13);
plot(f1([1:length(f1)/4]),fft_x1_arg([1:length(f1)/4]));axis([0 1/4 -pi pi]);
subplot(5,3,2);
plot(real(x2),'r-',imag(x2),'b-'); axis([0 length(n) -1.5 1.5]);
subplot(5,3,5);
plot(f2,fft_x2_abs);
subplot(5,3,8);
plot(f2,fft_x2_arg);axis([0 1 -pi pi]);
subplot(5,3,11);
plot(f2([1:length(f2)/4]),fft_x2_abs([1:length(f2)/4]));
subplot(5,3,14);
plot(f2([1:length(f2)/4]),fft_x2_arg([1:length(f2)/4]));axis([0 1/4 -pi pi]);
subplot(5,3,3);
plot(real(x3),'r-',imag(x3),'b-'); axis([0 length(n) -1.5 1.5]);
subplot(5,3,6);
plot(f3,fft_x3_abs);
subplot(5,3,9);
plot(f3,fft_x3_arg);axis([0 1 -pi pi]);
subplot(5,3,12);
plot(f3([1:length(f3)/4]),fft_x3_abs([1:length(f3)/4]));
subplot(5,3,15);
plot(f3([1:length(f3)/4]),fft_x3_arg([1:length(f3)/4]));axis([0 1/4 -pi pi]);

Potrebbero piacerti anche