casacore
Loading...
Searching...
No Matches
Chebyshev.h
Go to the documentation of this file.
1// # Chebyshev.h A function class that defines a Chebyshev polynomial
2// # Copyright (C) 2000,2001,2002,2003,2005
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25// #
26// #! ========================================================================
27
28#ifndef SCIMATH_CHEBYSHEV_H
29#define SCIMATH_CHEBYSHEV_H
30
31#include <casacore/casa/aips.h>
32#include <casacore/scimath/Functionals/ChebyshevParam.h>
33#include <casacore/scimath/Functionals/Function1D.h>
34#include <casacore/scimath/Mathematics/AutoDiff.h>
35#include <casacore/scimath/Mathematics/AutoDiffMath.h>
36
37namespace casacore { // # NAMESPACE CASACORE - BEGIN
38
39// # Forward Declarations
40
41// <summary> A function class that defines a Chebyshev polynomial
42// </summary>
43
44// <use visibility=export>
45
46// <reviewed reviewer="wbrouw" date="2001/11/12" tests="tChebyshev" demos="">
47// </reviewed>
48
49// <prerequisite>
50// <li> <linkto class=Function>Function</linkto>
51// </prerequisite>
52//
53// <etymology>
54// This class is named after Chebyshev Type I polynomials
55// </etymology>
56//
57// <synopsis>
58// This class allows one to form and evaluate a function as a
59// Chebyshev series, a linear combination of so-called Chebyshev
60// polynomials.
61//
62// This class's implementation is split into two parts:
63// the parent class <linkto class="ChebyshevParam">ChebyshevParam&lt;T&gt;</linkto>,
64// which manages the function's parameters, and this class, which handles
65// how the function is evaluated. Thus, be sure to also consult
66// <linkto class="ChebyshevParam">ChebyshevParam&lt;T&gt;</linkto> for
67// the full interface of this function.
68//
69// <ANCHOR NAME="Chebyshev:about">
70// <H3>About Chebyshev Polynomials</H3></ANCHOR>
71//
72// Chebyshev polynomials are a special type of ultraspheric polynomials
73// that are useful in such contexts as numerical analysis and circuit
74// design. They form an orthogobnal set.
75// A (type I) Chebyshev polynomial, T_n, is generated via the
76// equation:
77// <srcblock>
78// T_n(x) = cos n(arccos x)
79// </srcblock>
80// Through clever use of trigometric identities, one can express T_n
81// as a real polynomial expression of the form
82// <srcblock>
83// n
84// T_n(x) = SUM C_i t^i
85// i=0
86// </srcblock>
87// The low order polynomials look like this:
88// <srcblock>
89// T_0 = 1
90// T_1 = x
91// T_2 = 2x^2 - 1
92// T_3 = 4x^3 - 3x
93// T_4 = 8x^4 - 8x^2 + 1
94// T_5 = 16x^5 - 20x^3 + 5x
95// </srcblock>
96// Higher order polynomials satisfy the recurrance relation,
97// <srcblock>
98// T_(n+1) = 2xT_(n) - T_(n-1).
99// </srcblock>
100//
101// A common use of Chebyshev polynomials is in approximating
102// functions. In particular, any function that is approximated by
103// a power series,
104// <srcblock>
105// f(x) ~ SUM P_i x^i,
106// </srcblock>
107// over the interval [-1, 1] can be approximated by a linear
108// combination of Chebyshev polynomials:
109// <srcblock>
110// f(x) ~ SUM C_i T_i(x),
111// </srcblock>
112// where C_i is the set of so-called Chebyshev coefficients.
113//
114// Approximating a function with Chebyshev polynomials has some
115// important advantages. For one, if the function is well approximated
116// by a converging power series, one can obtain an equally accurate
117// estimate using fewer terms of the corresponding Chebyshev series.
118// More important, though, is the property over the interval [-1, 1],
119// each polynomial has a domain of [-1, 1]; thus, the series is nicely
120// bounded. And because of this bounded property, approximations
121// calculated from a Chebyshev series are less susceptible to machine
122// rounding errors than the equivalent power series.
123//
124// <ANCHOR NAME="Chebyshev:using">
125// <H3>Using the Chebyshev Function class</H3></ANCHOR>
126//
127// With a simple change of variable, it is possible to approximate a
128// continuous function over any restricted interval using a
129// Chebyshev series. This documention refers to this interval as the
130// <em>Chebyshev interval</em> (set with the
131// <linkto class="ChebyshevParam">setInterval()</linkto> function). The
132// other important input parameters, of course, include the
133// coefficients of the polynomials.
134//
135// Like all Functions, the Chebyshev series is evaluated via the
136// function operator, <src>operator()</src>. If the input value is
137// within the range set by
138// <linkto class="ChebyshevParam">setInterval()</linkto>, it is
139// transformed to the range [-1, 1] via,
140// <srcblock>
141// y = x - (min + max)/2) / ((max - min)/2)
142// </srcblock>
143// The series is then evaluated with the coefficients set either at
144// construction or via setCoefficients(). The value that is returned
145// when the input value is outside the Chebyshev interval depends on
146// the out-of-interval mode (set via
147// <linkto class="ChebyshevParam">setOutOfIntervalMode()</linkto>). The
148// default mode is to return a default value which can be set via
149// <linkto class="ChebyshevParam">setDefault()</linkto>. The supported
150// modes are identified by the
151// enumeration OutOfIntervalMode; see the
152// <linkto class="ChebyshevParam">documentation for ChebyshevParam</linkto>
153// for a detailed description of these modes. In practice, though, it is
154// expected that this class will be configured for the interval of interest.
155//
156// The derivative of a Chebyshev series with respect to the independent
157// variable (i.e. the argument <src>x</src>) is easily calculated analytically
158// and can be expressed as another Chebyshev series; this is what the
159// <src>derivative()</src> function returns. However, the more general way to
160// obtain derivatives is via the <linkto class="AutoDiff">AutoDiff</linkto>
161// templated type.
162//
163// </synopsis>
164//
165// <example>
166// In this example, a 2nd order Chebyshev polynomial series is
167// created.
168// <srcblock>
169// // set coeffs to desired values
170// Vector<Double> coeffs(3, 1);
171//
172// // configure the function
173// Chebyshev<Double> cheb;
174// cheb.setInterval(-0.8, 7.2);
175// cheb.setDefault(1.0);
176// cheb.setCoefficients(coeffs);
177//
178// // evaluate the function as necessary
179// Double z = cheb(-0.5); // -0.5 is within range, z = 0.78625
180// z = cheb(4.2); // 4.2 is within range, z = 0.375
181// z = cheb(-3); // -3 is out of the interval, z = 1
182// </srcblock>
183//
184// The next example illustrates how to use the
185// <linkto class="AutoDiff">AutoDiff</linkto> class to simultaneously
186// calculate derivatives. Here, we replace the Double type with
187// AutoDiff<Double>.
188// <srcblock>
189// Chebyshev<AutoDiffA<Double> > cheb;
190// cheb.setDefault(AutoDiffA<Double>(1));
191// cheb.setInterval(AutoDiffA<Double>(-0.8), AutoDiffA<Double>(7.2));
192//
193// // we'll track derivatives with respect to x and each of our
194// // coefficients; for a second-order series, this makes 4
195// // derivatives total. x will be the first variable; the
196// // coefficients will the 2nd-4th variables
197// cheb.setCoefficient(0, AutoDiffA<Double>(3.1, 4, 1)); // c0 = 3.1
198// cheb.setCoefficient(1, AutoDiffA<Double>(2.4, 4, 2)); // c1 = 2.4
199// cheb.setCoefficient(2, AutoDiffA<Double>(0.5, 4, 3)); // c2 = 0.5
200//
201// // now evaluate the function
202// AutoDiffA<Double> x(1.2, 4, 0); // x = 1.2
203// AutoDiffA<Double> y = cheb(x); // y = 1.65
204// Double dydx = y.derivative(0); // dy/dx = 0.35
205// Double dydc1 = y.derivative(2); // dy/dc1 = -0.5
206// </srcblock>
207// </example>
208//
209// <motivation>
210// This class was created to support systematic errors in the simulator tool.
211// It can be used by Jones matrix classes to vary gains in a predictable way,
212// mimicing natural processes of the atmosphere or instrumental effects.
213// </motivation>
214
215// <templating arg=T>
216// <li> T should have standard numerical operators. Current
217// implementation only tested for real types (and their AutoDiffs).
218// </templating>
219
220// <thrown>
221// <li> Assertion in debug mode if attempt is made to address incorrect
222// coefficients
223// </thrown>
224//
225// <todo asof="2001/08/22">
226// <li> It would be helpful to be able to convert to and from the
227// Polynomial<T> type; this would be supported via a function,
228// Polynomial<T> polynomial(), and constructor,
229// Chebyshev(Polynomial<T>)
230// </todo>
231
232template <class T>
234 public:
235 // # Constructors
236 // create a zero-th order Chebyshev polynomial with the first coefficient
237 // equal to zero. The bounded domain is [T(-1), T(1)]. The
238 // OutOfDomainMode is CONSTANT, and the default value is T(0).
240
241 // create an n-th order Chebyshev polynomial with the coefficients
242 // equal to zero. The bounded domain is [T(-1), T(1)]. The
243 // OutOfDomainMode is CONSTANT, and the default value is T(0).
244 explicit Chebyshev(const uInt n) : ChebyshevParamModeImpl<T>(n) {}
245
246 // create a zero-th order Chebyshev polynomical with the first coefficient
247 // equal to one.
248 // min is the minimum value of its Chebyshev interval, and
249 // max is the maximum value.
250 // mode sets the behavior of the function outside the Chebyshev interval
251 // (see setOutOfIntervalMode() and OutOfIntervalMode enumeration
252 // definition for details).
253 // defval is the value returned when the function is evaluated outside
254 // the Chebyshev interval and mode=CONSTANT.
255 Chebyshev(const T &min, const T &max,
257 const T &defval = T(0))
258 : ChebyshevParamModeImpl<T>(min, max, mode, defval) {}
259
260 // create a fully specified Chebyshev polynomial.
261 // coeffs holds the coefficients of the Chebyshev polynomial (see
262 // setCoefficients() for details).
263 // min is the minimum value of its canonical range, and
264 // max is the maximum value.
265 // mode sets the behavior of the function outside the Chebyshev interval
266 // (see setOutOfIntervalMode() and OutOfIntervalMode enumeration
267 // definition for details).
268 // defval is the value returned when the function is evaluated outside
269 // the canonical range and mode=CONSTANT.
270 Chebyshev(const Vector<T> &coeffs, const T &min, const T &max,
272 const T &defval = T(0))
273 : ChebyshevParamModeImpl<T>(coeffs, min, max, mode, defval) {}
274
275 // create a fully specified Chebyshev polynomial.
276 // config is a record that contains the non-coefficient data
277 // that configures this class.
278 // The fields recognized by this class are those documented for the
279 // <linkto class="ChebyshevParam">ChebyshevPara::setMode()</linkto>
280 // function.
281 // <group>
283 Chebyshev(const Vector<T> &coeffs, const RecordInterface &mode)
284 : ChebyshevParamModeImpl<T>(coeffs, mode) {}
285 // </group>
286
287 // create a deep copy of another Chebyshev polynomial
288 // <group>
289 Chebyshev(const Chebyshev &other) : ChebyshevParamModeImpl<T>(other) {}
290 // </group>
291
292 // make this instance a (deep) copy of another Chebyshev polynomial
295 return *this;
296 }
297
298 // Destructor
299 virtual ~Chebyshev() {}
300
301 // # Operators
302 // Evaluate the Chebyshev at <src>x</src>.
303 virtual T eval(const typename FunctionTraits<T>::ArgType *x) const;
304
305 // # Member functions
306 // Return the Chebyshev polynomial which is the derivative of this one
307 // (with respect to the argument <src>x</src>).
309
310 // Create a new copy of this object. The caller is responsible
311 // for deleting the pointer.
312 // <group>
313 virtual Function<T> *clone() const { return new Chebyshev<T>(*this); }
314 // </group>
315};
316
317} // namespace casacore
318
319#ifndef CASACORE_NO_AUTO_TEMPLATES
320#include <casacore/scimath/Functionals/Chebyshev.tcc>
321#endif // # CASACORE_NO_AUTO_TEMPLATES
322#endif
OutOfIntervalMode
Modes that identify how this function behaves outside its Chebyshev interval (see setInterval()).
@ CONSTANT
return a constant, default value.
uInt order() const
return the order of this polynomial.
ChebyshevParam< T > & operator=(const ChebyshevParam< T > &other)
make a (deep) copy of another Chebyshev polynomial
Chebyshev()
create a zero-th order Chebyshev polynomial with the first coefficient equal to zero.
Definition Chebyshev.h:239
Chebyshev(const uInt n)
create an n-th order Chebyshev polynomial with the coefficients equal to zero.
Definition Chebyshev.h:244
virtual ~Chebyshev()
Destructor.
Definition Chebyshev.h:299
Chebyshev(const T &min, const T &max, const typename ChebyshevEnums::OutOfIntervalMode mode=ChebyshevEnums::CONSTANT, const T &defval=T(0))
create a zero-th order Chebyshev polynomical with the first coefficient equal to one.
Definition Chebyshev.h:255
Chebyshev< T > derivative() const
Return the Chebyshev polynomial which is the derivative of this one (with respect to the argument x).
Chebyshev< T > & operator=(const Chebyshev< T > &other)
make this instance a (deep) copy of another Chebyshev polynomial
Definition Chebyshev.h:293
Chebyshev(const Vector< T > &coeffs, const RecordInterface &mode)
Definition Chebyshev.h:283
Chebyshev(const Vector< T > &coeffs, const T &min, const T &max, const typename ChebyshevEnums::OutOfIntervalMode mode=ChebyshevEnums::CONSTANT, const T &defval=T(0))
create a fully specified Chebyshev polynomial.
Definition Chebyshev.h:270
Chebyshev(const Chebyshev &other)
create a deep copy of another Chebyshev polynomial
Definition Chebyshev.h:289
virtual Function< T > * clone() const
Create a new copy of this object.
Definition Chebyshev.h:313
virtual T eval(const typename FunctionTraits< T >::ArgType *x) const
Evaluate the Chebyshev at x.
Chebyshev(uInt order, const RecordInterface &mode)
create a fully specified Chebyshev polynomial.
Definition Chebyshev.h:282
T ArgType
Type for arguments.
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
LatticeExprNode max(const LatticeExprNode &left, const LatticeExprNode &right)
unsigned int uInt
Definition aipstype.h:49
LatticeExprNode min(const LatticeExprNode &left, const LatticeExprNode &right)
RecordInterface()
The default constructor creates an empty record with a variable structure.