|
Packit |
67cb25 |
.. index::
|
|
Packit |
67cb25 |
single: Chebyshev series
|
|
Packit |
67cb25 |
single: fitting, using Chebyshev polynomials
|
|
Packit |
67cb25 |
single: interpolation, using Chebyshev polynomials
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
************************
|
|
Packit |
67cb25 |
Chebyshev Approximations
|
|
Packit |
67cb25 |
************************
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This chapter describes routines for computing Chebyshev approximations
|
|
Packit |
67cb25 |
to univariate functions. A Chebyshev approximation is a truncation of
|
|
Packit |
67cb25 |
the series :math:`f(x) = \sum c_n T_n(x)`, where the Chebyshev
|
|
Packit |
67cb25 |
polynomials :math:`T_n(x) = \cos(n \arccos x)` provide an orthogonal
|
|
Packit |
67cb25 |
basis of polynomials on the interval :math:`[-1,1]` with the weight
|
|
Packit |
67cb25 |
function :math:`1 / \sqrt{1-x^2}`.
|
|
Packit |
67cb25 |
The first few Chebyshev polynomials are,
|
|
Packit |
67cb25 |
:math:`T_0(x) = 1`, :math:`T_1(x) = x`, :math:`T_2(x) = 2 x^2 - 1`.
|
|
Packit |
67cb25 |
For further information see Abramowitz & Stegun, Chapter 22.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The functions described in this chapter are declared in the header file
|
|
Packit |
67cb25 |
:file:`gsl_chebyshev.h`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Definitions
|
|
Packit |
67cb25 |
===========
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. type:: gsl_cheb_series
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
A Chebyshev series is stored using the following structure::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
typedef struct
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double * c; /* coefficients c[0] .. c[order] */
|
|
Packit |
67cb25 |
int order; /* order of expansion */
|
|
Packit |
67cb25 |
double a; /* lower interval point */
|
|
Packit |
67cb25 |
double b; /* upper interval point */
|
|
Packit |
67cb25 |
...
|
|
Packit |
67cb25 |
} gsl_cheb_series
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The approximation is made over the range :math:`[a,b]` using
|
|
Packit |
67cb25 |
:data:`order` + 1 terms, including the coefficient :math:`c[0]`. The series
|
|
Packit |
67cb25 |
is computed using the following convention,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: not texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. math:: f(x) = {c_0 \over 2} + \sum_{n=1} c_n T_n(x)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. only:: texinfo
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
::
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
f(x) = (c_0 / 2) + \sum_{n=1} c_n T_n(x)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
which is needed when accessing the coefficients directly.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Creation and Calculation of Chebyshev Series
|
|
Packit |
67cb25 |
============================================
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: gsl_cheb_series * gsl_cheb_alloc (const size_t n)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function allocates space for a Chebyshev series of order :data:`n`
|
|
Packit |
67cb25 |
and returns a pointer to a new :type:`gsl_cheb_series` struct.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: void gsl_cheb_free (gsl_cheb_series * cs)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function frees a previously allocated Chebyshev series :data:`cs`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_cheb_init (gsl_cheb_series * cs, const gsl_function * f, const double a, const double b)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function computes the Chebyshev approximation :data:`cs` for the
|
|
Packit |
67cb25 |
function :data:`f` over the range :math:`(a,b)` to the previously specified
|
|
Packit |
67cb25 |
order. The computation of the Chebyshev approximation is an
|
|
Packit |
67cb25 |
:math:`O(n^2)` process, and requires :math:`n` function evaluations.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Auxiliary Functions
|
|
Packit |
67cb25 |
===================
|
|
Packit |
67cb25 |
The following functions provide information about an existing
|
|
Packit |
67cb25 |
Chebyshev series.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: size_t gsl_cheb_order (const gsl_cheb_series * cs)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function returns the order of Chebyshev series :data:`cs`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: size_t gsl_cheb_size (const gsl_cheb_series * cs)
|
|
Packit |
67cb25 |
double * gsl_cheb_coeffs (const gsl_cheb_series * cs)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
These functions return the size of the Chebyshev coefficient array
|
|
Packit |
67cb25 |
:code:`c[]` and a pointer to its location in memory for the Chebyshev
|
|
Packit |
67cb25 |
series :data:`cs`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Chebyshev Series Evaluation
|
|
Packit |
67cb25 |
===========================
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: double gsl_cheb_eval (const gsl_cheb_series * cs, double x)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function evaluates the Chebyshev series :data:`cs` at a given point :data:`x`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_cheb_eval_err (const gsl_cheb_series * cs, const double x, double * result, double * abserr)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function computes the Chebyshev series :data:`cs` at a given point
|
|
Packit |
67cb25 |
:data:`x`, estimating both the series :data:`result` and its absolute error
|
|
Packit |
67cb25 |
:data:`abserr`. The error estimate is made from the first neglected term
|
|
Packit |
67cb25 |
in the series.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: double gsl_cheb_eval_n (const gsl_cheb_series * cs, size_t order, double x)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function evaluates the Chebyshev series :data:`cs` at a given point
|
|
Packit |
67cb25 |
:data:`x`, to (at most) the given order :data:`order`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_cheb_eval_n_err (const gsl_cheb_series * cs, const size_t order, const double x, double * result, double * abserr)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function evaluates a Chebyshev series :data:`cs` at a given point
|
|
Packit |
67cb25 |
:data:`x`, estimating both the series :data:`result` and its absolute error
|
|
Packit |
67cb25 |
:data:`abserr`, to (at most) the given order :data:`order`. The error
|
|
Packit |
67cb25 |
estimate is made from the first neglected term in the series.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. @deftypefun double gsl_cheb_eval_mode (const gsl_cheb_series * cs, double x, gsl_mode_t mode)
|
|
Packit |
67cb25 |
.. @end deftypefun
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. @deftypefun int gsl_cheb_eval_mode_err (const gsl_cheb_series * cs, const double x, gsl_mode_t mode, double * result, double * abserr)
|
|
Packit |
67cb25 |
.. Evaluate a Chebyshev series at a given point, using the default
|
|
Packit |
67cb25 |
.. order for double precision mode(s) and the single precision
|
|
Packit |
67cb25 |
.. order for other modes.
|
|
Packit |
67cb25 |
.. @end deftypefun
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Derivatives and Integrals
|
|
Packit |
67cb25 |
=========================
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The following functions allow a Chebyshev series to be differentiated or
|
|
Packit |
67cb25 |
integrated, producing a new Chebyshev series. Note that the error
|
|
Packit |
67cb25 |
estimate produced by evaluating the derivative series will be
|
|
Packit |
67cb25 |
underestimated due to the contribution of higher order terms being
|
|
Packit |
67cb25 |
neglected.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_cheb_calc_deriv (gsl_cheb_series * deriv, const gsl_cheb_series * cs)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function computes the derivative of the series :data:`cs`, storing
|
|
Packit |
67cb25 |
the derivative coefficients in the previously allocated :data:`deriv`.
|
|
Packit |
67cb25 |
The two series :data:`cs` and :data:`deriv` must have been allocated with
|
|
Packit |
67cb25 |
the same order.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. function:: int gsl_cheb_calc_integ (gsl_cheb_series * integ, const gsl_cheb_series * cs)
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
This function computes the integral of the series :data:`cs`, storing the
|
|
Packit |
67cb25 |
integral coefficients in the previously allocated :data:`integ`. The two
|
|
Packit |
67cb25 |
series :data:`cs` and :data:`integ` must have been allocated with the same
|
|
Packit |
67cb25 |
order. The lower limit of the integration is taken to be the left hand
|
|
Packit |
67cb25 |
end of the range :data:`a`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Examples
|
|
Packit |
67cb25 |
========
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The following example program computes Chebyshev approximations to a
|
|
Packit |
67cb25 |
step function. This is an extremely difficult approximation to make,
|
|
Packit |
67cb25 |
due to the discontinuity, and was chosen as an example where
|
|
Packit |
67cb25 |
approximation error is visible. For smooth functions the Chebyshev
|
|
Packit |
67cb25 |
approximation converges extremely rapidly and errors would not be
|
|
Packit |
67cb25 |
visible.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. include:: examples/cheb.c
|
|
Packit |
67cb25 |
:code:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
:numref:`fig_cheb` shows output from the program with the original function, 10-th order
|
|
Packit |
67cb25 |
approximation and 40-th order approximation, all sampled at intervals of
|
|
Packit |
67cb25 |
0.001 in :math:`x`.
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. _fig_cheb:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
.. figure:: /images/cheb.png
|
|
Packit |
67cb25 |
:scale: 60%
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Chebyshev approximations to a step function
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
References and Further Reading
|
|
Packit |
67cb25 |
==============================
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
The following paper describes the use of Chebyshev series,
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
* R. Broucke, "Ten Subroutines for the Manipulation of Chebyshev Series
|
|
Packit |
67cb25 |
[C1] (Algorithm 446)". *Communications of the ACM* 16(4), 254--256
|
|
Packit |
67cb25 |
(1973)
|