Hilbert Transform | Hilbert Transform

Basic procedure: Start with a bandpass filter, then apply the Hilbert transform to obtain a complex signal, which separates amplitude and phase.

Objective: Obtain instantaneous amplitude and phase by adding the imaginary part to the real signal.

📌 We do not alter the real part; we only add the imaginary part on top of it.

Mathematical Definition

Assuming we have a signal named real(t)real(t), the Hilbert transform is given by:

real(t)+iimag(t)real(t) + i * imag(t)

The imag signal is the result of shifting the real signal by π/2\pi/2. For example, if the original signal is cos(2πft)cos(2\pi ft), then the result after the Hilbert transform will be cos(2πft)+isin(2πft)cos(2\pi ft) + i * sin(2\pi ft).

Code

MATLAB Code

1
2
3
4
5
6
7
8
9
10
11
12
% Hilbert Custom function
f = fft(signal);

posF = 1:(n/2); % indices for positive and negative freqs.
negF = (n/2)+1:n;

rotateN = 1i*f(negF); % rotate negative frequencies; cos --> sin
newN = 1i*rotateN; % multiply by i --> i*sin()

new_f = [f(posF) newN]; % build full vector of complex components (pos + neg); real component does not change
f = f + new_f; % add to original signal: cos() + i*sin()
hilberty = ifft(f); % inverse fft --> back to time domain
1
2
3
4
5
% using Hilbert function

hx = hilbert(x);
phase_x = angle(hx); % phase
amp_x = abs(hx); % amplitude

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Hilbert Custom function
import numpy as np

def hilbert(signal):
n = len(signal)
f = np.fft.fft(signal)

posF = np.arange(1, n//2 + 1) # indices for positive frequencies
negF = np.arange(n//2 + 1, n) # indices for negative frequencies

rotateN = 1j * f[negF] # rotate negative frequencies; cos --> sin
newN = 1j * rotateN # multiply by i --> i*sin()

new_f = np.concatenate((f[posF], newN)) # build full vector of complex components (pos + neg); real component does not change
f = f + new_f # add to original signal: cos() + i*sin()
hilberty = np.fft.ifft(f) # inverse fft --> back to time domain

return hilberty
1
2
3
4
5
6
# using Hilbert function
import numpy as np

hx = np.fft.hilbert(x)
phase_x = np.angle(hx) # phase
amp_x = np.abs(hx) # amplitude

Filtering | Filter

Filtering the data before applying the Hilbert transform is crucial to prevent wide bandwidths that could lead to challenging interpretations.

Two common types of filters: Finite Impulse Response (FIR) and Infinite Impulse Response (IIR).

Advantages and characteristics of FIR compared to IIR:

  • FIR kernel functions are zero at positive and negative infinity.
  • Wavelets can be considered a type of FIR filter.
  • FIR is recommended over IIR because it’s stable and less prone to introducing nonlinear phase distortions.
  • However, FIR filters are more computationally expensive.

Things to consider when designing filters:

  • Sharp edges in the filter’s frequency response can cause ripples in the time domain. Thus, it’s best to design filters that are plateau-shaped and ensure transition zones cover 10% to 25% of the frequency range (max frequency - min frequency).

Code

MATLAB Code

The most common functions are firls and fir1, along with other functions available.

firls: Least-squares linear-phase FIR filter.

1
b = firls(n, f, a)

n: The n denotes the filter order, and the corresponding kernel length is n+1 (referring to the number of points rather than time). n has no upper limit, but higher values increase computational load. The lower limit of n ranges from 2-5 times the lowest frequency (for instance, if the lowest frequency is 10Hz, a kernel corresponding to a time length of 200-500ms is typically used).

f: f represents the x-coordinates of the filter points, indicating the scaled relative values of the filter points’ frequencies after scaling (such that Nyquist frequency = 1). For example, f = [0, 0.1, 0.15, 0.3, 0.35, 1];

a: a signifies the y-coordinates of the filter points and is scaled to the range [0,1]. For instance, a = [0 0 1 1 0 0]; Note that the lengths of a and f should be the same.

fir1: Window-based FIR filter.

Python

Continued.


Note: The content in this blog is class notes shared for educational purposes only. Some images and content are sourced from textbooks, teacher materials, and the internet. If there is any infringement, please contact aursus.blog@gmail.com for removal.