casacore
scimath
Functionals.h
Go to the documentation of this file.
1
//# Functionals.h: A module that represents various function-like classes.
2
//# Copyright (C) 1995,1996,1998,1999,2001,2002
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: aips2-request@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
//# $Id$
27
28
29
#ifndef SCIMATH_FUNCTIONALS_H
30
#define SCIMATH_FUNCTIONALS_H
31
32
//# Base classes
33
#include <casacore/casa/aips.h>
34
#include <casacore/casa/BasicMath/Functional.h>
35
#include <casacore/scimath/Functionals/FunctionTraits.h>
36
#include <casacore/scimath/Functionals/FunctionParam.h>
37
#include <casacore/scimath/Functionals/Function.h>
38
#include <casacore/scimath/Functionals/Function1D.h>
39
40
//# Combination methods
41
#include <casacore/scimath/Functionals/FunctionWrapper.h>
42
#include <casacore/scimath/Functionals/CombiFunction.h>
43
#include <casacore/scimath/Functionals/CompoundFunction.h>
44
45
//# remainder will be removed
46
#include <casacore/scimath/Functionals/SampledFunctional.h>
47
48
//# 1-D Functions
49
#include <casacore/scimath/Functionals/Interpolate1D.h>
50
#include <casacore/scimath/Functionals/ArraySampledFunctional.h>
51
#include <casacore/scimath/Functionals/ScalarSampledFunctional.h>
52
53
namespace
casacore
{
//# NAMESPACE CASACORE - BEGIN
54
55
// <module>
56
//
57
// <summary>A module that represents various function-like classes.</summary>
58
59
// <reviewed reviewer="tcornwel" date="1996/02/13" demos=""></reviewed>
60
61
// <etymology>
62
// The term <src>Functional</src> was chosen to roughly follow the usage in
63
// Barton and Nackman's <em>Scientific and Engineering C++</em>.
64
// Functional classes map a Domain object into a Range object, rather like a
65
// mathematical <src>function</src>. They use <src>operator()</src>,
66
// so they look much like single argument C++ <src>functions</src>.
67
// </etymology>
68
//
69
// <synopsis>
70
// <src>Functionals</src> and their derived classes map an input
71
// <src>Domain</src> object into an output <src>Range</src> object using the
72
// <src>operator()</src>.
73
// Often the input and output types are numeric, but it can be of any type.
74
// <srcblock>
75
// class Offspring : public Functional<List<Parents>, List<Children> > {
76
// public:
77
// List<Children> operator()(List<Parents>);
78
// };
79
// </srcblock>
80
// would be a legal Functional.
81
//
82
// The <src>Functions</src> and their derived classes map, again using the
83
// <src>operator()</src>, numeric value(s) into a numeric value. Since they are
84
// numeric, the <src>Domain</src> and <src>Range</src> base type can be of type
85
// <src>AutoDiff<T></src> (where <src>T</src> is numeric base type) or one
86
// of its derivations, in which case the value and its derivatives will be
87
// calculated.
88
//
89
// <note role=warning> In the current version the <src>Domain</src> and
90
// <src>Range</src> are the same for Functions </note>
91
//
92
// The basic classes are:
93
// <dl>
94
// <dt> <linkto class=Functional><src>Functional<Domain, Range></src></linkto>
95
// <dd>
96
// A base class that maps a <src>Domain</src> object into a <src>Range</src>
97
// object using the <src>Range operator(const Domain &)</src>. All
98
// information necessary to convert the <src>Domain</src> into a
99
// <src>Range</src> will be available in the class
100
// or in the input information. No variable class state (<em>parameters</em>)
101
// are available.
102
//
103
// <dt> <linkto class=FunctionParam><src>FunctionParam<T></src></linkto>
104
// <dd> A helper base class that acts as a container for <em>parameters</em>
105
// (<em>state</em>) used in <src>Function</src> classes. The class contains
106
// a list of parameters, and a list of flags associated with the parameters.
107
// Methods to set and obtain the parameters (using <src>operator[]</src>)
108
// and their flags (using methods <src>mask()</src>) are available. The flags
109
// can e.g. be used to indicate to <src>Fitting</src> routines if a certain
110
// parameter has to be updated ('fitted') or not.
111
// <note role=tip>
112
// The FunctionParam class does not assume anything about the uses of the
113
// class, but leaves that to the final users. This means that a lot of
114
// copying between intermediate and final users is not necessary
115
// (like between a Gaussian fitter with fixed parameters
116
// and the Fitting routines: the Gaussian fitter just sets a flag to False, and
117
// let the Fitting worry about what to do internally).
118
// </note>
119
//
120
// <dt> <linkto class=Function><src>Function<T></src></linkto>
121
// <dd> Base class for function objects with zero or more parameters (i.e.
122
// Functionals with state).
123
// All parameters should be of the same type <em>T</em> as the <src>
124
// Function<T></src>. <src>Function</src> objects are specifically geared
125
// towards use in the <linkto module=Fitting>Fitting</linkto> classes, but
126
// can be used anywhere where the value (and/or derivatives) of functions
127
// are needed.
128
//
129
// The <src>Function<T></src> class is derived from <src>Functional</src>
130
// and contains a <src>FunctionParam<T></src> object.
131
// The parameters act as state for the function
132
// (e.g. a width for a Gaussian). A function object is called using the
133
// <src>T operator(const T&)</src> (<em>ndim=1</em>), or the
134
// <src>T operator(const Vector<T>&)</src> (all values of <em>ndim</em>), or
135
// <src>T operator(const T&, const T&)</src> (for <em>ndim=2</em> only).
136
// If the template argument is <src>AutoDiff<T></src>, the parameters and the
137
// returned value will be <src>AutoDiff<T></src>; the arguments of the
138
// <src>operator()</src> will be of type <src>T</src>. The returned value
139
// of the function will be the function value at <em>x</em> (and the
140
// derivatives w.r.t. the non-masked parameters) Using <src>AutoDiffA<T></src>
141
// the derivatives can be calculated w.r.t. parameters and/or arguments, see
142
// <linkto class=AutoDiff>AutoDiff</linkto> and <linkto class=FunctionTraits>
143
// FunctionTraits</linkto> for details.
144
//
145
// <note role=tip>
146
// A <src>Function1D</src> is provided for 1-dimensional function objects
147
// </note>
148
// </dl>
149
//
150
// Actual functional classes:
151
// <dl>
152
// <dt> e.g. <linkto
153
// class=Gaussian1D><src>Gaussian1D<T></src></linkto>
154
// <dd> An actual function object will be derived from
155
// <src>Function<T></src>. The minimum functionality of a Function
156
// object will be support for the <src>operator()</src> methods (through a
157
// single, hidden, <src>eval()</src> method); for the manipulation of the
158
// associated parameters (using <src>operator[index]</src> and
159
// <src>mask(index)</src>) and some administrative aids (<src>ndim()</src>,
160
// <src>nparameters()</src> and the like.
161
//
162
// In most cases it is advantageous to have a special parameter handling
163
// class (e.g. <src>Gaussian1DParam</src>), to separate the (template
164
// independent) parameter handling from the possible specialization of
165
// the <src>eval()</src> method, and to more easily incorporate
166
// special parameter handling (e.g. using <em>flux</em> rather than amplitude
167
// of a Gaussian). All of this is transparent to the end-user.
168
// </dl>
169
// Combinatory Function objects are provided to easily combine and create
170
// function objects:
171
// <dl>
172
// <dt> <linkto class=CompoundFunction>CompoundFunction</linkto>
173
// <dd> creates
174
// a new, compound, function object from one or more other function objects
175
// (including compounds...). The new function will have the sum of the
176
// parameters of the input functions as the new parameters (i.e the compound
177
// function created from a 1-dimensional Gaussian (with 3 parameters) and a
178
// third-order polynomial (with 4 parameters) will have 7 parameters).
179
// <dt> <linkto class=CombiFunction>CombiFunction</linkto>
180
// <dd> creates
181
// a (linear) combination of a number of input functions. The number of
182
// parameters of the newly created function will be equal to the number of
183
// input functions (i.e. the combi
184
// function created from a 1-dimensional Gaussian (with 3 parameters) and a
185
// third-order polynomial (with 4 parameters) will have 2 parameters). The
186
// function will be <src>param0*gauss(x) + param1*poly(x)</src>
187
// <dt> <linkto class=FunctionWrapper>FunctionWrapper</linkto>
188
// <dd> will take
189
// a global function (or by the use of the <em>STL</em> function adapters
190
// <src>mem_fun*</src> also member functions) of any dimension, and with
191
// any number of parameters. The function is assumed to be called as
192
// <src>f(x, p)</src>, and is wrapped like
193
// <src>FunctionWrapper(&func, param&, ndim)</src> (see example).
194
//
195
// </dl>
196
//
197
// </synopsis>
198
199
// <example>
200
// A function to find a bracketed root by bisection could be written
201
// as follows:
202
// <srcblock>
203
// template <class Domain, class Range>
204
// Domain findRoot(const Functional<Domain,Range> &func, Domain left,
205
// Domain right, Domain tol) {
206
// Range fr = func(right);
207
// Range fl = func(left);
208
// Range sign = fr > 0 ? 1 : -1 ;
209
// AlwaysAssertExit(fl*fr < 0.0 && right > left);
210
// while (right - left > tol) {
211
// Domain mid = (left + right) / 2;
212
// Range fmid = func(mid);
213
// if (sign*fmid > 0.0) right = mid;
214
// else left = mid;
215
// };
216
// return (left + right)/2;
217
// }
218
// </srcblock>
219
// Since Function1D is derived from Functional, the
220
// above function will also work with classes derived from Function1D. To
221
// behave sensibly, the Domain and Range types should be real, <em>i.e.</em>,
222
// Float or Double.
223
//
224
// To calculate the value of a polynomial
225
// <srcblock>2 + 4x<sup>2</sup> + 6x<sup>4</sup></srcblock>
226
// at <src>x=5.1</src>:
227
// <srcblock>
228
// Polynomial<Double> pol(4);
229
// pol[0] = 2; pol[2] = 4; pol[4] = 6;
230
// cout << "Polynomial value at 5.1: " << pol(5.1) << endl;
231
// </srcblock>
232
//
233
// Create a simple function (1-dimensional) with 2 parameters (A and B):
234
// <srcblock>
235
// Double myf(const Double x, const Vector<Double> p) {
236
// return p[0]*sin(p[1]*x); }
237
// </srcblock>
238
// make it into a function object for initial parameters 2 and pi:
239
// <srcblock>
240
// Vector<Double> p(2);
241
// p[0] = 2; p[1] = C::pi;
242
// FunctionWrapper<Double> f0(myf, p, 2);
243
// </srcblock>
244
// Make the first parameter 3:
245
// <srcblock>
246
// f0[0] = 3;
247
// </srcblock>
248
// (for the global function you have to change <src>p[0]</src>).
249
// Calculate the value of the function:
250
// <srcblock>
251
// cout << "The value " << f0(3) << " should be 1.5 times the value " <<
252
// myf(3) << endl;
253
// </srcblock>
254
// A function object could be created as:
255
// <srcblock>
256
// template<class T> class objf : public Function<T> {
257
// public:
258
// objf() : Function<T>(2) {}; // 2 parameters
259
// objf(const objf<T> &other) : Function<T>(other) {};
260
// virtual ~objf() {};
261
// // The actual method called for the evaluation operator():
262
// virtual T eval(typename Function<T>::FunctionArg x) const {
263
// return param_p[0] * sin(param_p[1] * x[0]); };
264
// // Return a copy of function (used for combination e.g.)
265
// virtual Function<T> *clone() const {
266
// return new objf<T>(*this); };
267
// };
268
// </srcblock>
269
// Which can be called as:
270
// <srcblock>
271
// objf<Double> f1;
272
// f1[0] = 2; f1[1] = C::pi;
273
// cout << "The value " << myf(3) << " should be equal to the value " <<
274
// f1(3) << endl;
275
// </srcblock>
276
// </example>
277
278
// <motivation>
279
// The immediate motivations for this module were:
280
// <ol>
281
// <li> To represent functions which are used in linear and non-linear least
282
// squares fitting
283
// </ol>
284
// </motivation>
285
286
// <todo asof="2001/12/30">
287
// <li> It could be convenient to have a letter/envelope class, and to
288
// define ``function arithmetic.''
289
// </todo>
290
291
// </module>
292
293
294
}
//# NAMESPACE CASACORE - END
295
296
#endif
297
casacore
this file contains all the compiler specific defines
Definition:
mainpage.dox:28
Generated by
1.8.18