So, in iPython, I run the following,
In [1]: from pylab import *;
In [2]: x = np.array([4.,3.,2.,1.,0.,1.,2.,3.,4.]);
In [3]: rfft(x)
Out[3]:
array([ 20.00000000+0.j , 7.79085937+2.83564091j,
-0.21688142-0.18198512j, 0.50000000+0.8660254j ,
-0.07397795-0.41954982j])
The variable x
is an even function around the middle element in the array, but yet it's fft isn't entirely real as it should be. Why is that? How do I input an even function to numpy/scipy's fft function so it'll interpret it as the even function it's meant to be?
The N
samples cover a period of the signal without repeating samples (ie. without including the (N+1)st sample which is the same as the first one). To visualize this, you can match the samples with the corresponding symmetry candidate to get:
given signal : 4 3 2 1 0 1 2 3 4
periodic extension : ... 1 2 3 4 4 3 2 1 0 1 2 3 4 4 3 2 1 0 1 2 3 4 ...
symmetry : ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | |_| | | | |
| | | |_____| | | |
| | |_________| | |
| |_____________| |
|_________________|
You can also verify this by plotting your signal with:
plt.plot(np.arange(18), np.append(x, x));
plt.plot(np.array([ 4.5, 4.5]), np.array([0,5]), 'r--');
plt.plot(np.array([ 9.0, 9.0]), np.array([0,5]), 'k--');
plt.plot(np.array([13.5,13.5]), np.array([0,5]), 'r--');
plt.axis([0, 18, 0, 5]);
plt.grid(True);
plt.show();
Where the dashed black line represent the period of your signal, and the red lines the midpoint along the period. As you can see, the signal is in fact not symmetric.
So according to that convention of not repeating the first sample, to get a symmetric signal you should define your signal as:
x = np.array([4.,3.,2.,1.,0.,1.,2.,3.])
which would produce the following real-valued (within numerical precision) frequency-domain sequence with the application of rfft
:
array([ 16.00000000 +0.00000000e+00j, 6.82842712 -1.11022302e-15j, 0.00000000 -0.00000000e+00j, 1.17157288 -1.11022302e-15j, 0.00000000 +0.00000000e+00j])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With