casacore
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
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
SampledFunctional.h
FunctionTraits.h
aips.h
FunctionParam.h
ScalarSampledFunctional.h
ArraySampledFunctional.h
Function1D.h
FunctionWrapper.h
CombiFunction.h
Function.h
Interpolate1D.h
CompoundFunction.h
Functional.h
Generated by
1.8.5