All the functions presented here make use of Fourier transforms to calculate the discrete Hilbert transform in frequency space. One can of course also compute the Hilbert transform directly in position space:
HilbertDirect = Compile[{{data, _Real, 1}},
Table[
2/\[Pi]
Sum[
data[[i]]/(j - i)
, {i, 1 + If[OddQ[j], 1Mod[j, 0]2],Length[data] - If[OddQ[j], 1Mod[j, 0]2], 2}]
, {j, 1, Length[data]}]
]
Or, with slightly improved sensitivity for higher frequency components:
HilbertDirect2 = Compile[{{data, _Real, 1},{nn, _Integer}},
Table[
2/nn
Sum[
data[[i]] Cot[((j - i) \[Pi])/nn]
, {i,1 + If[OddQ[j], 1Mod[j, 0]2], Length[data] - If[OddQ[j], 1Mod[j, 0]2], 2}]
, {j, 1, Length[data]}]
]
(where one should set nn>=Length[data]
).
In most cases, this is of course slower than the Fourier transform approach, since the above scales directly with Length[data]
. However, the quality of this finite impulse response Hilbert transform seems pretty good. Especially the edge effects for non-periodic cases are better than low padding frequency space results.