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