Wolfram Research

Function Repository Resource:

DiscreteHartleyTransform (1.0.0) current version: 1.1.0 »

Source Notebook

Compute the discrete Hartley transform of a list

Contributed by: Jan Mangaldan

ResourceFunction["DiscreteHartleyTransform"][list]

computes the discrete Hartley transform of a list of complex numbers.

Details

The discrete Hartley transform vs of a list ur of length n is defined to be . The normalization is chosen such that the transform is its own inverse.
The discrete Hartley transform is sometimes defined to have the normalization constant 1 or instead.
The discrete Hartley transform is real-valued for real-valued data.
The list of data supplied to ResourceFunction["DiscreteHartleyTransform"] must be one-dimensional, but need not have a length equal to a power of two.
If the elements of list are exact numbers, ResourceFunction["DiscreteHartleyTransform"] begins by applying N to them.
ResourceFunction["DiscreteHartleyTransform"] can be used on SparseArray objects.

Examples

Basic Examples (1) 

Compute a discrete Hartley transform:

In[1]:=
ResourceFunction["DiscreteHartleyTransform"][{1, 1, 2, 2, 1, 1, 0, 0}]
Out[1]=

Scope (2) 

x is a list of real values:

In[2]:=
x = {1, 0, 0, 1, 0, 0, 1};

Compute the Hartley transform with machine arithmetic:

In[3]:=
ResourceFunction["DiscreteHartleyTransform"][x]
Out[3]=

Compute using 24-digit precision arithmetic:

In[4]:=
ResourceFunction["DiscreteHartleyTransform"][N[x, 24]]
Out[4]=

Compute a complex Hartley transform:

In[5]:=
v = RandomComplex[1 + I, 17];
In[6]:=
ResourceFunction["DiscreteHartleyTransform"][v]
Out[6]=

This is equivalent to separately taking the Hartley transforms of the real and imaginary parts:

In[7]:=
ResourceFunction["DiscreteHartleyTransform"][Re[v]] + I ResourceFunction["DiscreteHartleyTransform"][Im[v]]
Out[7]=

Applications (2) 

Use the discrete Hartley transform to compute the power spectrum of "white noise":

In[8]:=
dat = RandomReal[1, 200];
fht = ResourceFunction["DiscreteHartleyTransform"][dat];
ListLinePlot[(fht^2 + RotateRight[Reverse[fht]]^2)/2]
Out[11]=

Show the logarithmic spectrum, including the first (DC) component:

In[12]:=
ListLinePlot[Log10[fht^2 + RotateRight[Reverse[fht]]^2], PlotRange -> All]
Out[22]=

Compute discrete cyclic convolutions to smooth a discontinuous function with a Gaussian:

In[23]:=
n = 100; dx = 1./(n - 1);
a = Table[UnitStep[x - 1/2], {x, 0, 1, dx}];
b = Table[
   If[x <= 1/2, Exp[-100 x^2], Exp[-100 (1 - x)^2]], {x, 0, 1, dx}];
b = b/Total[b];
In[24]:=
{ListPlot[a, Filling -> Axis, DataRange -> {0, 1}], ListPlot[b, Filling -> Axis, PlotRange -> All, DataRange -> {0, 1}]}
Out[24]=

Compute the cyclic convolution:

In[25]:=
hta = ResourceFunction["DiscreteHartleyTransform"][a];
htb = ResourceFunction["DiscreteHartleyTransform"][b];
rb = RotateRight[Reverse[htb]];
c = Sqrt[
    Length[a]] ResourceFunction["DiscreteHartleyTransform"][
     hta (htb + rb) + RotateRight[Reverse[hta]] (htb - rb)]/2;

Show the original and smoothed function:

In[26]:=
ListPlot[{a, c}, DataRange -> {0, 1}]
Out[26]=

The convolution is consistent with ListConvolve:

In[27]:=
Max[Abs[c - ListConvolve[a, b, {1, 1}]]]
Out[27]=

Properties and Relations (4) 

Compute the discrete Hartley transform from its definition:

In[28]:=
u = N[{1, 2, 3, 4, 5, 6, 7}];
n = Length[u];
In[29]:=
AbsoluteTiming[v1 = Table[1/Sqrt[n] \!\(TraditionalForm\`
\*UnderoverscriptBox[\(\[Sum]\), \(r = 1\), \(n\)]\*
TemplateBox[{"u", "r"},
"IndexedDefault"]\ \((Cos[
\*FractionBox[\(2  \[Pi]\ \((r - 1)\)\ \((s - 1)\)\), \(n\)]] + Sin[
\*FractionBox[\(2  \[Pi]\ \((r - 1)\)\ \((s - 1)\)\), \(n\)]])\)\), {s, 1, n}]]
Out[29]=

DiscreteHartleyTransform is faster:

In[30]:=
AbsoluteTiming[v2 = ResourceFunction["DiscreteHartleyTransform"][u]]
Out[30]=
In[31]:=
Chop[v1 - v2]
Out[31]=

Compute the discrete Hartley transform of a vector by multiplying it with the Hartley matrix:

In[32]:=
u = N[{1, 2, 3, 4, 5, 6, 7}];
n = Length[u];
In[33]:=
AbsoluteTiming[v1 = ResourceFunction["HartleyMatrix"][n] . u]
Out[33]=

DiscreteHartleyTransform is faster:

In[34]:=
AbsoluteTiming[v2 = ResourceFunction["DiscreteHartleyTransform"][u]]
Out[34]=
In[35]:=
Chop[v1 - v2]
Out[35]=

The discrete Hartley transform is its own inverse:

In[36]:=
v = RandomReal[{-2, 2}, 13];
In[37]:=
v - ResourceFunction["DiscreteHartleyTransform"][
   ResourceFunction["DiscreteHartleyTransform"][v]] // Chop
Out[37]=

A list of numbers:

In[38]:=
v = RandomReal[{-2, 2}, 13];

Compute its discrete Hartley transform:

In[39]:=
fht = ResourceFunction["DiscreteHartleyTransform"][v]
Out[39]=

Use the discrete Hartley transform to compute the discrete Fourier transform:

In[40]:=
rev = RotateRight[Reverse[fht]];
(fht + rev)/2 + I (fht - rev)/2
Out[41]=

Compare with the result of Fourier:

In[42]:=
Fourier[v]
Out[42]=

Version History

  • 1.1.0 – 13 March 2023
  • 1.0.0 – 13 February 2023

Source Metadata

Related Resources

License Information