The discrete Hankel transform acts on a vector of sampled data, where the samples are assumed to have been taken at points related to the zeroes of a Bessel function of fixed order; compare this to the case of the discrete Fourier transform, where samples are taken at points related to the zeroes of the sine or cosine function.

Specifically, let *f(t)* be a function on the unit interval and
*j_(\nu,m)* the *m*-th zero of the Bessel function
*J_\nu(x)*. Then the finite *\nu*-Hankel transform of
*f(t)* is defined to be the set of numbers *g_m* given by,

g_m = \int_0^1 t dt J_\nu(j_(\nu,m)t) f(t),

so that,

f(t) = \sum_{m=1}^\infty (2 J_\nu(j_(\nu,m)t) / J_(\nu+1)(j_(\nu,m))^2) g_m.

Suppose that *f* is band-limited in the sense that
*g_m=0* for *m > M*. Then we have the following
fundamental sampling theorem.

g_m = (2 / j_(\nu,M)^2) \sum_{k=1}^{M-1} f(j_(\nu,k)/j_(\nu,M)) (J_\nu(j_(\nu,m) j_(\nu,k) / j_(\nu,M)) / J_(\nu+1)(j_(\nu,k))^2).

It is this discrete expression which defines the discrete Hankel
transform. The kernel in the summation above defines the matrix of the
*\nu*-Hankel transform of size *M-1*. The coefficients of
this matrix, being dependent on *\nu* and *M*, must be
precomputed and stored; the `gsl_dht`

object encapsulates this
data. The allocation function `gsl_dht_alloc`

returns a
`gsl_dht`

object which must be properly initialized with
`gsl_dht_init`

before it can be used to perform transforms on data
sample vectors, for fixed *\nu* and *M*, using the
`gsl_dht_apply`

function. The implementation allows a scaling of
the fundamental interval, for convenience, so that one can assume the
function is defined on the interval *[0,X]*, rather than the unit
interval.

Notice that by assumption *f(t)* vanishes at the endpoints
of the interval, consistent with the inversion formula
and the sampling formula given above. Therefore, this transform
corresponds to an orthogonal expansion in eigenfunctions
of the Dirichlet problem for the Bessel differential equation.