4 views (last 30 days)

Show older comments

Hi,

I have a 50 Hz high-sampled signal with 3300 Hz noise and I'm trying to use a simple and manually designed low-pass filter to remove the noise and create the pure 50 Hz signal. When I plot the pure signal after using the ifft, the amplitudes are not correct, however the noise removal seems to work. Anybody who knows what I am missing? My code is shown below:

fs = 1/0.00001; % sample rate

fsdur = 0.00001; % sample duration

freqs = linspace(0, fs/2+1, fs/2);

data=Var1(1:fs) % 1 second of data

sigfourier=fft(data)/fs

ampsigfourier=sqrt(real(sigfourier).^2+imag(sigfourier).^2)*2 % check amplitudes

PSD=sigfourier.*conj(sigfourier)*fs

% simple filter

vec=zeros(round(fs),1);

positions=[10:60];

vec(positions)=1;

newfourier=sigfourier.*vec

signalfiltered=real(ifft(newfourier))

Jonas
on 13 May 2021

David Goodmanson
on 14 May 2021

Hi Sebastian,

You appear to be treating fs in somewhat casual fashion. If fs = 1e5, then for a 1 sec pulse duration the number of samples N is also 1e5. But for any other pulse length that is not true. The code below uses sample length N, because fft and ifft make use of the sample length but know nothing about fs.

The 'signalfiltered' waveform differs from the data by a factor of 1e5 and another factor of 2.

[1] 1e5: fft and ifft are inverses of each other, so that ifft(fft(signal)) = signal. If you use sigfourier = fft(signal)/N as you did, then the ifft has to be multiplied by N to get back to the time waveform.

[2] sigfourier contains both positive and negative frequencies. The filtering process you used captured the positive frequencies but not the negative ones, which are up close to the top end of the frequency plot. Including both positve and negative frequencies in ifft gives a cosine waveform with the correct amplitude. From

cos(2*pi*f0*t) = (1/2)*(exp(2*pi*i*f0*t) + exp(-2*pi*i*f0*t))

you can see that neglecting the negative frequencies gives a complex wave of amplitude 1/2, and taking the real part gives (1/2)*cos(2*pi*f0*t).

I made some sample data but did not include any noise because the noise is not germane to the scaling. The code below shows the original code in fig(1) and the code with the rescaled variables in fig(2).

N = 1e5; fs = 1e5;

f0 = 50;

t = (1:N)/N;

data = 4.5*cos(2*pi*f0*t);

sigfourier = fft(data)/N;

% simple filter

vec = zeros(size(data));

positions = 10:60;

vec(positions) = 1;

newfourier = sigfourier.*vec;

signalfiltered = real(ifft(newfourier));

figure(1); grid on

subplot(2,1,1)

plot(data(1:6000))

subplot(2,1,2)

plot(signalfiltered(1:6000))

% version 2

vec = zeros(size(data));

positions2 = [10:60 N-60:N-10];

vec(positions2) = 1;

newfourier2 = sigfourier.*vec;

signalfiltered2 = N*real(ifft(newfourier2));

figure(2); grid on

subplot(2,1,1)

plot(data(1:6000))

subplot(2,1,2)

plot(signalfiltered2(1:6000))

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

Start Hunting!