2
$\begingroup$

I'm trying to get the fourier transform of a signal with real values, however the results I get with rfft are noiser than those with fft.

I wrote the following code:

import numpy as np
from scipy.fftpack import rfft, fft
import matplotlib.pyplot as plt
# Number of sample points

N = 600
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
f1 = 50
f2 = 80
y = np.sin( f1* 2.0*np.pi*x) + 0.5*np.sin(f2 * 2.0*np.pi*x)
yf = fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
plt.plot(xf, 2.0/N * np.abs(yf)[0:N/2])
#plt.savefig('sin.png')
plt.show()


yf2 = rfft(y)
xf2 = np.linspace(0.0, 1.0/(2.0*T), N)
plt.plot(xf2, 2.0/N * np.abs(yf2))
plt.savefig('sin2.png')
plt.show()

and I get the following results:

Fourier Transform with fft

Fourier transform with rfft

I thought that for real values I would get the same result with fft and rfft, do you know why there are some differences ?

$\endgroup$
1
  • $\begingroup$ FYI scipy.fftpack is now considered legacy, new code should use scipy.fft. $\endgroup$
    – VMMF
    Jun 15, 2023 at 15:34

1 Answer 1

2
$\begingroup$

The DFT of a real sequence is complex-valued. The array output by scipy.fftpack.rfft consists of the real part of the 0th entry, followed by the imaginary part of the 0th entry, followed by the real part of thre 1st entry, followed by the imaginary part of the 1st entry,...

Convert the output of rfft into the appropriate complex array and plot the absolute values of that array, and you will have what you seek:

yf3 = yf2[0:-2:2] + 1j*yf2[1:-1:2];
plt.plot(np.abs(yf3));
plt.show()

$\endgroup$
1
  • $\begingroup$ It works perfectly well, thank you for your clear answer $\endgroup$
    – Rhecsu
    May 14, 2020 at 23:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.