Blame doc/dht.rst

Packit 67cb25
.. index::
Packit 67cb25
   single: discrete Hankel transforms
Packit 67cb25
   single: Hankel transforms, discrete
Packit 67cb25
   single: transforms, Hankel
Packit 67cb25
Packit 67cb25
**************************
Packit 67cb25
Discrete Hankel Transforms
Packit 67cb25
**************************
Packit 67cb25
Packit 67cb25
This chapter describes functions for performing Discrete Hankel
Packit 67cb25
Transforms (DHTs). The functions are declared in the header file
Packit 67cb25
:file:`gsl_dht.h`.
Packit 67cb25
Packit 67cb25
Definitions
Packit 67cb25
===========
Packit 67cb25
Packit 67cb25
The discrete Hankel transform acts on a vector of sampled data, where
Packit 67cb25
the samples are assumed to have been taken at points related to the
Packit 67cb25
zeros of a Bessel function of fixed order; compare this to the case of
Packit 67cb25
the discrete Fourier transform, where samples are taken at points
Packit 67cb25
related to the zeroes of the sine or cosine function.
Packit 67cb25
Packit 67cb25
Starting with its definition, the Hankel transform (or Bessel transform) of
Packit 67cb25
order :math:`\nu` of a function :math:`f` with :math:`\nu > -1/2` is defined as
Packit 67cb25
(see Johnson, 1987 and Lemoine, 1994)
Packit 67cb25
Packit 67cb25
.. math:: F_\nu(u) = \int_0^\infty f(t) J_\nu(u t) t dt
Packit 67cb25
Packit 67cb25
If the integral exists, :math:`F_\nu` is called the Hankel transformation
Packit 67cb25
of :math:`f`. The reverse transform is given by
Packit 67cb25
Packit 67cb25
.. math:: f(t) = \int_0^\infty F_\nu(u) J_\nu(u t) u du
Packit 67cb25
Packit 67cb25
where :math:`\int_0^\infty f(t) t^{1/2} dt` must exist and be
Packit 67cb25
absolutely convergent, and where :math:`f(t)` satisfies Dirichlet's
Packit 67cb25
conditions (of limited total fluctuations) in the interval
Packit 67cb25
:math:`[0,\infty]`.
Packit 67cb25
Packit 67cb25
Now the discrete Hankel transform works on a discrete function
Packit 67cb25
:math:`f`, which is sampled on points :math:`n=1...M` located at
Packit 67cb25
positions :math:`t_n=(j_{\nu,n}/j_{\nu,M}) X` in real space and
Packit 67cb25
at :math:`u_n=j_{\nu,n}/X` in reciprocal space. Here,
Packit 67cb25
:math:`j_{\nu,m}` are the m-th zeros of the Bessel function
Packit 67cb25
:math:`J_\nu(x)` arranged in ascending order. Moreover, the
Packit 67cb25
discrete functions are assumed to be band limited, so
Packit 67cb25
:math:`f(t_n)=0` and :math:`F(u_n)=0` for :math:`n>M`. Accordingly,
Packit 67cb25
the function :math:`f` is defined on the interval :math:`[0,X]`.
Packit 67cb25
Packit 67cb25
Following the work of Johnson, 1987 and
Packit 67cb25
Lemoine, 1994, the discrete Hankel transform is given by
Packit 67cb25
Packit 67cb25
.. only:: not texinfo
Packit 67cb25
Packit 67cb25
   .. math::
Packit 67cb25
Packit 67cb25
      F_\nu(u_m) = {{2 X^2}\over{j_{\nu,M}^2}}
Packit 67cb25
            \sum_{k=1}^{M-1} f\left({{j_{\nu,k} X}\over{j_{\nu,M}}}\right)
Packit 67cb25
                {{J_\nu(j_{\nu,m} j_{\nu,k} / j_{\nu,M})}\over{J_{\nu+1}(j_{\nu,k})^2}}.
Packit 67cb25
Packit 67cb25
.. only:: texinfo
Packit 67cb25
Packit 67cb25
   ::
Packit 67cb25
Packit 67cb25
      F_\nu(u_m) = (2 X^2 / j_(\nu,M)^2)
Packit 67cb25
            \sum_{k=1}^{M-1} f(j_(\nu,k) X/j_(\nu,M))
Packit 67cb25
                (J_\nu(j_(\nu,m) j_(\nu,k) / j_(\nu,M)) / J_(\nu+1)(j_(\nu,k))^2).
Packit 67cb25
Packit 67cb25
It is this discrete expression which defines the discrete Hankel
Packit 67cb25
transform calculated by GSL. In GSL, forward and backward transforms
Packit 67cb25
are defined equally and calculate :math:`F_\nu(u_m)`.
Packit 67cb25
Following Johnson, the backward transform reads
Packit 67cb25
Packit 67cb25
.. only:: not texinfo
Packit 67cb25
Packit 67cb25
   .. math::
Packit 67cb25
Packit 67cb25
      f(t_k) = {{2}\over{X^2}}
Packit 67cb25
            \sum_{m=1}^{M-1} F\left({{j_{\nu,m}}\over{X}}\right)
Packit 67cb25
                {{J_\nu(j_{\nu,m} j_{\nu,k} / j_{\nu,M})}\over{J_{\nu+1}(j_{\nu,m})^2}}.
