hibol
hibol

Reputation: 33

FFT results Matlab VS Numpy (Python) : not the same results

I have a Matlab script to compute the DFT of a signal and plot it:

(data can be found here)

clc; clear; close all;

fid = fopen('s.txt');
txt = textscan(fid,'%f'); 

s = cell2mat(txt);

nFFT = 100;
fs = 24000;
deltaF = fs/nFFT;
FFFT = [0:nFFT/2-1]*deltaF;
win = hann(length(s));

sw = s.*win;
FFT = fft(sw, nFFT)/length(s);
FFT = [FFT(1); 2*FFT(2:nFFT/2)];
absFFT = 20*log10(abs(FFT));

plot(FFFT, absFFT)
grid on

I am trying to translate it to Python and can't get the same result.

import numpy as np
from matplotlib import pyplot as plt

x = np.genfromtxt("s.txt", delimiter='  ')

nfft = 100
fs = 24000
deltaF = fs/nfft;
ffft = [n * deltaF for n in range(nfft/2-1)]
ffft = np.array(ffft)
window = np.hanning(len(x))

xw = np.multiply(x, window)
fft = np.fft.fft(xw, nfft)/len(x)
fft = fft[0]+ [2*fft[1:nfft/2]]
fftabs = 20*np.log10(np.absolute(fft))

plt.figure()
plt.plot(ffft, np.transpose(fftabs))
plt.grid()

The plots I get (Matlab on the left, Python on the right):

enter image description here

What am I doing wrong?

Upvotes: 3

Views: 11863

Answers (3)

hibol
hibol

Reputation: 33

I found out that using np.fft.rfft instead of np.fft.fft and modifying the code as following does the job :

import numpy as np
from matplotlib import pyplot as pl

x = np.genfromtxt("../Matlab/s.txt", delimiter='  ')

nfft = 100
fs = 24000
deltaF = fs/nfft;
ffft = np.array([n * deltaF for n in range(nfft/2+1)])
window = np.hanning(len(x))

xw = np.multiply(x, window)
fft = np.fft.rfft(xw, nfft)/len(x)
fftabs = 20*np.log10(np.absolute(fft))

pl.figure()
pl.plot(np.transpose(ffft), fftabs)
pl.grid()

The resulting plot : right result with Python

I can see that the first and the last points, as well as the amplitudes are not the same. It isn't a problem for me (I am more interested in the general shape), but if someone can explain, I'd be happy.

Upvotes: 0

ymmx
ymmx

Reputation: 4967

Both codes are different in one case you concatenate two lists

FFT = [FFT(1); 2*FFT(2:nFFT/2)];

in the matlab code

in the other you add the first value of fft with the rest of the vector

fft = fft[0]+ [2*fft[1:nfft/2]]

'+' do not concatenate here because you have numpy array

In python, it should be:

fft = fft[0:nfft/2]
fft[1:nfft/2] =  2*fft[1:nfft/2]

Upvotes: 3

I am not a Mathlab user so I am not sure but there are few things I'd ask to see if I can help you.

You called np.array after array has been made (ffft). That probably will not change the nature of array as well as you hoped, perhaps it would be better to try to define it inside np.array(n * deltaF for n in range(nfft/2-1)) I am not sure of formatting but you get the idea. The other thing is that the range doesn't seem right to me. You want it to have a value of 49?

Another one is the fft = fft[0]+ [2*fft[1:nfft/2]] compared to FFT = [FFT(1); 2*FFT(2:nFFT/2)]; I am not sure if the comparsion is accurate or not. It just seemed to be a different type of definition to me?

Also, when I do these type of calculations, I 'print' out the intermediate steps so I can compare the numbers to see where it breaks.

Hope this helps.

Upvotes: 0

Related Questions