I am trying to plot the C.T. Signal Gaph (x(t)) in MATLAB for 0<=t<0.2 ms as mentioned in the below given figure. I have written the following code, but, not sure what should be the step size for time t in the graph. Any help would be highly appreciated:) Thanks!
t = 0:0.00002:0.0002;
f = 10000;
x = 4*sin(2*pi*f*t);
figure;
plot(t,x);
There seems to be a misstatement in the text. Ts is the sampling period, whereas the sampling rate is the inverse of the sampling period, Fs=1/Ts. With a Ts of 0.02 ms, that means the sampling rate is actually 50 kHz.
What's happening in the graph is that a continuous function, x(t) is being sampled by multiplying it with a pulse train, p(t). The p(t) function is composed of an infinite number of (Dirac) delta functions equally spaced by Ts seconds and goes on for infinity. The input also goes on for forever, since sin(t) is defined for all t. The concept here is to understand that by multiplying x(t) by p(t), you're getting samples of x(t) spaced out at Ts intervals.
Because both signals are infinite, you should just pick a meaningful time range for the analysis you wish to perform. In this case, it's educational, so just pick maybe a few cycles of the incoming frequency so you can see the samples. At 10kHz, the input should repeat every 0.1 ms. You should expect to see 5 samples per cycle of the sine wave (0.1 ms / (0.02 ms/sample) = 5 samples). I'd just plot it from -0.2 ms to 0.2 ms to see a few of the cycles. By adding '-o' as the plot option, you'll see 'o' markers wherever the samples were taken.
t = -0.0002:0.00002:0.0002;
f = 10000;
x = 4*sin(2*pi*f*t);
figure;
plot(t,x,'-o');
You can try changing the sampling period. For instance, try dividing it by 10.
t = -0.0002:0.000002:0.0002;
f = 10000;
x = 4*sin(2*pi*f*t);
figure;
plot(t,x,'-o');
Related
Assume I have a smooth function (represented as a vector):
x=0:0.1:1000;
y=sin(2*x);
and I want to find its periodicity - pi (or even its frequency -2 ) .
I have tried the following:
nfft=1024;
Y=fft(y,nfft);
Y=abs(Y(1:nfft/2));
plot(Y);
but obviously it doesn't work (the plot does not give me a peak at "2" ).
Will you please help me find a way to find the value "2"?
Thanks in advance
You have several issues here:
You are computing the fft of x when your actual signal is y
x should be in radians
You need to define a sampling rate and use that to determine the frequency values along the x axis
So once we correct all of these things, we get:
samplingRate = 1000; % Samples per period
nPeriods = 10;
nSamples = samplingRate * nPeriods;
x = linspace(0, 2*pi*nPeriods, nSamples);
y = sin(2*x);
F = fft(y);
amplitude = abs(F / nSamples);
f = samplingRate / nSamples*[0:(nSamples/2-1),-nSamples/2:-1];
plot(f, amplitude)
In general, you can't use an FFT alone to find the period of a periodic signal. That's because an FFT does sinusoidal basis decomposition (or basis transform), and lots of non-sinusoidal waveforms (signals that look absolutely nothing like a sinewave or single sinusoidal basis vector) can be repeated to form a periodic function, waveform, or signal. Thus, it's quite possible for the frequency of a periodic function or waveform to not show up at all in an FFT result (it's called the missing fundamental problem).
Only in the case of a close or near sinusoidal signal will an FFT reliably report the reciprocal of the period of that periodic function.
There are lots of pitch detection/estimation algorithms. You can use an FFT as a sub-component of some composite methods, including cepstrums or cepstral analysis, and Harmonic Product Spectrum pitch detection methods.
I was expecting the frequency component to be 1700 i.e. a spike at 1700 but the output shows multiple frequency:
fs = 44100;
t = 0:1/fs:0.001;
s = sin(2 * pi * 1700 * t);
subplot(211), stem(abs(fft(s))), title('abs(fft(s))')
subplot(212), stem(s), title('s')
Similarly when I tried the below code I did not got what I expected:
Fs = 8000;
dt = 1/Fs;
StopTime = 0.25;
t = (0:dt:StopTime-dt)';
Fc = 60;
x = cos(2*pi*Fc*t);
subplot(211), stem(abs(fft(x))), title('abs(fft(x))')
subplot(212), stem(x), title('x')
Why my frequency component are being displayed as multiples values as there should be exactly one frequency present in a signal in one steady sine / cos wave.
It's a single frequency, but it appears twice: positive and negative frequencies. You'll see this better with fftshift, which arranges the frequency samples so that they run from -fs/2 to fs/2:
subplot(211)
freq_axis = -fs/2+fs/numel(t):fs/numel(t):fs/2;
stem(freq_axis, abs(fftshift(fft(s))))
title('abs(fft(s))')
For example, in your first example this produces the following figure.
Note the two spikes around +1700 and -1700 Hz. Their location is not exact for two reasons:
Your time signal is of finite duration, which produces convolution with a sinc in the frequency domain. That is, the frequency spike is made wider.
The FFT gives frequency samples, and none of those samples falls exactly at +/-1700 Hz.
In your second example the time signal is longer (it contains more cycles), which reduces the width of the frequency spikes. This can be appreciated in your second figure (again the fftshift correction is needed to make the two spikes appear in symmetric frequency locations).
Since your signal is not an integer number of cycles there is a discontinuity (remember that the Fourier Transform assumes periodicity), which results in spectral leakage, which is visible as a "smearing" of the spectrum. To avoid this we usually apply a suitable window function (e.g. von Hann aka Hanning window)prior to the FFT - think of this as smoothing out the discontinuity. This reduces the smearing and makes peaks more distinct.
As noted in another answer, you also see a second peak because you're plotting the entire spectrum, and every component in the time domain has a positive and a negative frequency component in the frequency domain. For a real-valued signal the FFT is complex-conjugate symmetric in the frequency domain and so half of the spectrum is redundant. You would normally only plot N/2 values.
I have the following matlab code, and I am trying to get 64 samples of various sinewave frequencies at 16KHz sampling frequency:
close all; clear; clc;
dt=1/16000;
freq = 8000;
t=-dt;
for i=1:64,
t=t+dt;a(i)=sin(2*pi*freq*t);
end
plot(a,'-o'); grid on;
for freq = 1000, the output graph is
The graph seems normal upto 2000, but at 3000, the graph is
We can see that the amplitude changes during every cycle
Again, at 4000 the graph is
Not exactly a sinewave, but the amplitude is as expected during every cycle and if I play it out it sounds like a single frequency tone
But again at 6000 we have
and at 8000 we have
Since the sampling frequency is 16000 I was assuming that I should be able to generate sinewave samples for upto 8000, and I was expecting the graph I got at 4000 to appear at 8000. Instead, even at 3000, the graph starts to look weird
If I change the sampling frequency to 32000 and the sinewave frequency to 16000, I get the same graph that I am getting now at 8000. Why does matlab behave this way?
EDIT:
at freq = 7900
This is just an artifact of aliasing. Notice how the vertical axis for the 8kHz graph only goes up to 1.5E-13? Ideally the graph should be all zeros; what you're seeing is rounding error.
Looking at the expression for computing the samples at 16kHz:
x(n) = sin(2 * pi * freq * n / 16000)
Where x is the signal, n is the integer sample number, and freq is the frequency in hertz. So, when freq is 8kHz, it's equivalent to:
x(n) = sin(2 * pi * 8000 * n / 16000) = sin(pi * n)
Because n is an integer, sin(pi * n) will always be zero. 8kHz is called the Nyquist frequency for a sampling rate of 16kHz for this reason; in general, the Nyquist frequency is always half the sample frequency.
At 3kHz, the signal "looks weird" because some of the peaks are at non-integer multiples of 16kHz, because 16 is not evenly divisible by 3. Same goes for the 6kHz signal.
The reason they still sound like pure sine tones is because of how the amplitude is interpolated between samples. The graph uses simple linear interpolation, which gives the impression of harsh edges at the samples. However, a physical loudspeaker (more precisely, the circuitry which drives it) does not use linear interpolation directly. Instead, a small filter circuit is used to smooth out those harsh edges (aka anti-aliasing) which removes the artificial frequencies above the aforementioned Nyquist frequency.
That is problem of matlab but a nature of sampling.
16KHz sampling makes 16K (16,000) sampled data per second. 8KHz signal has 8K (8000) cycles per second. So two sample data per a cycle.
Two is minimum number of data per cycle. This is know a part of "sampling theorem".
Let try to show two cycles with three points on graph, you may understand that its impossible to show two cycles by three points. In the same way, you can't show 2N cycles by (2N-1) points.
The effect seen for 8 kHz is as all other answers already mention aliasing effects and arises due to that the sine wave for 8 kHz is sin(2*pi*n*8000*1/16000) = sin(n*pi), which is explained in Drew McGovens answer. Luckily the amplitude is not the only parameter that defines the signal. The other parameter that is required to completely define the signal is the phase. This means that when doing for fourier analysis of the signal, it is still possible to find the right frequency. Try:
close all; clear; clc;
dt=1/16000;
freq = 7300;
t=-dt;
for i=1:64,
t=t+dt;a(i)=sin(2*pi*freq*t);
end
plot(a,'-o'); grid on;
figure; plot( linspace(1,16000,1000), abs(fft(a)) );
A side comment: some people might argue against using i as index variable since that can also be used as the imagiary number i. Personally I have nothing against using i since the runtime and overhead only is affected slightly and I always uses 1i. However, just make sure to use 1i consistently for the imaginary unit then.
I have a exponentially decaying sinusoidal function which should decay in microseconds with frequency of 5 MHz.
function[t,x]=microsec(a, p, d, f)
% microsec plots an oscillatory transient voltage disturbance
% f = 5 MHz;
% a is the magnitude of oscillatory disturbance component
% p is the starting time of osillatory disturbance component in normal
% voltage
% d is the decay factor of oscillatory component
f = 5000000;
a = 1.0;
p = 0.03;
d = 55e4;
t=0:0.1e-6:0.1;
ff=50; %frequency of normal voltage
x=sin(2*pi*ff*t)+ a*(u(t-p).*(exp(-d.*(t-p)))).*sin(2*pi*f*(t));
%exponentially decaying sinusoidal...
%...transient element added to normal voltage
plot(t,x)
function y=u(t)
% unit step function needed to decide the starting time of disturbance
y=t>=0;
end
end
I expect this output:
But the resulting plot is not what I desired, it is blank up to the starting time of the disturbance:
Increasing the decay factor or oscillatory component frequency does not improve my result.
Someone told me, it is due to over-sampling. However, I didn't get help on
How to plot a graph for microseconds range i.e. a sine wave of duration 0.1 sec
With a frequency of 50Hz
And a disturbance starting at 0.03 sec
And the disturbance itself being only microseconds in duration.
The issue is the resolution of t with regard to the duration of the disturbance. It simply cannot be captured.
Change t to t=0:0.1e-8:0.1; and you will start seeing something. However, your disturbance decays so quickly compared to the underlying sine-wave that it is hard to capture. The following zoomed figure illustrates this. Please note the x-limits from 0.02999 to 0.03001:
I have a set of data that is periodic (but not sinusoidal). I have a set of time values in one vector and a set of amplitudes in a second vector. I'd like to quickly approximate the period of the function. Any suggestions?
Specifically, here's my current code. I'd like to approximate the period of the vector x(:,2) against the vector t. Ultimately, I'd like to do this for lots of initial conditions and calculate the period of each and plot the result.
function xdot = f (x,t)
xdot(1) =x(2);
xdot(2) =-sin(x(1));
endfunction
x0=[1;1.75]; #eventually, I'd like to try lots of values for x0(2)
t = linspace (0, 50, 200);
x = lsode ("f", x0, t)
plot(x(:,1),x(:,2));
Thank you!
John
Take a look at the auto correlation function.
From Wikipedia
Autocorrelation is the
cross-correlation of a signal with
itself. Informally, it is the
similarity between observations as a
function of the time separation
between them. It is a mathematical
tool for finding repeating patterns,
such as the presence of a periodic
signal which has been buried under
noise, or identifying the missing
fundamental frequency in a signal
implied by its harmonic frequencies.
It is often used in signal processing
for analyzing functions or series of
values, such as time domain signals.
Paul Bourke has a description of how to calculate the autocorrelation function effectively based on the fast fourier transform (link).
The Discrete Fourier Transform can give you the periodicity. A longer time window gives you more frequency resolution so I changed your t definition to t = linspace(0, 500, 2000).
time domain http://img402.imageshack.us/img402/8775/timedomain.png (here's a link to the plot, it looks better on the hosting site).
You could do:
h = hann(length(x), 'periodic'); %# use a Hann window to reduce leakage
y = fft(x .* [h h]); %# window each time signal and calculate FFT
df = 1/t(end); %# if t is in seconds, df is in Hz
ym = abs(y(1:(length(y)/2), :)); %# we just want amplitude of 0..pi frequency components
semilogy(((1:length(ym))-1)*df, ym);
frequency domain http://img406.imageshack.us/img406/2696/freqdomain.png Plot link.
Looking at the graph, the first peak is at around 0.06 Hz, corresponding to the 16 second period seen in plot(t,x).
This isn't computationally that fast though. The FFT is N*log(N) operations.