Confused with fft Matlab - matlab

I am little bit confused with fft. That would be good if anyone can help me. first, I want to convert fft output in time domain. Where t = f/k and K = BW/Tm (BW = bandwidth & Tm = transmit time). After that again i need to take fft and ouput should be box (rectangular function) which is having width of BW(40e9).
f1 = 1e6; % first cutoff frequency
f2 = 4e6; % second cutoff frequency
BW = 40e9; % bandwidth
Tm = 0.2e-3; % transmit time
fs = 1e7; % sampling frequency
c = 3e8; % speed of light
w1 = f1/ (fs/2); % normalizing first cutoff frequency
w2 = f2/ (fs/2): % normalizing second cutoff frequency
[b,a] = butter(2, [w1,w2], 'bandpass');
load('fb2040');
x = fb2040(3,:);
y_filt = filter(b,a,x); % filtering
nfft = length(y_filt);
res = fft(y_filt, nfft)/ nfft;
f = fs/2 * linspace(0,1,nfft/2+1);
res = res(1:nfft/2+1);
figure, plot(f,abs(res));
xlabel('frequency in MHz');
ylabel('amp');
return

Related

FFT Not Getting Expected Results And Too Much Noise

Here's my code:
close all;clc;clear all;
f=fopen ('sum_021223.txt');
Adata=cell2mat(textscan(f, '%f %f %f %f %f'));
time=Adata(:,5);
data = Adata;
data(:,5:end) = 0;
final=size(data,1);
data(1,1)=data(2,1);
testsum=sum(data,2);
Fs = .5; % Sampling frequency
T = 1/Fs; % Sampling period
L = final; % Length of signal
t = (0:L-1)*T;
t=t';
Y=fft(testsum)
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
% P1(1,1)=P1(2,1);
plot(f,P1)
title("Single-Sided Amplitude Spectrum of X(t)")
xlabel("f (Hz)")
ylabel("|P1(f)|")
I believe I setup my code correct. I am sampling data once per 2 seconds. I have 30530 rows of data (About 17 hours worth)
However my FFT just looks like a bunch of noise, and I would expect some spikes around the smaller frequencies that would represent changes in air temperature and such over the day I took the data.
The input data on Dropbox.
I tried to set P1(1,1) to be equal to P1(2,1). This somewhat helped, but not really.
Your FFT looks corect, you have a very noisy data. You can maybe plot a power spectrum of that signal. You can distinguish different parts in the signal, here is function:
close all;clc;clear all;
f=fopen ('sum_021223.txt');
Adata=cell2mat(textscan(f, '%f %f %f %f %f'));
time=Adata(:,5);
data = Adata;
data(:,5:end) = 0;
final=size(data,1);
data(1,1)=data(2,1);
testsum=sum(data,2);
Fs = .5; % Sampling frequency
T = 1/Fs; % Sampling period
L = numel(testsum); % Length of signal
t = (0:L-1)*T;
t=t';
[f,y]=MyPower(testsum,Fs);
plot(f,y)
title("Single-Sided Amplitude Spectrum of X(t)")
xlabel("f (Hz)")
ylabel("|P1(f)|")
ylim([0,6e-3]);
function [f,y]=MyPower(y,freq)
tuReal = "seconds";
samples=numel(y);
period=1/freq;
time=linspace(0,samples*period,samples)';
signal=y;
Fs=freq;
% Compute effective sampling rate.
tNumeric = time2num(time,tuReal);
[Fs,irregular] = effectivefs(tNumeric);
Ts = 1/Fs;
% Resample non-uniform signals.
x = signal;
if irregular
x = resample(x,tNumeric,Fs,'linear');
end
% Set Welch spectrum parameters.
L = fix(length(x)/4.5);
noverlap = fix(L*50/100);
win = window(#hamming,L);
% Compute the power spectrum.
[ps,f] = pwelch(x,win,noverlap,[],Fs);
w = 2*pi*f;
% Convert frequency unit.
factor = funitconv('rad/TimeUnit', 'Hz', 'seconds');
w = factor*w;
Fs = 2*pi*factor*Fs;
% Remove frequencies above Nyquist frequency.
I = w<=(Fs/2+1e4*eps);
w = w(I);
ps = ps(I);
% Configure the computed spectrum.
ps = table(w, ps, 'VariableNames', ["Frequency", "SpectrumData"]);
ps.Properties.VariableUnits = ["Hz", ""];
ps = addprop(ps, {'SampleFrequency'}, {'table'});
ps.Properties.CustomProperties.SampleFrequency = Fs;
f=ps.Frequency;
y=ps.SpectrumData;
end

Matlab FFT: Power Spectral Density or Amplitude Spectral Density?

The amplitude of a FFT should be depending on the length of the signal.
To display the result in a independent way the Power Spectral Density or the Amplitude Spectral Density should be used. There are calculated as follows:
Amplitude FFT = Y
Signal Length = L
Power Spectral Density PSD = Y^2/L
Amplitude Spectral Density ASD = Y/sqrt(L)
https://www.sjsu.edu/people/burford.furman/docs/me120/FFT_tutorial_NI.pdf
My problem is, that the result of the Matlab fft is already indipendent from the signal length and I do not understand if this is already a PSD or a ASD.
Let's take the Matlab example Noisy Signal: https://ch.mathworks.com/help/matlab/ref/fft.html
If we make the FFT on the same signal, but twice or ten times longer, the FFT amplitude does not change.
This because of the line:
P2 = abs(Y/L);
where the amplitude is divided through the signal length. But why is the formula different from the PSD or the ASD formula and we still obtain amplitudes indipendent from the signal length?
In this example it is shown, that the two signals, ones for 50s, ones for 500s, has almost the same amplitudes.
% Signal 1
sps = 1000; % Sampling frequency
T = 1/sps; % Sampling period
Frequency1 = 150; % frequency 1 [Hz]
SignalAmplitude1 = 1; % mm/s
Frequency2 = 45; % dominant frequency [Hz]
SignalAmplitude2 = 1.2; % mm/s
L = 50; % Length of signal, sek.
L = L*1000; % convert to ms
time = (0:L-1)*T; % Time vector
Signal = cos(2*pi*Frequency1*time)*SignalAmplitude1 + sin(2*pi*Frequency2*time)*SignalAmplitude2;
f = sps*(0:(L/2))/L;
FFTcomplex = fft(Signal);
P2 = abs(FFTcomplex)/L;
P1 = P2(:,round(1:L/2+1));
P1(:,2:end-1) = 2*P1(:,2:end-1);
Ampl_FFT_1 = P1;
% Signal 2
sps = 1000; % Sampling frequency
T = 1/sps; % Sampling period
Frequency1 = 150; % frequency 1 [Hz]
SignalAmplitude1 = 1; % mm/s
Frequency2 = 45; % dominant frequency [Hz]
SignalAmplitude2 = 1.2; % mm/s
L = 500; % Length of signal, sek.
L = L*1000; % convert to ms
time = (0:L-1)*T; % Time vector
Signal = cos(2*pi*Frequency1*time)*SignalAmplitude1 + sin(2*pi*Frequency2*time)*SignalAmplitude2;
f = sps*(0:(L/2))/L;
FFTcomplex = fft(Signal);
P2 = abs(FFTcomplex)/L;
P1 = P2(:,round(1:L/2+1));
P1(:,2:end-1) = 2*P1(:,2:end-1);
Ampl_FFT_2 = P1;
sum(Ampl_FFT_2)-sum(Ampl_FFT_1)

Optical frequency comb time to frequency domain - MATLAB

I am trying to generate ultrashort pulses and then seeing the resulting frequency comb using a fourier transform, I have used the gaussian pulse and pulse train functions to try and do this but it is not coming out correctly - I am hoping to be able to change the variables at the top to see the changes quickly
If here is a solution or any good resources that could help me I would appreciate it alot... Thanks
Code is here:
fs = 1e17 ; % sample rate
frep = 7.5e9; % repition rate
f_sig = 1.93e15; %frequency of signal
tc = gauspuls('cutoff',f_sig,100,[],-80);
t = -tc*200:1/fs:tc*200;
[x1,x2,x3] = gauspuls(t,f_sig,0.5);
figure(1);
plot(t,x1,t,x3)
xlabel('Time (s)')
ylabel('Waveform')
ts = 0:1/fs/2:tc*50000000 ;
d = 0:1/frep:tc*50000000 ; %delay
y = pulstran(ts,d,x,fs);
figure(2);
plot(ts,y)
%Frequency Comb FFT
fsamp = fs;
L= length(t); %signal length
NFFT = 2^nextpow2(L);
FFT = abs(fftshift(fft(x3,NFFT))/NFFT); %FFT with FFTshift for both negative & positive frequencies
f = fsamp*(-NFFT/2:(NFFT/2-1))/NFFT; %Frequency Vector
figure(3)
plot(f/1e9,10*log10(FFT/1e-3));
title('Magnitude of FFT');
xlabel('Frequency (GHz)');
ylabel('Magnitude |X(f)|');
%xlim([-100 100])

matlab Band-pass Filter not working

I try to simulate a noisy signal and Filter it. the signal mix some low frequency signals and some random noise. my goal is to get 14.8Hz signal.
my band-pass bandwidth is 14.7Hz to 14.9Hz.
function filteringTest
Hd = KaiserFilter;
Fs = 4000; % Sampling frequency
T = 1/Fs; % Sample time
L = 40000; % Length of signal
t = (0:L-1)*T; % Time vector
r1 = 320;
r2 = 575;
y = 50*sin(2*pi*14.8*t) + r1*sin(2*pi*14.7*t) + r2*sin(2*pi*15.1*t) + 10.1*rand(size(t));
yfilter = filter(Hd.Numerator,1,y);
plot(yfilter)
function Hd = KaiserFilter
Fs = 4000; % Sampling Frequency
N = 4096; % Order
Fc1 = 14.7; % First Cutoff Frequency
Fc2 = 14.9; % Second Cutoff Frequency
flag = 'scale'; % Sampling Flag
Beta = 0.5; % Window Parameter
% Create the window vector for the design algorithm.
win = kaiser(N+1, Beta);
% Calculate the coefficients using the FIR1 function.
b = fir1(N, [Fc1 Fc2]/(Fs/2), 'bandpass', win, flag);
Hd = dfilt.dffir(b);
my signal image is :
and filter result is :
when i try to increase Filter Order from 4096 to 32*4096 , i get this result :
why this filter do not work correct? do i chage my filtering method?
what should i do to get 14.8Hz frequency signal?
thanks.
Why is your sampling rate so high? Reduce your sampling rate and use a notch filter to take out a selective frequency. I have re-written some sections of your code:
Fs = 200;
desiredFrequency = 14.8;
[b,a] = NotchFilter(Fs, desiredFrequency)
In the filter definition, you can do this:
function [b,a] = NotchFilter(Fs,desiredFrequency)
w = desiredFrequency/(Fs/2);
[b,a] = iirnotch(w,w/400);
Now perform the filtering
y_filter = filtfilt(b,a,y);
desiredSignal = y-y_filter;
plot(desiredSignal,'LineWidth',2); hold on; plot(y,'LineWidth',2)
You'll see something like this.

Bandpass filter failing to filter unwanted frequencies in matlab

I'm making a bandpass filter and I've created a signal with some unwanted frequencies based on sinusoids:
Fs = 8e3; % Sampling Rate
fn = Fs/2; % Nyquist frequency
L = 1e3; % Length of signal
T = 1/Fs; % Sampling period
t = T*linspace(0,L,Fs); % Time domain
% Frequencies in Hz
f1 = 1500;
f2 = 700;
f3 = 2500;
f4 = 3500;
% Signal
x = 6*sin(2*pi*f1*t);
% Noise
noise = 3*sin(2*pi*f2*t)...
+ 2*sin(2*pi*f3*t)...
+ 1*sin(2*pi*f4*t);
x_noise = x + noise;
I then create a Butterworth bandpass filter:
[b,a] = butter(10,[1000 2000]/fn,'bandpass');
The signal in time and frequency space, with the bandpass response (with freqz) looks like this:
Fig. 1 Signal with corruption | Fig. 2 Frequency with bandpass response
I would've figured from here on, simply doing
xf = filter(b,a,x_noise);
would've yielded something very similar to the original signal, but alas, what I get is really far from the filtered signal with a high response far from the bandpass.
What am I doing wrong here?
Here's the full code:
clear all
Fs = 8e3; % Sampling Rate
fn = Fs/2; % Nyquist frequency
L = 1e3; % Length of signal
T = 1/Fs; % Sampling period
t = T*linspace(0,L,Fs); % Time domain
% Frequencies in Hz
f1 = 1500;
f2 = 700;
f3 = 2500;
f4 = 3500;
% Signal
x = 6*sin(2*pi*f1*t);
% Noise
noise = 3*sin(2*pi*f2*t)...
+ 2*sin(2*pi*f3*t)...
+ 1*sin(2*pi*f4*t);
x_noise = x + noise;
subplot(221);
idx = 1:round(length(t)/30);
plot(t(idx),x(idx),t(idx),x_noise(idx));
xlabel('Time (s)'); ylabel('Signal Amplitudes');
legend('Original signal','Noisy signal');
% Frequency space
f = fn*linspace(0,1,L/2+1);
X = fft(x_noise)/L;
[b,a] = butter(10,[1000 2000]/fn,'bandpass');
h = abs(freqz(b,a,floor(L/2+1)));
subplot(222);
plot(f,abs(X(1:L/2+1)),f,h*max(abs(X)));
xlabel('Freq (Hz)'); ylabel('Frequency amplitudes');
legend('Fourier Transform of signal','Filter amplitude response');
% Filtered signal
xf = filter(b,a,x_noise);
subplot(223)
plot(t(idx),xf(idx));
xlabel('Time (s)'); ylabel('Signal Amplitudes');
legend('Filtered signal');
% Filtered in frequency space
Xf = abs(fft(xf)/L);
subplot(224);
plot(f,Xf(1:L/2+1),f,h*5e-6);
xlabel('Freq (Hz)'); ylabel('Frequency amplitudes');
legend('Fourier Transform of filtered signal','Bandpass');
Your time variable t is wrong, e.g 1/(t(2)-t(1)) should give Fs but it doesn't.
Try instead:
t = T*(0:L-1);