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.")
print(x.shape,N,axis)
Xf = sp_fft.fft(x, N, axis=axis)
print(Xf.shape)
#plt.plot(Xf)
#plt.show()
h = np.zeros(N)
#plt.plot(h)
#plt.show()
if N % 2 == 0:
h[0] = h[N // 2] = 1
h[1:N // 2] = 2
else:
h[0] = 1
h[1:(N + 1) // 2] = 2
print(h)
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
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.
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.plot(x,y)
plt.title('Complex Waveform')
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.show()
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)
plt.grid()
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.