Functionals.h

Go to the documentation of this file.
00001 //# Functionals.h: A module that represents various function-like classes.
00002 //# Copyright (C) 1995,1996,1998,1999,2001,2002
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id$
00027 
00028 
00029 #ifndef SCIMATH_FUNCTIONALS_H
00030 #define SCIMATH_FUNCTIONALS_H
00031 
00032 //# Base classes
00033 #include <casacore/casa/aips.h>
00034 #include <casacore/casa/BasicMath/Functional.h>
00035 #include <casacore/scimath/Functionals/FunctionTraits.h>
00036 #include <casacore/scimath/Functionals/FunctionParam.h>
00037 #include <casacore/scimath/Functionals/Function.h>
00038 #include <casacore/scimath/Functionals/Function1D.h>
00039 
00040 //# Combination methods
00041 #include <casacore/scimath/Functionals/FunctionWrapper.h>
00042 #include <casacore/scimath/Functionals/CombiFunction.h>
00043 #include <casacore/scimath/Functionals/CompoundFunction.h>
00044 
00045 //# remainder will be removed
00046 #include <casacore/scimath/Functionals/SampledFunctional.h>
00047 
00048 //# 1-D Functions
00049 #include <casacore/scimath/Functionals/Interpolate1D.h>
00050 #include <casacore/scimath/Functionals/ArraySampledFunctional.h>
00051 #include <casacore/scimath/Functionals/ScalarSampledFunctional.h>
00052 
00053 namespace casacore { //# NAMESPACE CASACORE - BEGIN
00054 
00055 // <module>
00056 //
00057 // <summary>A module that represents various function-like classes.</summary>
00058 
00059 // <reviewed reviewer="tcornwel" date="1996/02/13" demos=""></reviewed>
00060 
00061 // <etymology>
00062 // The term <src>Functional</src> was chosen to roughly follow the usage in
00063 // Barton and Nackman's <em>Scientific and Engineering C++</em>.
00064 // Functional classes map a Domain object into a Range object, rather like a
00065 // mathematical <src>function</src>. They use <src>operator()</src>,
00066 // so they look much like single argument C++ <src>functions</src>.
00067 // </etymology>
00068 //
00069 // <synopsis>
00070 // <src>Functionals</src> and their derived classes map an input
00071 // <src>Domain</src> object into an output <src>Range</src> object using the 
00072 // <src>operator()</src>.
00073 // Often the input and output types are numeric, but it can be of any type. 
00074 // <srcblock>
00075 // class Offspring : public Functional<List<Parents>, List<Children> > {
00076 //  public:
00077 //    List<Children> operator()(List<Parents>);
00078 // };
00079 // </srcblock>
00080 // would be a legal Functional.
00081 // 
00082 // The <src>Functions</src> and their derived classes map, again using the
00083 // <src>operator()</src>, numeric value(s) into a numeric value. Since they are
00084 // numeric, the <src>Domain</src> and <src>Range</src> base type can be of type
00085 // <src>AutoDiff<T></src> (where <src>T</src> is numeric base type) or one
00086 // of its derivations, in which case the value and its derivatives will be
00087 // calculated.
00088 // 
00089 // <note role=warning> In the current version the <src>Domain</src> and 
00090 // <src>Range</src> are the same for Functions </note>
00091 //
00092 // The basic classes are:
00093 // <dl>
00094 // <dt> <linkto class=Functional><src>Functional<Domain, Range></src></linkto>
00095 // <dd>
00096 // A base class that maps a <src>Domain</src> object into a <src>Range</src>
00097 // object using the <src>Range operator(const Domain &)</src>. All
00098 // information necessary to convert the <src>Domain</src> into a
00099 // <src>Range</src> will be available in the class
00100 // or in the input information. No variable class state (<em>parameters</em>)
00101 // are available.
00102 // 
00103 // <dt> <linkto class=FunctionParam><src>FunctionParam<T></src></linkto>
00104 // <dd> A helper base class that acts as a container for <em>parameters</em>
00105 // (<em>state</em>) used in <src>Function</src> classes. The class contains
00106 // a list of parameters, and a list of flags associated with the parameters.
00107 // Methods to set and obtain the parameters (using <src>operator[]</src>)
00108 // and their flags (using methods <src>mask()</src>) are available. The flags
00109 // can e.g. be used to indicate to <src>Fitting</src> routines if a certain
00110 // parameter has to be updated ('fitted') or not.
00111 // <note role=tip>
00112 // The FunctionParam class does not assume anything about the uses of the
00113 // class, but leaves that to the final users. This means that a lot of
00114 // copying between intermediate and final users is not necessary
00115 // (like between a Gaussian fitter with fixed parameters
00116 // and the Fitting routines: the Gaussian fitter just sets a flag to False, and
00117 // let the Fitting worry about what to do internally).
00118 // </note>
00119 // 
00120 // <dt> <linkto class=Function><src>Function<T></src></linkto>
00121 // <dd> Base class for function objects with zero or more parameters (i.e.
00122 // Functionals with state).
00123 // All parameters should be of the same type <em>T</em> as the <src>
00124 // Function<T></src>. <src>Function</src> objects are specifically geared
00125 // towards use in the <linkto module=Fitting>Fitting</linkto> classes, but
00126 // can be used anywhere where the value (and/or derivatives) of functions
00127 // are needed.
00128 //
00129 // The <src>Function<T></src> class is derived from <src>Functional</src>
00130 // and contains a <src>FunctionParam<T></src> object.
00131 // The parameters act as state for the function
00132 // (e.g. a width for a Gaussian). A function object is called using the
00133 // <src>T operator(const T&)</src> (<em>ndim=1</em>), or the
00134 // <src>T operator(const Vector<T>&)</src> (all values of <em>ndim</em>), or
00135 // <src>T operator(const T&, const T&)</src> (for <em>ndim=2</em> only).
00136 // If the template argument is <src>AutoDiff<T></src>, the parameters and the
00137 // returned value will be <src>AutoDiff<T></src>; the arguments of the
00138 // <src>operator()</src> will be of type <src>T</src>. The returned value
00139 // of the function will be the function value at <em>x</em> (and the
00140 // derivatives w.r.t. the non-masked parameters) Using <src>AutoDiffA<T></src>
00141 // the derivatives can be calculated w.r.t. parameters and/or arguments, see
00142 // <linkto class=AutoDiff>AutoDiff</linkto> and <linkto class=FunctionTraits>
00143 // FunctionTraits</linkto> for details. 
00144 // 
00145 // <note role=tip>
00146 // A <src>Function1D</src> is provided for 1-dimensional function objects
00147 // </note>
00148 // </dl>
00149 // 
00150 //  Actual functional classes:
00151 // <dl>
00152 // <dt> e.g. <linkto
00153 // class=Gaussian1D><src>Gaussian1D<T></src></linkto>
00154 // <dd> An actual function object will be derived from 
00155 // <src>Function<T></src>. The minimum functionality of a Function
00156 // object will be support for the <src>operator()</src> methods (through a
00157 // single, hidden, <src>eval()</src> method); for the manipulation of the
00158 // associated parameters (using <src>operator[index]</src> and
00159 // <src>mask(index)</src>) and some administrative aids (<src>ndim()</src>,
00160 // <src>nparameters()</src> and the like.
00161 //
00162 // In most cases it is advantageous to have a special parameter handling
00163 // class (e.g. <src>Gaussian1DParam</src>), to separate the (template
00164 // independent) parameter handling from the possible specialization of
00165 // the <src>eval()</src> method, and to more easily incorporate
00166 // special parameter handling (e.g. using <em>flux</em> rather than amplitude
00167 // of a Gaussian). All of this is transparent to the end-user.
00168 // </dl>
00169 // Combinatory Function objects are provided to easily combine and create
00170 // function objects:
00171 // <dl> 
00172 // <dt> <linkto class=CompoundFunction>CompoundFunction</linkto>
00173 // <dd> creates
00174 // a new, compound, function object from one or more other function objects
00175 // (including compounds...). The new function will have the sum of the 
00176 // parameters of the input functions as the new parameters (i.e the compound
00177 // function created from a 1-dimensional Gaussian (with 3 parameters) and a 
00178 // third-order polynomial (with 4 parameters) will have 7 parameters).
00179 // <dt> <linkto class=CombiFunction>CombiFunction</linkto> 
00180 // <dd> creates
00181 // a (linear) combination of a number of input functions. The number of
00182 // parameters of the newly created function will be equal to the number of
00183 // input functions (i.e. the combi 
00184 // function created from a 1-dimensional Gaussian (with 3 parameters) and a 
00185 // third-order polynomial (with 4 parameters) will have 2 parameters). The
00186 // function will be <src>param0*gauss(x) + param1*poly(x)</src>
00187 // <dt> <linkto class=FunctionWrapper>FunctionWrapper</linkto>
00188 // <dd> will take
00189 // a global function (or by the use of the <em>STL</em> function adapters
00190 // <src>mem_fun*</src> also member functions) of any dimension, and with
00191 // any number of parameters. The function is assumed to be called as
00192 // <src>f(x, p)</src>, and is wrapped like 
00193 // <src>FunctionWrapper(&func, param&, ndim)</src> (see example). 
00194 //   
00195 // </dl>
00196 //
00197 // </synopsis>
00198 
00199 // <example>
00200 // A function to find a bracketed root by bisection could be written
00201 // as follows:
00202 // <srcblock>
00203 //    template <class Domain, class Range> 
00204 //      Domain findRoot(const Functional<Domain,Range> &func, Domain left, 
00205 //                      Domain right, Domain tol) {
00206 //          Range fr = func(right);
00207 //          Range fl = func(left);
00208 //          Range sign = fr > 0 ? 1 : -1 ;
00209 //          AlwaysAssertExit(fl*fr < 0.0 && right > left);
00210 //          while (right - left > tol) {
00211 //              Domain mid = (left + right) / 2;
00212 //              Range fmid = func(mid);
00213 //              if (sign*fmid > 0.0) right = mid;
00214 //              else left = mid;
00215 //          };
00216 //          return (left + right)/2;
00217 //      }
00218 // </srcblock>
00219 // Since Function1D is derived from Functional, the
00220 // above function will also work with classes derived from Function1D. To
00221 // behave sensibly, the Domain and Range types should be real, <em>i.e.</em>,
00222 // Float or Double.
00223 //
00224 // To calculate the value of a polynomial
00225 // <srcblock>2 + 4x<sup>2</sup> + 6x<sup>4</sup></srcblock>
00226 // at <src>x=5.1</src>:
00227 // <srcblock>
00228 //      Polynomial<Double> pol(4);
00229 //      pol[0] = 2; pol[2] = 4; pol[4] = 6;
00230 //      cout << "Polynomial value at 5.1: " << pol(5.1) << endl;
00231 // </srcblock>
00232 //
00233 // Create a simple function (1-dimensional) with 2 parameters (A and B):
00234 // <srcblock>
00235 //      Double myf(const Double x, const Vector<Double> p) {
00236 //        return p[0]*sin(p[1]*x); }
00237 // </srcblock>
00238 // make it into a function object for initial parameters 2 and pi:
00239 // <srcblock>
00240 //      Vector<Double> p(2);
00241 //      p[0] = 2; p[1] = C::pi;
00242 //      FunctionWrapper<Double> f0(myf, p, 2);
00243 // </srcblock>
00244 // Make the first parameter 3:
00245 // <srcblock>
00246 //      f0[0] = 3;
00247 // </srcblock>
00248 // (for the global function you have to change <src>p[0]</src>).
00249 // Calculate the value of the function:
00250 // <srcblock>
00251 //      cout << "The value " << f0(3) << " should be 1.5 times the value " <<
00252 //        myf(3) << endl;
00253 // </srcblock>
00254 // A function object could be created as:
00255 // <srcblock>
00256 //      template<class T> class objf : public Function<T> {
00257 //       public:
00258 //         objf() : Function<T>(2) {};          // 2 parameters
00259 //         objf(const objf<T> &other) : Function<T>(other) {};
00260 //         virtual ~objf() {};
00261 //         // The actual method called for the evaluation operator():
00262 //         virtual T eval(typename Function<T>::FunctionArg x) const {
00263 //           return param_p[0] * sin(param_p[1] * x[0]); };
00264 //         // Return a copy of function (used for combination e.g.)
00265 //         virtual Function<T> *clone() const {
00266 //           return new objf<T>(*this); };
00267 //     };
00268 // </srcblock>
00269 // Which can be called as:
00270 // <srcblock>
00271 //      objf<Double> f1;
00272 //      f1[0] = 2; f1[1] = C::pi;
00273 //      cout << "The value " << myf(3) << " should be equal to the value " <<
00274 //        f1(3) << endl;
00275 // </srcblock>
00276 // </example>
00277 
00278 // <motivation>
00279 // The immediate motivations for this module were:
00280 // <ol>
00281 //    <li> To represent functions which are used in linear and non-linear least
00282 //         squares fitting
00283 // </ol>
00284 // </motivation>
00285 
00286 // <todo asof="2001/12/30">
00287 //   <li> It could be convenient to have a letter/envelope class, and to 
00288 //        define ``function arithmetic.''
00289 // </todo>
00290 
00291 // </module>
00292 
00293 
00294 } //# NAMESPACE CASACORE - END
00295 
00296 #endif
00297 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1