While working on fft in Python, I'm running into problems with the normalization of the function and calculating the squared sum of the coefficients.
My code is as follows:
import pandas as pd
import numpy as np
import scipy.fftpack
# sample points
N = 1024
# sample spacing
T = 1.0/512.0
# example function
x = np.linspace(0.0, N*T, N)
y = 1.5 * np.sin(5*2*np.pi*x) + 3 * np.sin(6*2*np.pi*x)
df = pd.DataFrame({'X': x, 'Y': y})
sumy = sum(abs(df['Y'])**2)
df['FFT (Y)'] = scipy.fftpack.fft(df['Y'])/(N/2)
df['FFT (freq)'] = scipy.fftpack.fftfreq(N, T)
sumffty = sum(abs(df['FFT (Y)'])**2)
print sumy, sumffty
According to Parseval's identity, the sums should be equal; however, they're off by a factor of 256 (sumffty being the smaller one). What am I missing?
The Parseval's identity is also called energy theorem or Rayleigh's energy theorem. The quantity [|X(ω)|2] is called the energy density spectrum of the signal x(t).
In mathematical analysis, Parseval's identity, named after Marc-Antoine Parseval, is a fundamental result on the summability of the Fourier series of a function. Geometrically, it is a generalized Pythagorean theorem for inner-product spaces (which can have an uncountable infinity of basis vectors).
In mathematics, Parseval's theorem usually refers to the result that the Fourier transform is unitary; loosely, that the sum (or integral) of the square of a function is equal to the sum (or integral) of the square of its transform.
Fourier Transforms ( scipy.fft ) Fast Fourier transforms. 1-D discrete Fourier transforms. 2- and N-D discrete Fourier transforms.
Parseval's theorem states that the total power in the two domains (space/time and frequency) are equal. Its statement, for DFT is this. Notice, that in spite of the 1/N on the right, this is not mean power, but total power. The reason for the 1/N is the normalization convention for the DFT.
Put in Python, this means that for a time/space signal sig
, Parseval equivalence may be stated as:
np.sum(np.abs(sig)**2) == np.sum(np.abs(np.fft.fft(sig))**2)/sig.size
Below is a complete example, starting with some toy cases (one and two dimensional arrays filled one 1s). Note that I used the .size
property of numpy.ndarray, which returns the total number of elements in the array. Hope this helps!
import numpy as np
# 1-d, 4 elements:
ones_1d = np.array([1.,1.,1.,1.])
ones_1d_f = np.fft.fft(ones_1d)
# compute total power in space and frequency domains:
space_power_1d = np.sum(np.abs(ones_1d)**2)
freq_power_1d = np.sum(np.abs(ones_1d_f)**2)/ones_1d.size
print 'space_power_1d = %f'%space_power_1d
print 'freq_power_1d = %f'%freq_power_1d
I'm sorry I couldn't use your example directly--I'm not a Pandas user and couldn't understand it perfectly.
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