casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Function.h
Go to the documentation of this file.
1 //# Function.h: Numerical functional interface class
2 //# Copyright (C) 2001,2002,2003,2004,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: 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 #ifndef SCIMATH_FUNCTION_H
29 #define SCIMATH_FUNCTION_H
30 
31 //# Includes
32 #include <casacore/casa/aips.h>
38 
39 //# Forward declarations
40 #include <casacore/casa/iosfwd.h>
41 
42 namespace casacore { //# NAMESPACE CASACORE - BEGIN
43 
44 //# Forward declarations
45 class String;
46 class RecordInterface;
47 
48 // <summary> Numerical functional interface class
49 // </summary>
50 
51 // <use visibility=export>
52 
53 // <reviewed reviewer="tcornwel" date="1996/02/22" tests="tGaussian2D"
54 // demos="">
55 // </reviewed>
56 
57 // <prerequisite>
58 // <li> <linkto class="Functional">Functional</linkto>
59 // <li> <linkto class="FunctionParam">FunctionParam</linkto>
60 // </prerequisite>
61 //
62 // <synopsis>
63 // A <src>Function</src> is used for classes which map a
64 // scalar or n-dimensional Vector of type <src>T</src> into a <src>T</src>.
65 // The object also has zero or more parameters which can be masked
66 // if necessary, and be used in the <src>Fitting</src> module, and, implicitly,
67 // in the <linkto class=AutoDiff>AutoDiff</linkto> differentiation module.
68 //
69 // The parameter interface is provided by the
70 // <linkto class="FunctionParam"><src>FunctionParam</src></linkto> class.
71 //
72 // A Function can have a <src>name()</src> which can be used in generic
73 // interfaces.
74 //
75 // The function calls implemented are:
76 // <ul>
77 // <li> <src>operator()()</src>
78 // <li> <src>operator()(const T &x)</src>
79 // <li> <src>operator()(const Vector<T> &x)</src>
80 // <li> <src>operator()(Function::FunctionArg x)</src>
81 // <li> <src>operator()(const T &x, const T &y)</src> (for 2D)
82 // <li> <src>operator()(const T &x, const T &y, const T &z)</src> (for 3D)
83 // </ul>
84 // The <src>T</src> in the above is the <src>Function::ArgType</src>
85 // as derived from the <linkto class="FunctionTraits">FunctionTraits</linkto>
86 // class.
87 // These calls are (in debug mode) tested for the correct number of arguments,
88 // after which they call a <src>T eval(FunctionArg x) const = 0</src> to
89 // be implemented in derived classes. The derived class should also implement
90 // an <src>uInt ndim() const = 0</src>. The derived class can access the
91 // nth parameter with the <src>[n]</src> operator, and the corresponding
92 // mask with <src>mask(n)</src> method.
93 // The variables are referenced with <src>x[i]</src>.
94 //
95 // </synopsis>
96 
97 // <example>
98 // A complete implementation of say an <src>A.sin(2pi.f.x)</src> with
99 // parameters amplitude(<em>A</em>) and frequency(<em>f</em>) and variable
100 // time(<em>x</em>) could be:
101 // <srcblock>
102 // //# Sinusoid.h
103 // #include <casacore/casa/aips.h>
104 // #include <casacore/scimath/Functionals/Function.h>
105 // #include <casacore/casa/BasicSL/Constants.h>
106 // #include <casacore/casa/BasicMath/Math.h>
107 // // The sinusoid class
108 // template<class T> class Sinusoid : public Function<T> {
109 // public:
110 // // For easy reference of the parameters
111 // enum { AMPL=0, FREQ };
112 // // Constructors. Defaults are A=1, f=1
113 // Sinusoid() : Function<T>(2) {
114 // param_p[AMPL] = T(1.0); param_p[FREQ] = T(1.0); }
115 // explicit Sinusoid(const T &ampl) : Function<T>(2) {
116 // param_p[AMPL] = ampl; param_p[FREQ] = T(1.0); }
117 // Sinusoid(const T &ampl, const T &freq) : Function<T>(2) {
118 // param_p[AMPL] = ampl; param_p[FREQ] = freq; }
119 // Sinusoid(const Sinusoid &other) : Function<T>(2) {
120 // param_p[AMPL] = other.param_p[AMPL];
121 // param_p[FREQ] = other.parameter[FREQ]; }
122 // Sinusoid<T> &operator=(const Sinusoid<T> &other) {
123 // if (this != &other) param_p = other.param_p;
124 // return *this; }
125 // virtual ~Sinusoid() {}
126 // // Dimensionality
127 // virtual uInt ndim() const { return 2; }
128 // // Evaluate
129 // virtual T eval(Function<T>::FunctionArg x) const {
130 // return param_p[AMPL]*sin(T(C::_2pi)*param_p[FREQ]*x[0]); }
131 // // Copy it
132 // virtual Function<T> *clone() const { return new Sinusoid<T>(param_p); }
133 // };
134 // </srcblock>
135 // The following will calculate the value and the derivative for
136 // <src>A=2; f=3; x=0.1;</src>
137 // <srcblock>
138 // // The function objects for value, and for value + derivative
139 // Sinusoid<Double> soid1(2.0, 3.0);
140 // typedef AutoDiff<Double> Adif;
141 // Sinusoid<Adif> soid2(Adif(2,2,0), Adif(3,2,1));
142 // cout << "Value: " << soid1(0.1) << endl;
143 // cout << "(val, deriv): " << soid2(Adif(0.1)) << endl;
144 // </srcblock>
145 //
146 // A shorter version, where all parameter handling is done at user level
147 // could be:
148 // <srcblock>
149 // //# Sinusoid.h
150 // #include <casacore/casa/aips.h>
151 // #include <casacore/scimath/Functionals/Function.h>
152 // #include <casacore/casa/BasicSL/Constants.h>
153 // #include <casacore/casa/BasicMath/Math.h>
154 // template<class T> class Sinusoid : public Function<T> {
155 // public:
156 // enum { AMPL=0, FREQ };
157 // Sinusoid() : Function<T>(2){param_p[AMPL] T(1);param_p[FREQ]=T(1);}
158 // virtual ~Sinusoid() {}
159 // virtual uInt ndim() const { return 2; }
160 // virtual T eval(Function<T>::FunctionArg x) const {
161 // return param_p[AMPL]*sin(T(C::_2pi)*param_p[FREQ]*x[0]); }
162 // virtual Function<T> *clone() const { return new Sinusoid<T>param_p; }
163 // };
164 // </srcblock>
165 // The following will calculate the value and the derivative for
166 // <src>A=2; f=3; x=0.1;</src>
167 // <srcblock>
168 // // The function objects for value, and for value + derivative
169 // typedef AutoDiff<Double> Adif;
170 // typedef Function<Double> FD;
171 // typedef Function<AutoDiff<Double> > FAdif
172 // Sinusoid<Double> soid1;
173 // Sinusoid<Adif> soid2;
174 // soid1[FD::AMPL] = 2; soid1[FD::FREQ] = 3;
175 // soid2[FAdif::AMPL] = Adif(2,2,0);
176 // soid2[FAdif::FREQ] = Adif(3,2,1);
177 // cout << "Value: " << soid1(0.1) << endl;
178 // cout << "(val, deriv): " << soid2(Adif(0.1)) << endl;
179 // </srcblock>
180 // </example>
181 
182 // <motivation>
183 // A function of more than one variable was required for a function which
184 // represents the sky brightness. Adjustable parameters were required for
185 // non-linear least squares fitting.
186 // </motivation>
187 //
188 // <templating arg=T>
189 // <li> Besides the requirements set by the
190 // <linkto class="Functional">Functional</linkto> base class, it must be
191 // possible to form a <src>Vector<T></src>.
192 // </templating>
193 //
194 // <todo asof="2005/01/20">
195 // <li> At some point, we may want to implement a letter-envelope class,
196 // implement function arithmetic, etc.
197 // <li> use maybe Poolstack for static Vector
198 // </todo>
199 
200  template<class T, class U=T> class Function :
201  public Functional<typename FunctionTraits<T>::ArgType, U>,
202  public Functional<Vector<typename FunctionTraits<T>::ArgType>, U> {
203 
204  public:
205  //# Typedefs
207  typedef const ArgType* FunctionArg;
208 
209  //# Constructors
210  // Constructors
211  // <group>
213  explicit Function(const uInt n) : param_p(n), arg_p(0), parset_p(False),
214  locked_p(False) {}
215  explicit Function(const Vector<T> &in) : param_p(in), arg_p(0),
217  Function(const FunctionParam<T> &other) : param_p(other), arg_p(0),
219  template <class W, class X>
220  Function(const Function<W,X> &other) : param_p(other.parameters()),
221  arg_p(0), parset_p(other.parsetp()), locked_p(False) {}
222  Function(const Function<T,U> &other) :
223  Functional<typename FunctionTraits<T>::ArgType, U> (other),
224  Functional<Vector<typename FunctionTraits<T>::ArgType>, U>(other),
225  param_p(other.param_p),
226  arg_p(other.arg_p),
227  parset_p(other.parset_p),
228  locked_p(False)
229  {}
230  // </group>
231 
232  // Destructor
233  virtual ~Function() {}
234 
235  // Returns the number of dimensions of function
236  virtual uInt ndim() const = 0;
237  // Returns the number of parameters
238  uInt nparameters() const { return param_p.nelements(); }
239 
240  // Evaluate the function object
241  virtual U eval(FunctionArg x) const = 0;
242 
243  //# Operators
244  // Manipulate the nth parameter (0-based) with no index check
245  // <group>
246  T &operator[](const uInt n) { parset_p |= !locked_p;
247  return param_p[n]; }
248  const T &operator[](const uInt n) const { return param_p[n]; }
249  // </group>
250  // Evaluate this function object at <src>x</src>or at <src>x, y</src>.
251  // The length of <src>x</src> must be greater than or equal to
252  // <src>ndim()</src>.
253  // <group>
254  virtual U operator()() const {
255  DebugAssert(ndim()==0, AipsError); return eval(FunctionArg(0)); }
256  virtual U operator()(const ArgType &x) const {
257  DebugAssert(ndim()<=1, AipsError); return eval(&x); }
258  virtual U operator()(const Vector<ArgType> &x) const;
259  virtual U operator()(FunctionArg x) const { return eval(x); }
260  virtual U operator()(const ArgType &x, const ArgType &y) const;
261  virtual U operator()(const ArgType &x, const ArgType &y,
262  const ArgType &z) const;
263  // </group>
264 
265  //# Member functions
266  // Specify the name associated with the function (default will be
267  // <src>unknown</src>)
268  virtual const String &name() const;
269  // Manipulate the mask associated with the nth parameter
270  // (e.g. to indicate whether the parameter is adjustable or
271  // nonadjustable).
272  // Note: no index check.
273  // <group>
274  Bool &mask(const uInt n) { parset_p |= !locked_p;
275  return param_p.mask(n); }
276  const Bool &mask(const uInt n) const { return param_p.mask(n); }
277  // </group>
278  // Return the parameter interface
279  // <group>
280  const FunctionParam<T> &parameters() const { return param_p; }
282  // </group>
283  // Get <src>arg_p</src> and <src>parset_p</src>. Necessary for reasons
284  // of protection in the copying of non-conforming Functions.
285  // <group>
286  const Vector<ArgType> &argp() const { return arg_p; }
287  Bool parsetp() const { return parset_p; }
288  // </group>
289  // Compiler cannot always find the correct 'const' version of parameter
290  // access. In cases where this would lead to excessive overheads in
291  // moving parameters around (like in <src>CompoundFunction</src>) the
292  // parameter changing can be set to be locked, and no changes are
293  // assumed.
294  // <group>
295  void lockParam() { locked_p = True; }
296  void unlockParam() { locked_p = False; }
297  // </group>
298 
299  // get/set the function mode. These provide an interface to
300  // function-specific configuration or state that controls how the
301  // function calculates its values but otherwise does not qualify as
302  // a parameter. Some part of the state, for example, might have a
303  // type different from that of T. The state is passed as fields of a
304  // record, mode--the names, types and values of which are specific to
305  // the implementing function and should be documented in the implementing
306  // class. It is recommended that all possible inputs passed to this
307  // function via setMode() be considered optional such that if the
308  // record omits a legal field, that part of the state is left unchanged.
309  // Fields not recognized by the implementing class should be ignored.
310  // An exception should be thrown if a recognized field contains illegal
311  // data. The default implementations for both getMode() and setMode()
312  // ignore the input record.
313  // <group>
314  virtual void setMode(const RecordInterface& mode);
315  virtual void getMode(RecordInterface& mode) const;
316  // </group>
317 
318  // return True if the implementing function supports a mode. The default
319  // implementation returns False.
320  virtual Bool hasMode() const;
321 
322  // Print the function (i.e. the parameters)
323  ostream &print(ostream &os) const { return param_p.print(os); }
324  // Return a copy of this object from the heap. The caller is responsible
325  // for deleting this pointer. The <src>cloneAD</src> will return a clone
326  // with an <src>AutoDef<T></src>; the <src>cloneNonAD</src> a clone
327  // with <src><T></src>. An <src>AipsError</src> will be thrown if the
328  // <src>cloneAD()</src> or <src>cloneNonAD()</src> is not implemented
329  // for a specific function.
330  // <group>
331  virtual Function<T,U> *clone() const = 0;
334  *cloneNonAD() const;
335  // </group>
336 
337 protected:
338  //# Data
339  // The parameters and masks
341  // Aid for non-contiguous argument storage
343  // Indicate parameter written
344  mutable Bool parset_p;
345  // Indicate that parameters are expected to be locked from changing
346  mutable Bool locked_p;
347 };
348 
349 //# Global functions
350 // <summary> Global functions </summary>
351 // <group name=Output>
352 // Output declaration
353 template<class T, class U>
354 ostream &operator<<(ostream &os, const Function<T,U> &fun);
355 // </group>
356 
357 //# Inlines
358 template<class T, class U>
359 inline ostream &operator<<(ostream &os, const Function<T,U> &fun) {
360  return fun.print(os); }
361 
362 } //# NAMESPACE CASACORE - END
363 
364 #ifndef CASACORE_NO_AUTO_TEMPLATES
365 #include <casacore/scimath/Functionals/Function.tcc>
366 #endif //# CASACORE_NO_AUTO_TEMPLATES
367 #endif
uInt nparameters() const
Returns the number of parameters.
Definition: Function.h:238
Function(const uInt n)
Definition: Function.h:213
virtual U operator()(const ArgType &x) const
Definition: Function.h:256
Vector< ArgType > arg_p
Aid for non-contiguous argument storage.
Definition: Function.h:342
const Bool & mask(const uInt n) const
Definition: Function.h:276
A 1-D Specialization of the Array class.
FunctionParam< T > param_p
The parameters and masks.
Definition: Function.h:340
virtual void setMode(const RecordInterface &mode)
get/set the function mode.
Map a domain object into a range object via operator().
Definition: Functional.h:122
virtual const String & name() const
Specify the name associated with the function (default will be unknown)
Bool parset_p
Indicate parameter written.
Definition: Function.h:344
virtual U operator()() const
Evaluate this function object at xor at x, y.
Definition: Function.h:254
virtual void getMode(RecordInterface &mode) const
const Vector< ArgType > & argp() const
Get arg_p and parset_p.
Definition: Function.h:286
virtual uInt ndim() const =0
Returns the number of dimensions of function.
FunctionParam< T > & parameters()
Definition: Function.h:281
FunctionTraits< T >::ArgType ArgType
Definition: Function.h:206
T & operator[](const uInt n)
Manipulate the nth parameter (0-based) with no index check.
Definition: Function.h:246
Function(const Function< W, X > &other)
Definition: Function.h:220
const ArgType * FunctionArg
Definition: Function.h:207
Container of function parameters with masking flags.
Definition: FunctionParam.h:87
virtual Function< typename FunctionTraits< T >::DiffType > * cloneAD() const
Function()
Constructors.
Definition: Function.h:212
Bool parsetp() const
Definition: Function.h:287
Function(const Vector< T > &in)
Definition: Function.h:215
Numerical functional interface class.
#define DebugAssert(expr, exception)
Definition: Assert.h:185
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
Bool locked_p
Indicate that parameters are expected to be locked from changing.
Definition: Function.h:346
Function(const FunctionParam< T > &other)
Definition: Function.h:217
const Bool False
Definition: aipstype.h:44
void unlockParam()
Definition: Function.h:296
void lockParam()
Compiler cannot always find the correct &#39;const&#39; version of parameter access.
Definition: Function.h:295
T ArgType
Type for arguments.
Bool & mask(const uInt n)
Manipulate the mask associated with the nth parameter (e.g.
Definition: Function.h:274
virtual ~Function()
Destructor.
Definition: Function.h:233
const FunctionParam< T > & parameters() const
Return the parameter interface.
Definition: Function.h:280
virtual U operator()(FunctionArg x) const
Definition: Function.h:259
Base class for all Casacore library errors.
Definition: Error.h:134
ostream & print(ostream &os) const
Print the function (i.e.
Definition: Function.h:323
Function data types for parameters and arguments.
Function(const Function< T, U > &other)
Definition: Function.h:222
String: the storage and methods of handling collections of characters.
Definition: String.h:223
Abstract base class for Record classes.
virtual Function< T, U > * clone() const =0
Return a copy of this object from the heap.
virtual Bool hasMode() const
return True if the implementing function supports a mode.
const T & operator[](const uInt n) const
Definition: Function.h:248
virtual U eval(FunctionArg x) const =0
Evaluate the function object.
const Bool True
Definition: aipstype.h:43
unsigned int uInt
Definition: aipstype.h:51
virtual Function< typename FunctionTraits< T >::BaseType > * cloneNonAD() const
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42