DSPRelated.com
Forums

Hilbert transformation using real valued input FFT

Started by Unknown November 13, 2013
Hello,

I would like to use the hilbert transformation to get an amplitude envelope of a real valued (=measured) signal. Wikipedia describes it nicely:

https://en.wikipedia.org/wiki/Analytic_signal#Applications

I implemented my tests in matlab/octave and it's easy:

#
# Hilbert transformation of x
#
# Shifts the signal by pi
#
function H=hilbert(x)
  N=length(x);

  X = fft(x);
  X = X * -i;

 #negative frequencies
  r=(N/2+1):N;
  X( r ) = X( r ) * -1; # *** see here ***

  H=ifft(X);
endfunction


# get the amplitude envelope:
#
function y=envelope( x )
  y=sqrt(x.^2 + real(hilbert(x)).^2);
endfunction


So far, so good. Now I want to implement it on my DSP and I use the algorithm described here, to calculate an FFT from a real valued input:

http://processors.wiki.ti.com/index.php/Efficient_FFT_Computation_of_Real_Input

Works great, but: Using this algorithm, I never see the negative frequencies, so I can't multiply them by -1 (as marked above).

My question: Is it somehow possible to implement hilbert transformation using the real valued FFT algoritm?

I naively tried multiplying only the positive frequencies by -i, but it didn't work. Well, IIRC, it can't work: If A=a+bi  is at a positive frequency, then:
A * -i =b-ai
Given the input is real, then the negative frequency is A's complex conjugate ( =: A# = a-bi):
A# * -i = -b-ai
The code above multiplies the negative frequencies by -1, so
(A# * -i) * -1 = b+ai  =: B
Since B != conjugate(A * -i), the naive approach doesn't work.
If the time-domain signal x(t) is real-valued, then the Fourier X(\omega) = -X*(\omega). The app note you are reading specifically notes "Algorithms to perform forward and inverse Fast Fourier Transforms (FFT and IFFT) typically assume complex input and output data. However, many applications use only real-valued data in the time domain." 

So you are reading the wrong app note, unless you like to do unnecessary Fourier-kungfu to fit what you are trying to do into what they are doing. 

Julius 


On Wednesday, November 13, 2013 4:54:44 AM UTC-5, markus.gr...@googlemail.com wrote:
> Hello, > > > > I would like to use the hilbert transformation to get an amplitude envelope of a real valued (=measured) signal. Wikipedia describes it nicely: > > > > https://en.wikipedia.org/wiki/Analytic_signal#Applications > > > > I implemented my tests in matlab/octave and it's easy: > > > > # > > # Hilbert transformation of x > > # > > # Shifts the signal by pi > > # > > function H=hilbert(x) > > N=length(x); > > > > X = fft(x); > > X = X * -i; > > > > #negative frequencies > > r=(N/2+1):N; > > X( r ) = X( r ) * -1; # *** see here *** > > > > H=ifft(X); > > endfunction > > > > > > # get the amplitude envelope: > > # > > function y=envelope( x ) > > y=sqrt(x.^2 + real(hilbert(x)).^2); > > endfunction > > > > > > So far, so good. Now I want to implement it on my DSP and I use the algorithm described here, to calculate an FFT from a real valued input: > > > > http://processors.wiki.ti.com/index.php/Efficient_FFT_Computation_of_Real_Input > > > > Works great, but: Using this algorithm, I never see the negative frequencies, so I can't multiply them by -1 (as marked above). > > > > My question: Is it somehow possible to implement hilbert transformation using the real valued FFT algoritm? > > > > I naively tried multiplying only the positive frequencies by -i, but it didn't work. Well, IIRC, it can't work: If A=a+bi is at a positive frequency, then: > > A * -i =b-ai > > Given the input is real, then the negative frequency is A's complex conjugate ( =: A# = a-bi): > > A# * -i = -b-ai > > The code above multiplies the negative frequencies by -1, so > > (A# * -i) * -1 = b+ai =: B > > Since B != conjugate(A * -i), the naive approach doesn't work.
On Wednesday, November 13, 2013 4:54:44 AM UTC-5, markus.gr...@googlemail.com wrote:
> Hello, > > > > I would like to use the hilbert transformation to get an amplitude envelope of a real valued (=measured) signal. Wikipedia describes it nicely: > > > > https://en.wikipedia.org/wiki/Analytic_signal#Applications > > > > I implemented my tests in matlab/octave and it's easy: > > > > # > > # Hilbert transformation of x > > # > > # Shifts the signal by pi > > # > > function H=hilbert(x) > > N=length(x); > > > > X = fft(x); > > X = X * -i; > > > > #negative frequencies > > r=(N/2+1):N; > > X( r ) = X( r ) * -1; # *** see here *** > > > > H=ifft(X); > > endfunction > > > > > > # get the amplitude envelope: > > # > > function y=envelope( x ) > > y=sqrt(x.^2 + real(hilbert(x)).^2); > > endfunction > > > > > > So far, so good. Now I want to implement it on my DSP and I use the algorithm described here, to calculate an FFT from a real valued input: > > > > http://processors.wiki.ti.com/index.php/Efficient_FFT_Computation_of_Real_Input > > > > Works great, but: Using this algorithm, I never see the negative frequencies, so I can't multiply them by -1 (as marked above). > > > > My question: Is it somehow possible to implement hilbert transformation using the real valued FFT algoritm? > > > > I naively tried multiplying only the positive frequencies by -i, but it didn't work. Well, IIRC, it can't work: If A=a+bi is at a positive frequency, then: > > A * -i =b-ai > > Given the input is real, then the negative frequency is A's complex conjugate ( =: A# = a-bi): > > A# * -i = -b-ai > > The code above multiplies the negative frequencies by -1, so > > (A# * -i) * -1 = b+ai =: B > > Since B != conjugate(A * -i), the naive approach doesn't work.
Since you are looking to measure the instantaneous amplitude via Hilbert, how much of the band (from DC to one half of the sampling rate) do you really need to do this for? If you can accept for this to work on a passband, you may just use a pair of filters whose phase differs by 90 degrees. An example here: http://www.claysturner.com/dsp/ASG.pdf And there are quite a few others too. IHTH, Clay
multiply signal with a sine wave and a cosine wave at the intended center
frequency. Then lowpass-filter both, square and add. 	 

_____________________________		
Posted through www.DSPRelated.com
GAAAAAAAAAAAAAAAASP

This way of implementing the hilbert transform is an easy mean to package something for matlab & the like by maths peoples.

It's only right in a circular periodicity manner.

most of the time, for physical signal, you'll get tons of time domain aliasing.

read a chapter on designing an Hilbert FIR filter, and apply plain standard convolution.

You'll stumble on a large GRD which is more in line with physics, less "magical", with trade-offs about near 0 and near nyquist frequencies also more in line with the physical world.

regards