# Why does fourier transforming an analytic signal gives me negative frequency components?

I consider an array:

import numpy as np
from scipy.fft import fft
from scipy.signal import hilbert

a=np.random.rand(5)


First I manually compute the fourier spectrum of the analytic signal,i.e. by zeroing the negative frequency terms and doubling the positive frequency terms:

a_spec_manual = fft(a)
a_spec_manual[1:len(a)//2+1] = 2*a_spec_manual[1:len(a)//2+1]
a_spec_manual[len(a)//2+1:] = 0


Then I auto-compute the fourier transform of the analytic signal derived from a:

a_fft_analytic = fft(hilbert(a))


I was expecting a_fft_analytic to be equal to a_spec_manual. However, it is not the case. a_fft_analytic does have negative frequency components and I wonder why?

If indeed the first case is correct, is it possible to obtain the fourier spectrum of the analytic signal from real using single fft operation?

• They are equal. Did you mean to use an even len(a)? See assert np.allclose(a_fft_analytic, a_spec_manual) Apr 5, 2022 at 22:35
• I am sorry, I got confused with the negligible terms in the negative frequencies of the order of 10-17 for a_fft_analytic case. Probably these are rounding errors. However, I am actually trying to compute cross-correlations. I will edit the question and post again. Thanks for your reply. Apr 5, 2022 at 22:47

For the odd-length case, your code is already correct: assert np.allclose(a_spec_manual, a_fft_analytic).
Following your comment: yes, 1e-16 is "float zero" (and for float32 that's 1e-7). FFT takes no shortcuts (always does compute), so even "perfect" examples won't have exact zeros.