The Hilbert Transform of a 1D/real-valued vector signal returns the analytic signal, x, from a real data sequence, xr. The analytic signal x = xr + jxi has a real part, xr, which is the original data, and an imaginary part, xi, which contains the Hilbert transform.

hilbert uses a four-step algorithm:

1. Calculate the FFT of the input sequence, storing the result in a vector x.

2. Create a vector h whose elements h(i) have the values:

     1 for i = 1, (n/2)+1

     2 for i = 2, 3, ... , (n/2)

     0 for i = (n/2)+2, ... , n

3. Calculate the element-wise product of x and h.

4. Calculate the inverse FFT of the sequence obtained in step 3 and returns the first n elements of the result.

This algorithm was first introduced in [8]. A python implementation of this can be seen bellow:

from scipy import linalg, fft as sp_fft
import numpy as np

def hilbert(x, N=None, axis=-1):
        x = np.asarray(x)
        if np.iscomplexobj(x):
            raise ValueError("x must be real.")
        if N is None:
            N = x.shape[axis]
        if N <= 0:
            raise ValueError("N must be positive.")
        Xf = sp_fft.fft(x, N, axis=axis)
        h = np.zeros(N)
        if N % 2 == 0:
            h[0] = h[N // 2] = 1
            h[1:N // 2] = 2
            h[0] = 1
            h[1:(N + 1) // 2] = 2
        if x.ndim > 1:
            ind = [np.newaxis] * x.ndim
            ind[axis] = slice(None)
            h = h[tuple(ind)]
        x = sp_fft.ifft(Xf * h, axis=axis)
        return x 

This code was taken form Scipy implementation Scipy.signal.hilbert. I am looking to invert/reverse this process (inverse_hilbert), the best description i have found to do this is from Mathworks Inverse Hilbert Transform

Inverse Hilbert Transfrom

However the real and complex arrays currently have me at a loss not sure how this feeds into this equation, or if this is the correct equation as wikipedia has a different equation to my understanding. Anti-involution inverse

If we create a random complex signal and compute the hilbert Transform on it we get the following 2 arrays one real and one imagery. I am looking to reverse this transform any help would be appreciated.

import matplotlib.pyplot as plt

x = np.arange(0, 30, 0.1);
y = np.sin(0.05*x)+np.sin(6*x)+np.cos(3*x)  
plt.title('Complex Waveform')

Input Signal

x_a = hilbert(y)

plt.plot(x,x_a.real, label='Hilbert Real', alpha=0.5, lw=2)
plt.plot(x,x_a.imag, label='Hilbert Imag', alpha=0.5, lw=2)

Analytic Signal

Any comments here to help my under standing would be appreciated, really looking for a step by step way to reverse this transformation.

[8]: Marple, S. L. “Computing the Discrete-Time Analytic Signal via FFT.” IEEE® Transactions on Signal Processing. Vol. 47, 1999, pp. 2600–2603.


I think the confusion comes from the fact that the command hilbert in Scipy (and also in Matlab/Octave) does not just compute the Hilbert transform, but its output is the analytic signal. So if $x(t)$ is the (real-valued) input to such a function, its (complex-valued) output is


Clearly, if you want to obtain $x(t)$ from $y(t)$, you just need to take its real part.

Concerning the inverse Hilbert transform, as you've already found out, the following holds:


The relation $(2)$ holds no matter if $x(t)$ is real-valued or complex-valued. However, if you use the function hilbert on a complex-valued signal, you throw away information that cannot be retrieved, because you throw away the negative frequencies, which are not redundant for complex-valued signals (unlike for real-valued signals). So the function hilbert cannot be inverted if the signal is complex-valued.


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.