How to apply a bandstop filter after performing FFT

How to apply a bandstop filter after performing FFT on the this data, to remove the spikes ? SC is the data matrix.
rows1 =length(SC(:,2));
incr1=1/(rows1+1)*12;
fmax1=12*(1-1/(rows1+1));
X1=[0:incr1:fmax1/2]';
Y1 = abs(fft(SC(1:rows1,2),rows1));

5 Comments

Do not do the abs() at this stage.
Now, knowing that, and knowing that the first bin is "0 Hz", you can figure out which bins in the fft cover the frequencies you want to stop. You can now zero those locations or multiply them by an fraction to diminish them; you could use a curve to diminish more towards the center of the group if you wanted. After that, take the indices of those bins, subtract 1, and apply the same curve in reverse to the bins starting from the end of the fft result. For example, you might effectively multiply the fft result by
1 1 .7 .3 .1 .6 1 1 1 [...] 1 1 1 .6 .1 .3 .7 1
Now you can ifft back.
rows1 =length(SC(:,2));
incr1=1/(rows1+1)*12;
fmax1=12*(1-1/(rows1+1));
X1=[0:incr1:fmax1/2]';
Y1 = abs(fft(SC(1:rows1,2),rows1));
Y1=Y1/rows1;
for i=1:rows1/2
per1(i,1)=1/X1(i+1,1);
end
% plot(per,Y(2:(rows/2+1),1),'marker', '*');
dd1=max(Y1(2:(rows1/2+1),1));
ddd1=(Y1(2:(rows1/2+1),1))/dd1;
plot(per1,ddd1,'marker', '*');
This is the code I am using. We need to apply a bandstop filter after performing FFT on the data (attaching the main matrix as 'SC'), to remove the spikes with a narrow bandpass filter.
After applying the bandstop filter we need to apply an inverse FFT algorithm to recreate the time-series data (filtered) from the frequency domain to the time domain.
So how would be the code?
Why is it mandatory to take abs() of the fft() ?
When you use abs() of the fft() then in order to get real-valued components back after the ifft, then you have to force the second half of the spectra to be the complex conjugate mirror of the first half... except you don't even know what phase to use.
For example:
t = linspace(0,1,100);
y = sin(2*pi*5*t + pi/7) + sin(2*pi*3*t + pi/11);
plot(t,y)
Y1 = abs(fft(y));
Y2 = ifft(Y1);
whos Y2
Name Size Bytes Class Attributes Y2 1x100 800 double
plot(t, Y2)
Wrong magnitude, wrong phase.
OK, I understood. But how to use the bandstop filter after the fft on this data.
Example:
data = randn(1, 50);
plot(data)
title('original data');
Y1 = fft(data);
bins_of_interest = 5:22;
damping = exp(-(1:length(bins_of_interest)));
Y1(bins_of_interest) = Y1(bins_of_interest) .* damping;
Y1(end+2-bins_of_interest) = conj(Y1(bins_of_interest));
back_data = ifft(Y1);
whos back_data
Name Size Bytes Class Attributes back_data 1x50 400 double
plot(back_data)
title('reconstructed')
Your bins_of_interest should be chosen according to the sampling frequency and the number of points, and which frequencies you want to filter out; one of the links I posted shows how "wide" each bin is. Your "damping" could be constant or could be any curve that is appropriate for your circumstances, in recognition that you might not be wanting to filter each frequency equally.

Sign in to comment.

Answers (0)

Categories

Tags

Asked:

on 16 Jun 2021

Commented:

on 17 Jun 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!