0
votes

I'm trying to write a simple python script that recovers the amplitude and phase of a sine wave from it's fourier transformation.

I should be able to do this by calculating the magnitude, and direction of the vector defined by the real and imaginary numbers for the fourier transform, for a given frequency, i.e:

Amplitude_at_freq = sqrt(real_component_at_freq^2 + imag_component_at_freq^2)
Phase = arctan(imag_component_at_freq/real_component_at_freq)

Ref: 1 min 45 seconds into this video: https://www.youtube.com/watch?time_continue=106&v=IWQfj05i87g

I've written a simple python script using numpy's fft library to try and reproduce this, but despite writing out my derivation exactly as above, am failing to get the amplitude and phase, although I can recover the original frequency of my test sine wave correctly. This previous post Calculating amplitude from np.fft and this one Why FFT does not retrieve original amplitude when increasing signal length points to the same problem (where amplitude is off by factor of 2). Specifically the solution is to "multiply by 2 (half of spectrum is removed so energy must be preserved)," but I need clarification on what that means. Secondly there's no mention of my issue with recovering the phase change, and the amplitude is calculated differently from what I have here.

# Define amplitude, phase, frequency
_A = 4 # Amplitude
_p = 0 # Phase shift
_f = 8 # Frequency

# Construct a simple signal
t = np.linspace(0, 2*np.pi, 1024 + 1)[:-1]
g = _A * np.sin(_f * t + _p) 

# Apply the fourier transform
ff = np.fft.fft(g)

# Get frequency of original signal
ff_ii = np.where(np.abs(ff) > 1.0)[0][0] # Just get one frequency, the other one is just mirrored freq at negative value
print('frequency of:', ff_ii)

# Get the complex vector at that frequency to retrieve amplitude and phase shift
yy = ff[ff_ii] 

# Calculate the amplitude
T = t.shape[0] # domain of x; which we will divide height to get freq amplitude
A = np.sqrt(yy.real**2 + yy.imag**2)/T 
print('amplitude of:', A) 

# Calculate phase shift
phi = np.arctan(yy.imag/yy.real) 
print('phase change:', phi)

However, the result I'm getting is:

>> frequency of: 8
>> amplitude of: 2.0
>> phase change: 1.5707963267948957

So the frequency is accurate, but I'm getting an amplitude of 2, when it should be 4, and phase change of pi/2, when it should be zero.

Is my math wrong, or is my understanding of numpy's fft implementation incorrect?

1

1 Answers

2
votes

Fourier analyses a signal as a sum of exp(i.2.pi.f.t) terms, so it sees A.sin(2.pi.f1.t) as:
-i.A/2.exp(i.2.pi.f1.t)+i.A/2.exp(-i.2.pi.f1.t),
which is mathematically equal. So in Fourier terms, you have both the positive frequency f1 and negative -f1 with complex values -A/2.i and A/2.i respectively. So each 'side' has only half the amplitude, but if you add them together (in the inverse Fourier transform) you get back amplitude A. This split in positive and negative frequency is where your missing factor 2 is if you only look at one (positive or negative) side of the spectrum. This is often done in practice because for real signals, the other half is trivial to derive given one.

Look into the exact mathematics Euler's formula and Fourier transform.