I am trying to get the frequency response of any transfer functions using the Fourier transform of the impulse response of the system. It works pretty well for most of the cases tested but I still have a problem with transfer functions in which there is an integrator (e.g. 1/s ; (4s+2)/(3s^2+s) etc.).
Let's take the example of a pure integrator with H(s) = 1/s. The impulse response obtained is a step function as expected but then, the Fourier transform of the impulse response does not give the expected theoretical results. Instead it gives really small results and do not lead to the classic characteristics of an integrator (-20dB/decade magnitude and -90deg phase) after processing.
Maybe a few lines of codes can be helpful if I was not clear enough:
h = tf(1,[1 0]);
t_step = .1;
t = [0 : t_step : 100000]';
[y,t1] = impulse(h,t);
y_fft = fft(y);
Do you know where this problem may come from? If you need further information, please let me know. I am working on MATLAB R2013b.
As mentioned in my comment, the problem is related to:
fft assumes a periodic signal, i.e. an infinite repetition of the provided discrete signal
you should also include the response for negative times, i.e. before the pulse occured.
h = tf(1,[1 0]);
t_step = 1;
t = [0 : t_step : 999]';
[y,t1] = impulse(h,t);
y = [y; zeros(1000, 1)];
y_fft = fft(y);
figure
semilogx(db(y_fft(1:end/2)), 'r.');
figure
semilogx(180/pi*angle(y_fft(y_fft(1:end/2)~=0)), 'r');
Further remarks
Note that due to the periodicity of the fft (and y), half of the values are minus infinity, which I did not plot to obtain a nicer result.
Note that the effect of the difference between the fft and the continuous fourier transform depends on the real fourier transform of the impulse response. Especially aliasing may be a problem.
Related
I want to plot bode diagram of the following system both using bode and fft:
%// System info
num=[0 1]; %// Numerator of z-transform of impulse response of system
den=[1 -0.8]; %// Denominator of z-transform of impulse response of system
I used dbode to plot bode method:
figure(6); dbode(num,den,1) %// 1 is sampling time Ts
As I want to do it from fft method, it gets wrong:
Ts=1;
Fs=1/Ts;
L=length(ym);
NFFT = 2^nextpow2(L); %// Next power of 2 from length of ym
H2=fft(ym,NFFT)./fft(u,NFFT);
f=Fs/2*linspace(0,1,NFFT/2+1);
ww=f*2*pi;
figure(7)
semilogx(20*log10(abs(H2(1:NFFT/2+1))))
figure(10)
semilogx((180/pi)*angle(H2(1:NFFT/2+1)))
Bode diagram using bode:
Any idea
Here is my data (u and ym)
I looked at your data and compared it with the theoretical transfer function in the time-domain and it isn't a bad fit if you ignore some of the data:
t = 1:length(u);
num=[0 1]; %// Numerator of z-transform of impulse response of system
den=[1 -0.8]; %// Denominator of z-transform of impulse response of system
H = tf(num,den,1)
[yy,tt,xx] = step(H,max(t));
plot(t-10,ym-2.2,tt,yy)
You'll notice that I have discarded the time values before 10 and shifted the response values down by about 2.2. This gives the following plot (in Octave):
I suggest you do the same thing when taking the FFT:
L = length(ym(t>=10));
NFFT = 2^nextpow2(L);
H2 = fft(ym(t>=10)-2.2,NFFT)./fft(u(t>=10),NFFT);
f=Fs/2*linspace(0,1,NFFT/2+1);ww=f*2*pi;
[mag,ph,w ] = bode(H);
semilogx(ww,20*log10(abs(H2(1:NFFT/2+1))),w,20*log10(abs(mag)))
The DC level of the transfer function is correct, but the poor FFT technique yields too much noise at (relatively) higher frequencies. tfestimate would be a better choice to estimate the transfer based on the measurement data (again remember to pre-process the data the same way as I have just done here). It is part of the Signal Processing Toolbox.
I'm in the process attempting to convolve and export an audio signal y(t) with a frequency response h(t) in different ways for a MATLAB project. It's been straightforward for the most part, however, I've run into difficulty when trying to convolve the signals using the Convolution Theorem.
I'm able to take the Fourier Transforms of both signals easily using the fft() function, but when I multiply those two results together then use the ifft() functionto find my final signal, the program always outputs garbage. I've tried playing around with padding the input with zeros, but it hasn't done much.
Here's the gist of the code I have at the moment (plot functions were removed for readability).
Y = fft(y);
H = fft(h);
F = Y*H;
f = ifft(F);
For those who are interested, the audio file is a 38 second long .wav file with a sample rate of 22050. The impulse response is the Cosine function between -pi/2 and pi/2.
Thanks in advance, any help is greatly appreciated.
I am a bit rusty with the Convolution Theorem, so I can say something wrong; but I will highlight two things:
The product in frequency should be an element-wise multiplication, i.e.
F=Y.*H.
The frequency response should be a cosine in frequency, not in time. I guess you want a frequency response that does low-pass filtering.
I played a bit with these ideas, and this is what I got:
clear all; close all; clc;
% Signal
load handel.mat;
%sound(y,Fs)
N = numel(y);
t = linspace(0,(N-1)/Fs,N);
% Response
H = abs(cos(linspace(0,pi,N))).';
% FFT product
Y = fft(y);
h = abs(ifft(H));
F = Y.*H;
f = abs(ifft(F));
% Plot
figure('Name','Time-domain');
subplot(3,1,1); plot(t,y); title('Signal');
subplot(3,1,2); plot(t,h); title('System');
subplot(3,1,3); plot(t,f); title('Output');
figure('Name','Frequency-domain');
subplot(3,1,1); plot(abs(Y)); title('Signal');
subplot(3,1,2); plot(abs(H)); title('System');
subplot(3,1,3); plot(abs(F)); title('Output');
% Play
sound(y,Fs);
sound(f,Fs);
In the frequency domain, it looks like the low-pass filtering is working. However, if you listen to the audio, the result for the Handel track is not amazing.
Don't forget to have a look at the good answer of Luis Mendo in here.
Here is my Matlab code to solve the second order ODE for a mass-spring-dashpot system:
function Spring
clear all;
close all;
options=odeset('RelTol',1e-6);
p0 = [1 0]; %initial position and velocity
[t,p] = ode45(#SpringFunction, [0 20], p0, options);
plot(t,p(:,1)) %plot the first column (x) vs. time
return
function pdot = SpringFunction(t,p)
c = 5; w = 2;
g = sin(t); % forcing function
pdot = zeros(size(p));
pdot(1) = p(2);
pdot(2) = g-c*p(2)-(w^2)*p(1);
return
I believe the output I am getting is wrong because for this case I think a plot of displacement vs. time should look like a sinusoid with decreasing amplitude. Instead, it looks like this:
This seems incorrect to me, but please correct me if I'm wrong. I cannot see what is incorrect in the code.
You're sinusoidally forcing a damped system so you should expect the steady state to be a sinusoid. Here's a nice vibrations tutorial (PDF) β see pp. 448β450 on damped sinusoidal forcing. Try removing the forcing or greatly reducing its amplitude. Also, it looks like you have a lot of damping. Your damping ratio, ΞΆ (zeta), appears to be c/(2*w) = 5/4. This implies that the unforced form of your system is over-damped β with no forcing you won't see oscillation.
Also, be careful using ode45 with oscillatory systems. If your system happens to be too stiff, you may either need to adjust the tolerances or use a stiff solver such as ode15s to get accurate results. You can always try using tighter tolerances to check that they yield qualitatively similar results (same period, amplitude, rate of growth/decay, etc.).
I am currently studying DSP and i'm using the Matlab software package to work my way through the the problems. I am currently just starting to attempt to learn about the fourier series and am having trouble with the following problem.
Generate an 100hz triangle wave using Fourier Series.
Now, i cant quite understand this part of the problem about using the fourier series.
I have generated a 100hz triangle wave with the following matlab code:
t = 0:1/10000:1;
f=100;
x1 = sawtooth(2*pi*f*t, 0.5);
x2 = fft(x1);
plot(t,x1);
axis([0 0.10 -1 1]);
grid on;
Now what code would i use within matlab to plot the fourier series of this triangle wave?
Thanks to anyone who may have some input for this particular problem.
I think what the question is asking is for you to figure out the 'a' and 'b' coefficients and then generate the sawtooth wave by summing sines and cosines at the appropriate frequencies. It's not too hard to find the Fourier coefficients for a sawtooth wave online, but I encourage you to work it out and use that to check your answer :)
Then do something like this
n_harmonics = 10;
n = zeros(1, n_harmonics);
a = ?; % for you to figure out - probably a function of n
b = ?; % same idea
t = linspace(0, 2*pi);
x = zeros(size(t));
for nx = 1 : n,
x = x + a(nx)*cos(nx*t) + b(nx)*sin(nx*t);
end
plot(t, x)
Note the Fourier series is not the same thing as the Fourier transform, which is what fft is estimating. Most texts on signal processing will start with the Fourier series and build on that to get to the Fourier transform. Note also that there are tons of important and subtle differences when moving from continuous time to discrete time. Again, most textbooks will probably start with continuous time and then use that as a basis to introduce the discrete-time concepts.
Hey, I am currently deleveloping a algorithm to decide wheather or not a frame is voiced or unvoiced. I am trying to use the Cepstrum to discriminate between these two situations. I use MATLAB for my implementation.
I have some problems, saying something generally about the frame, but my currently implementation looks like (I'm award of the MATLAB has the function rceps, but this haven't worked for either):
ceps = abs(ifft(log10(abs(fft(frame.*window')).^2+eps)));
Can anybody give me a small demo, that will convert the frame to the power cepstrum, so a single lollipop at the pitch frequency. For instance use this code to generate the frequency.
fs = 8000;
timelength = 25e-3;
freq = 500;
k = 0:1/fs:timelength-(1/fs);
s = 0.8*sin(2*pi*freq*k);
Thanks.
According to Wikipedia, the power cepstrum is (deep breath) the magnitude squared of the Fourier transform of the log of the magnitude squared of the Fourier transform of the signal. So I think you're looking for
function c = ceps(frame, win)
c = abs(fft(log10(abs(fft(frame.*win)).^2+eps))).^2;
Note that I changed one of your variable names because WINDOW is a predefined function in the Signal Processing Toolbox.
But, ifft and fft only differ by a scale factor, and the outer abs won't change the overall shape, so where's the lollipop right? See further down on the Wikipedia page.
A sinusoidal time input isn't going to give you an impulse in the cepstrum. The sine should yield an impulse in the spectrum, which will still be an impulse after the logmag operation, which will transform into a level shift in the cepstrum. To get something impulsive in the cepstrum, you need something periodic in the spectrum, which means you need something with multiple harmonic frequencies in the time domain. Consider, for instance, a square wave:
N = 1024;
h = hann(N, 'periodic');
f = 10;
x = sin(2*pi*f*((1:N)'-1)/N); %#'# to deal with SO formatting
s = 2*(x > 0) - 1; %# square wave
cx = ceps(x, h);
cs = ceps(s, h);
cs will have your longed-for lollipop, not cx.
There seems to always be a large component in the 0th cepstral bin. I guess this is because the logarithm operation always makes the input to the second FFT have a big level shift? Also, I don't get the idea of quefrency, I would have expected the lollipop to be at N/f. So maybe there's still something wrong with this code, or (more likely) my understanding.