0

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?

Arnautovic
  • 103
  • 2
  • They are equal. Did you mean to use an even len(a)? See assert np.allclose(a_fft_analytic, a_spec_manual) – OverLordGoldDragon Apr 05 '22 at 22:35
  • 1
    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. – Arnautovic Apr 05 '22 at 22:47

1 Answers1

0

They aren't negative.

For the odd-length case, your code is already correct: assert np.allclose(a_spec_manual, a_fft_analytic).

For the even-length case, the Nyquist bin should not be doubled (briefly, it is already doubled in some sense, see link).

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.

OverLordGoldDragon
  • 8,912
  • 5
  • 23
  • 74