casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
CompoundParam.h
Go to the documentation of this file.
00001 //# CompoundParam.h: Parameters for sum of parameterized Functions
00002 //# Copyright (C) 2001,2002,2005
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 //#
00027 //# $Id: CompoundParam.h 21024 2011-03-01 11:46:18Z gervandiepen $
00028 
00029 #ifndef SCIMATH_COMPOUNDPARAM_H
00030 #define SCIMATH_COMPOUNDPARAM_H
00031 
00032 #include <casa/aips.h>
00033 #include <scimath/Functionals/Function.h>
00034 #include <casa/BasicSL/String.h>
00035 #include <casa/Containers/Block.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038 
00039 // <summary> Parameters for sum of parameterized Functions
00040 // </summary>
00041 
00042 // <use visibility=local>
00043 
00044 // <reviewed reviewer="tcornwel" date="1996/02/22" tests="tCompoundFunction" 
00045 // demos="">
00046 // </reviewed>
00047 //
00048 // <prerequisite>
00049 //   <li> <linkto class="Function">Function</linkto>
00050 // </prerequisite>
00051 //
00052 // <synopsis>
00053 // This class takes an arbitrary number of Function objects, and generates
00054 // a new, single function object. The parameters of the compound object
00055 // are the union of all the parameters in the input objects.
00056 //
00057 // When CompoundFunction is evaluated, the result is the sum of 
00058 // all the individual function values.
00059 //
00060 // Note that any Function object (including another Compound object) can be
00061 // part of a compound object. 
00062 // </synopsis>
00063 //
00064 // <example>
00065 // Suppose for some reason we wanted the sum of <src>x^2</src> plus a gaussian.
00066 // We could form it as follows:
00067 // <srcblock>
00068 //    Polynomial<Float> x2(2);
00069 //    x[2] = 1.0;                                        // x^2
00070 //    Gaussian1D<Float> gauss(1.0, 0.0, 1.0);          // e^{-x^2}
00071 //    CompoundParam<Float> sum;                        // sum == 0.0
00072 //    sum.addFunction(x2);                               // sum == x^2
00073 //    sum.addFunction(gauss);                            // sum == x^2+e^{-x^2}
00074 //    sum(2.0);                                          // == 4 + e^-4
00075 //    CompoundParam[0] = 2.0;                          // sum ==2x^2+e^{-x^2}
00076 //    sum(2.0);                                          // == 8 + e^-4
00077 //    // Set the height of the gaussian
00078 //    sum[parameterOffset[1] + Gaussian1D<Float>::HEIGHT] = 2.5;
00079 // </srcblock>
00080 // </example>
00081 
00082 // <templating arg=T>
00083 //  <li> T should have standard numerical operators and exp() function. Current
00084 //      implementation only tested for real types.
00085 //  <li> To obtain derivatives, the derivatives should be defined.
00086 // </templating>
00087 
00088 // <thrown>
00089 // <li> AipsError if dimensions of functions added different
00090 // </thrown>
00091 
00092 // <motivation>
00093 // This class was created to allow a non-linear least squares fitter to fit a 
00094 // (potentially) arbitrary number of functions (typically gaussians).
00095 // </motivation>
00096 //
00097 // <todo asof="2001/10/22">
00098 //   <li> Nothing I know of
00099 // </todo>
00100 
00101 template<class T> class CompoundParam : public Function<T>
00102 {
00103 public:
00104   //# Constructors
00105   // The default constructor -- no functions, no parameters, nothing, the
00106   // function operator returns a 0.
00107   CompoundParam();
00108   // Make this object a (deep) copy of other.
00109   // <group>
00110   CompoundParam(const CompoundParam<T> &other);
00111   CompoundParam(const CompoundParam<T> &other, Bool) :
00112     Function<T>(other), ndim_p(other.ndim_p),
00113     functionPtr_p(other.functionPtr_p.nelements()),
00114     paroff_p(other.paroff_p.nelements()),
00115     funpar_p(other.funpar_p.nelements()), 
00116     locpar_p(other.locpar_p.nelements()) { 
00117     for (uInt i=0; i<functionPtr_p.nelements(); ++i) {
00118       functionPtr_p[i] = other.functionPtr_p[i]->clone();
00119       paroff_p[i] = other.paroff_p[i];
00120     }
00121     for (uInt i=0; i<funpar_p.nelements(); ++i) {
00122       funpar_p[i] = other.funpar_p[i];
00123       locpar_p[i] = other.locpar_p[i];
00124     }
00125   }
00126   template <class W>
00127     CompoundParam(const CompoundParam<W> &other) :
00128     Function<T>(other), ndim_p(other.ndim()),
00129     functionPtr_p(other.nFunctions()),
00130     paroff_p(other.nFunctions()),
00131     funpar_p(other.nparameters()), 
00132     locpar_p(other.nparameters()) { 
00133     for (uInt i=0; i<functionPtr_p.nelements(); ++i) {
00134       functionPtr_p[i] = other.function(i).cloneAD();
00135       paroff_p[i] = other.parameterOffset(i);
00136     }
00137     for (uInt i=0; i<funpar_p.nelements(); ++i) {
00138       funpar_p[i] = other.parameterFunction(i);
00139       locpar_p[i] = other.parameterLocation(i);
00140     }
00141   }
00142   template <class W>
00143     CompoundParam(const CompoundParam<W> &other, Bool) :
00144     Function<T>(other), ndim_p(other.ndim()),
00145     functionPtr_p(other.nFunctions()),
00146     paroff_p(other.nFunctions()),
00147     funpar_p(other.nparameters()), 
00148     locpar_p(other.nparameters()) { 
00149     for (uInt i=0; i<functionPtr_p.nelements(); ++i) {
00150       functionPtr_p[i] = other.function(i).cloneNonAD();
00151       paroff_p[i] = other.parameterOffset(i);
00152     }
00153     for (uInt i=0; i<funpar_p.nelements(); ++i) {
00154       funpar_p[i] = other.parameterFunction(i);
00155       locpar_p[i] = other.parameterLocation(i);
00156     }
00157   }
00158   CompoundParam<T> &operator=(const CompoundParam<T> &other);
00159   // </group>
00160   
00161   virtual ~CompoundParam();
00162 
00163   //# Operators
00164   
00165   //# Member functions
00166   // Give name of function
00167   virtual const String &name() const { static String x("compound");
00168     return x; }
00169   
00170   // Add a function to the sum. All functions must have the same 
00171   // <src>ndim()</src> as the first one. Returns the (zero relative) number 
00172   // of the function just added.
00173   uInt addFunction(const Function<T> &newFunction);
00174   
00175   // Return the number of functions in the sum.
00176   uInt nFunctions() const { return functionPtr_p.nelements(); }
00177   
00178   // Return a reference to a specific Function.
00179   // <group>
00180   const Function<T> &function(uInt which) const {
00181     DebugAssert(nFunctions() > which, AipsError);
00182     return *(functionPtr_p[which]); }
00183   // </group>
00184   // Get the offset in function parameterlist for function which
00185   uInt parameterOffset(uInt which) const {
00186     DebugAssert(nFunctions() > which, AipsError); return paroff_p[which]; }
00187   // Get the function number belonging to parameter list element which
00188   uInt parameterFunction(uInt which) const {
00189     DebugAssert(nparameters() > which, AipsError);
00190     return funpar_p[which];
00191   }
00192   // Return locpar
00193   uInt parameterLocation(uInt which) const {
00194     DebugAssert(nparameters() > which, AipsError);
00195     return locpar_p[which];
00196   }
00197   // Returns the dimension of functions in the linear combination
00198   virtual uInt ndim() const { return ndim_p; }
00199 
00200 private:
00201   //# Data
00202   // Number of dimensions of underlying functions
00203   uInt ndim_p;
00204 
00205 protected:
00206   //# Data
00207   // Pointer to each added function
00208   PtrBlock<Function<T> *> functionPtr_p;
00209   // Index of offset for each function to its parameters in general list
00210   Block<uInt> paroff_p;
00211   // Index of function belonging to parameter
00212   Block<uInt> funpar_p;
00213   // Index of local parameter
00214   Block<uInt> locpar_p;
00215 
00216   //# Make members of parent classes known.
00217 protected:
00218   using Function<T>::parset_p;
00219   using Function<T>::param_p;
00220 public:
00221   using Function<T>::nparameters;
00222 };
00223 
00224 
00225 } //# NAMESPACE CASA - END
00226 
00227 #ifndef CASACORE_NO_AUTO_TEMPLATES
00228 #include <scimath/Functionals/CompoundParam.tcc>
00229 #endif //# CASACORE_NO_AUTO_TEMPLATES
00230 #endif