4

I am trying to detect the envelope of a high-frequency signal (similar to below) using Matlab Hilbert function

enter image description here

This is my output

enter image description here

It generally follows the envelope, but there is a high-frequency ripple in the envelope, see zoomed version below

enter image description here

Here is my code:

t =out.tout';
x =out.Itxmod';
y = hilbert(x);
env = abs(y);
figure;
plot_param = {'Color', [0.6 0.1 0.2],'Linewidth',2};
plot(t,x)
hold on
plot(t,[-1;1]*env,plot_param{:})
hold off
xlim([0.001 0.002])
title('Hilbert Envelope')

Question: How can I get a smooth envelope the signal without this high-frequency ripple?

Dan Boschen
  • 50,942
  • 2
  • 57
  • 135
Pojj
  • 143
  • 4

1 Answers1

7

This must be an artifact in the way the OP has generated the waveform (all those details are not provided) as I get different results as detailed below using the hilbert function in Matlab (which to be clear is NOT the Hilbert Transform, but the analytic signal which consists of the signal plus its Hilbert transform as the imaginary term). In general here are three suggestions to obtain the envelope:

Method 1: Determine the analytic signal using the FFT: take the FFT of the original signal, set all the negative frequencies to zero (the upper half of the FFT) and double the positive frequencies leaving bin 0 (DC) as is (and as Overlord pointed out in the comments, leave the Nyquist bin at $N/2$ as is when the FFT length $N$ is even). The IFFT will be the analytic signal and taking the absolute value of this signal will be the desired envelope. (As @aconcernedcitizen pointed out in the comments, this IS the method specifically implemented by Octave using the hilbert function from the signal package, and I assume MATLAB as well.)

Method 2: Determine the analytic signal with quadrature phase tracking filters where the filter length versus ripple can be traded.

Method 3: Use a traditional AM demodulator by multiplying the modulated signal with the coherent carrier and then low pass filtering the result.

A demonstration of Method 1 is shown below, which is a suitable solution for the OP's case:

signal and envelope

Zooming in on the start of the signal shows the distortion limited to the start-up condition and the smooth envelope after that.

zoom in

The Matlab code for this is as follows:

The OP hasn't provided full details on how the waveform was generated. I duplicated it by observation of the plots by doing the following:

fs = 1e6; 
T = 2e-3; 
N = round(fs * T);
t = [0:N-1]*1/fs;
carrier = cos(2*pi*100e3*t); 
modulation = cos(2*pi*10e3*t);
sig = 8 * carrier .* (1 - 0.025 * modulation);

With the results of method 1 below:

N = length(sig);
sig_spectrum = fft(sig);
hilbert_spectrum = zeros(1, N);
hilbert_spectrum(1) = sig_spectrum(1);
hilbert_spectrum(2: ceil(N/2) - 1) = 2 * sig_spectrum(2:ceil(N/2) - 1);
if mod(N, 2) == 0
  hilbert_spectrum(N/2) = sig_spectrum(N/2);
endif
hilbert_time = ifft(hilbert_spectrum);
envelope = abs(hilbert_time);

I subsequently confirmed that the magnitude of the hilbert function produces an identical result:

envelope2 = abs(hilbert(sig));
Dan Boschen
  • 50,942
  • 2
  • 57
  • 135
  • 1
    Caveat, Nyquist bin shouldn't be doubled (even N). – OverLordGoldDragon Apr 23 '21 at 20:44
  • 1
    Good point! The bin at N/2 should not be doubled when N is even. – Dan Boschen Apr 24 '21 at 00:24
  • I thought method 1 is the one that it's done by default with hilbert()? I know Octave uses it like that. – a concerned citizen Apr 24 '21 at 08:07
  • 1
    @aconcernedcitizen you're right, I just looked at the code in Octave and it is exactly method 1 – Dan Boschen Apr 24 '21 at 11:01
  • 1
    Hi Dan, I think MATLAB's hilbert() also uses method 1, according to the document – ZR Han Aug 27 '21 at 02:00
  • Hi there, I know this is a little late at this point, however, I am confused on how you obtain smoother results than OP since, as you state, your method 1 is equal to the method OP has used? – Manatee Pink Mar 21 '22 at 09:46
  • @ManateePink Unfortunately the OP hasn't provided the full details as to how the waveform was generated, so I don't know why the same result wasn't achieved. I added more details to how I generated my version as well as confirming the results are identical. – Dan Boschen Mar 21 '22 at 12:39
  • @DanBoschen, thanks for your response. But does that mean then that doing your method 1 would not result in a smoother result for OP since it is identical to taking the absolute value of the output of the hilbert function? Since OP is using a different input signal – Manatee Pink Mar 23 '22 at 14:57
  • @ManateePink I would need to see the actual waveform to answer that- I implemented to match what I saw graphically and don’t see any such ripple. Something else may be wrong. – Dan Boschen Mar 23 '22 at 15:42