0
$\begingroup$

Let's say the position of an object is given by simple sine function. By elementary calculus, I can calculate the acceleration in the time domain and find its Fourier transform. I can also calculate the Fourier transform of velocity and multiply it by frequency or multiply the Fourier transform of position by frequency square. All these three methods should yield the same Fourier transformed accelerations(within numerical accuracy).

Source: http://prosig.com/wp-content/uploads/pdf/blogArticles/OmegaArithmetic.pdf

However, as you can see in the attached plot the magnitude of Fourier transformed acceleration is off by orders of magnitude. Can you please point out what I am doing wrong? I understand that the peak frequency is the same but the magnitudes and overall shape of plots is worrying me. enter image description here enter image description here enter image description here

Here is my code

N =2**8
a =1
t=np.arange(N)
t = np.linspace(-100,100,N)
fs= 2
freq_normalized = rfftfreq(N)*fs

y = np.sin(a*t)
vel = np.cos(a*t)
acc = -np.sin(a*t)

fft_y = np.abs(rfft(y))
acc_y = [a*b**2 for a,b in zip(fft_y,freq_normalized)]

fft_v = np.abs(rfft(vel))
acc_v = [a*b for a,b in zip(fft_v,freq_normalized)]

acc_a = np.abs(rfft(acc))

acc_ifft_v = irfft(acc_v)
acc_ifft_y = irfft(acc_y)
acc_ifft = irfft(acc_a)

fig, ax = plt.subplots(figsize=(12, 8))
ax.spines['left'].set_position('center')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('center')
ax.spines['top'].set_color('none')
ax.spines['left'].set_smart_bounds(True)
ax.spines['bottom'].set_smart_bounds(True)
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.plot(t,y)
plt.ylabel(r'$ y $', fontsize=16)
plt.xlabel(r'$ t $', fontsize=16)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.show()



fig, ax = plt.subplots(figsize=(12, 8))
plt.title('Fourier spectrum from position')
plt.plot(freq_normalized,acc_y)
plt.ylabel(r'$ a_{\omega} $', fontsize=16)
plt.xlabel(r'$ \tilde \omega $', fontsize=16)
plt.xscale('log')
plt.yscale('log')
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()

fig, ax = plt.subplots(figsize=(12, 8))
plt.title('Fourier spectrum from velocity')
plt.plot(freq_normalized,acc_v)
plt.ylabel(r'$ a_{\omega} $', fontsize=16)
plt.xlabel(r'$ \tilde \omega $', fontsize=16)
plt.xscale('log')
plt.yscale('log')
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()

fig, ax = plt.subplots(figsize=(12, 8))
plt.title('Fourier spectrum from acceleration')
plt.plot(freq_normalized,acc_a)
plt.ylabel(r'$ a_{\omega} $', fontsize=16)
plt.xlabel(r'$ \tilde \omega $', fontsize=16)
plt.xscale('log')
plt.yscale('log')
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
$\endgroup$
  • $\begingroup$ Does the error depend on the length of the sequence you are deriving this from? $\endgroup$ – A_A Nov 22 '19 at 10:06
  • $\begingroup$ @A_A No. I mean increasing length of signal changes the amplitude value but I can always scale the output with N, but the difference in amplitudes is still few orders of magnitude. $\endgroup$ – Prav001 Nov 22 '19 at 14:32
  • $\begingroup$ That is what I had in mind, making sure that you take the $\frac{1}{N}$ factor into account. $\endgroup$ – A_A Nov 22 '19 at 15:04
0
$\begingroup$

The problem is that you are analyzing sine and cosine without using a smooth window e.g a Hanning window. Your phase range is from -100 to 100 giving 100 / $\pi$ = 31.83 periods.This means that you have a discontinuity at the end of the FFT time record. So you are not analyzing a sine or cosine as you believe. Using a Hanning window will suppress the discontinuities and give a more meaningful result.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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