Packit 67cb25
Packit 67cb25
.. only:: texinfo
Packit 67cb25
Packit 67cb25
   ::
Packit 67cb25
Packit 67cb25
      f(t_k) = (2 / X^2)
Packit 67cb25
            \sum_{m=1}^{M-1} F(j_(\nu,m)/X)
Packit 67cb25
                (J_\nu(j_(\nu,m) j_(\nu,k) / j_(\nu,M)) / J_(\nu+1)(j_(\nu,m))^2).
Packit 67cb25
Packit 67cb25
Obviously, using the forward transform instead of the backward transform gives an
Packit 67cb25
additional factor :math:`X^4/j_{\nu,M}^2=t_m^2/u_m^2`.
Packit 67cb25
Packit 67cb25
The kernel in the summation above defines the matrix of the
Packit 67cb25
:math:`\nu`-Hankel transform of size :math:`M-1`. The coefficients of
Packit 67cb25
this matrix, being dependent on :math:`\nu` and :math:`M`, must be
Packit 67cb25
precomputed and stored; the :type:`gsl_dht` object encapsulates this
Packit 67cb25
data. The allocation function :func:`gsl_dht_alloc` returns a
Packit 67cb25
:type:`gsl_dht` object which must be properly initialized with
Packit 67cb25
:func:`gsl_dht_init` before it can be used to perform transforms on data
Packit 67cb25
sample vectors, for fixed :math:`\nu` and :math:`M`, using the
Packit 67cb25
:func:`gsl_dht_apply` function. The implementation allows to define the
Packit 67cb25
length :math:`X` of the fundamental interval, for convenience, while
Packit 67cb25
discrete Hankel transforms are often defined on the unit interval
Packit 67cb25
instead of :math:`[0,X]`.
Packit 67cb25
Packit 67cb25
Notice that by assumption :math:`f(t)` vanishes at the endpoints
Packit 67cb25
of the interval, consistent with the inversion formula
Packit 67cb25
and the sampling formula given above. Therefore, this transform
Packit 67cb25
corresponds to an orthogonal expansion in eigenfunctions
Packit 67cb25
of the Dirichlet problem for the Bessel differential equation.
Packit 67cb25
Packit 67cb25
Functions
Packit 67cb25
=========
Packit 67cb25
Packit 67cb25
.. type:: gsl_dht
Packit 67cb25
Packit 67cb25
   Workspace for computing discrete Hankel transforms
Packit 67cb25
Packit 67cb25
.. function:: gsl_dht * gsl_dht_alloc (size_t size)
Packit 67cb25
Packit 67cb25
   This function allocates a Discrete Hankel transform object of size
Packit 67cb25
   :data:`size`.
Packit 67cb25
Packit 67cb25
.. function:: int gsl_dht_init (gsl_dht * t, double nu, double xmax)
Packit 67cb25
Packit 67cb25
   This function initializes the transform :data:`t` for the given values of
Packit 67cb25
   :data:`nu` and :data:`xmax`.
Packit 67cb25
Packit 67cb25
.. function:: gsl_dht * gsl_dht_new (size_t size, double nu, double xmax)
Packit 67cb25
Packit 67cb25
   This function allocates a Discrete Hankel transform object of size
Packit 67cb25
   :data:`size` and initializes it for the given values of :data:`nu` and
Packit 67cb25
   :data:`xmax`.
Packit 67cb25
Packit 67cb25
.. function:: void gsl_dht_free (gsl_dht * t)
Packit 67cb25
Packit 67cb25
   This function frees the transform :data:`t`.
Packit 67cb25
Packit 67cb25
.. function:: int gsl_dht_apply (const gsl_dht * t, double * f_in, double * f_out)
Packit 67cb25
Packit 67cb25
   This function applies the transform :data:`t` to the array :data:`f_in`
Packit 67cb25
   whose size is equal to the size of the transform.  The result is stored
Packit 67cb25
   in the array :data:`f_out` which must be of the same length.   
Packit 67cb25
Packit 67cb25
   Applying this function to its output gives the original data
Packit 67cb25
   multiplied by :math:`(X^2/j_{\nu,M})^2`,
Packit 67cb25
   up to numerical errors.
Packit 67cb25
Packit 67cb25
.. function:: double gsl_dht_x_sample (const gsl_dht * t, int n)
Packit 67cb25
Packit 67cb25
   This function returns the value of the :data:`n`-th sample point in the unit interval,
Packit 67cb25
   :math:`{({j_{\nu,n+1}} / {j_{\nu,M}}}) X`.
Packit 67cb25
   These are the points where the function :math:`f(t)` is assumed to be sampled.
Packit 67cb25
Packit 67cb25
.. function:: double gsl_dht_k_sample (const gsl_dht * t, int n)
Packit 67cb25
Packit 67cb25
   This function returns the value of the :data:`n`-th sample point in "k-space",
Packit 67cb25
   :math:`{{j_{\nu,n+1}} / X}`.
Packit 67cb25
Packit 67cb25
References and Further Reading
Packit 67cb25
==============================
Packit 67cb25
Packit 67cb25
The algorithms used by these functions are described in the following papers,
Packit 67cb25
Packit 67cb25
* H. Fisk Johnson, Comp.: Phys.: Comm.: 43, 181 (1987).
Packit 67cb25
Packit 67cb25
* D. Lemoine, J. Chem.: Phys.: 101, 3936 (1994).