DewDSPMasterNET
Hilbert Routine
Summary
Applies hilbert transform to Src.

Unit
SignalUtils

Declaration
Function Hilbert(SrcDst: TVec): TVec;

Description
Applies hilbert transform to Src. Src must be real signal. The result is complex. Hilbert transform generates a 90 degree phase shifted version of the original. This becomes the imaginary part of the complex signal. This routine is very usefull for single block processing, but can not be used for streaming data. Use a digital FIR filter based hilbert transformer for streaming data or resort to quadrature sampling techniques [1], p. 297.

.

Categories
FIR filters
 See Also 
[1] "Understanding digital signal processing.", Richard G. Lyons, Prentice-Hall, 2001. 
Remez 
KaiserImpulse 
RemezImpulse 

Example 1

Hilbert transform of a sine signal is computed for two cases:

- frequency of the sine falls exactly on the spectral bin (ideal case)
- frequency of the sine is not alligned with the frequency spectrum grid.

uses MtxExpr, Math387, MtxVec, SignalUtils, MtxVecTee, MtxVecEdit; procedure TForm1.Button1Click(Sender: TObject); var h,h1,Re,Im: Vector; begin h := Sin(Ramp(256,0,2*Pi*6/256)); SignalUtils.Hilbert(h); h.CplxToReal(Re,Im); DrawIt([Re,Im],['Real','Imag'],'Integer frequency'); h1.SetIt(false,[Re.DotProd(Im)]); ViewValues(h1,'Dot product between Re and Im',True); h := Sin(Ramp(256,0,2*Pi*6.5/256)); SignalUtils.Hilbert(h); h.CplxToReal(Re,Im); DrawIt([Re,Im],['Real','Imag'],'Non-integer frequency'); h1.SetIt(false,[Re.DotProd(Im)]); ViewValues(h1,'Dot product between Re and Im',True); h := Sin(Ramp(256,0,2*Pi*6.5/256)); Re.Copy(h); Im.Copy(h); KaiserImpulse(h1,[0.95,1],0.01,ftHilbertIII); //Or use remez: RemezImpulse(h1,[0.05,0.95],0.01,ftHilbertIII); FirFilter(Im,h1); //also compensates for integer filter delay (if filter is Odd length (type III)) DrawIt([Re,Im],['Real ','Imag'],'With FIR filter'); h1.SetIt(false,[Re.DotProd(Im)]); //dot product between Re and Im should be zero ViewValues(h1,'Dot product between Re and Im',True); end;
#include "MtxVecCPP.h" //MtxVecCPP.cpp must be included in the project #include "MtxVecEdit.hpp" #include "MtxVecTee.hpp" #include "SignalUtils.hpp" void __fastcall TForm1::BitBtn1Click(TObject *Sender) { Vector h,h1, Re, Im; h = Sin(Ramp(256,0,2*PI*6/256)); Signalutils::Hilbert(h); h->CplxToReal(Re,Im); DrawIt(OPENARRAY(TVec*,(Re, Im)), OPENARRAY(AnsiString,("Real","Imag")),"Integer frequency"); h1->SetIt(false,OPENARRAY(double,(Re->DotProd(Im))) ); ViewValues(h1,"Dot product between Re and Im",True); h = Sin(Ramp(256,0,2*PI*6.5/256)); Signalutils::Hilbert(h); h->CplxToReal(Re,Im); DrawIt(OPENARRAY(TVec*,(Re,Im)), OPENARRAY(AnsiString,("Real","Imag")),"Non-Integer frequency"); h1->SetIt(false,OPENARRAY(double,(Re->DotProd(Im)))); ViewValues(h1,"Dot product between Re and Im",True); h = Sin(Ramp(256,0,2*PI*6.5/256)); Re->Copy(h); Im->Copy(h); KaiserImpulse(h1,OPENARRAY(double,(0.95,1)),0.01,ftHilbertIII); //Or use remez: RemezImpulse(h1,OPENARRAY(double,(0.05,0.95)),0.01,ftHilbertIII); FirFilter(Im,h1); //also compensates for integer filter delay (if filter is Odd length (type III)) DrawIt(OPENARRAY(TVec*,(Re,Im)), OPENARRAY(AnsiString,("Real","Imag")),"FIR Filter"); h1->SetIt(false,OPENARRAY(double,(Re->DotProd(Im)))); //dot product between Re and Im should be zero ViewValues(h1,"Dot product between Re and Im",True); }
using Dew.Math; using Dew.Math.Units; using Dew.Signal; using Dew.Signal.Units; using Dew.Math.Tee; using Dew.Math.Editors; using Dew.Signal.Tee; private void button1_Click(object sender, EventArgs e) { Vector h = MtxExpr.Sin(MtxExpr.Ramp(256, 0, 2 * Math387.PI * 6/256)); Vector Re = new Vector(0); Vector Im = new Vector(0); Vector h1 = new Vector(0); SignalUtils.Hilbert(h); h.CplxToReal(Re, Im); TeeChart.DrawIt(new TVec[2] {Re,Im}, new string[2] {"Real","Imag"} ,"Integer frequency",false); h1.SetIt(false,new double[1] {Re.DotProd(Im)}); MtxVecEdit.ViewValues(h1,"Dot product between Re and Im",true); h = MtxExpr.Sin(MtxExpr.Ramp(256, 0, 2 * Math387.PI * 6.5/256)); SignalUtils.Hilbert(h); h.CplxToReal(Re, Im); TeeChart.DrawIt(new TVec[2] {Re,Im}, new string[2] {"Real","Imag"} ,"Non-integer frequency",false); h1.SetIt(false,new double[1] {Re.DotProd(Im)}); MtxVecEdit.ViewValues(h1,"Dot product between Re and Im",true); h = MtxExpr.Sin(MtxExpr.Ramp(256, 0, 2 * Math387.PI * 6.5/256)); Re.Copy(h); Im.Copy(h); SignalUtils.KaiserImpulse(h1,new double[2] {0.95,1}, 0.01, TFilterType.ftHilbertIII,1,2,true); //Or use remez: OptimalFIR.RemezImpulse(h1,new double[2] {0.05,0.95}, 0.01, TFilterType.ftHilbertIII); SignalUtils.FirFilter(Im,h1,1,1); //also compensates for integer filter delay (if filter is Odd length (type III)) TeeChart.DrawIt(new TVec[2] {Re,Im}, new string[2] {"Real","Imag"} ,"With FIR Filter",false); h1.SetIt(false,new double[1] {Re.DotProd(Im)}); //dot product between Re and Im should be zero MtxVecEdit.ViewValues(h1, "Dot product between Re and Im", true); }


Copyright 2008 Dew Research
http://www.dewresearch.com