casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Gaussian2D.h
Go to the documentation of this file.
00001 //# Gaussian2D.h: A two-dimensional Gaussian class
00002 //# Copyright (C) 1995,1996,1997,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 //# $Id: Gaussian2D.h 21024 2011-03-01 11:46:18Z gervandiepen $
00027 
00028 #ifndef SCIMATH_GAUSSIAN2D_H
00029 #define SCIMATH_GAUSSIAN2D_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <scimath/Functionals/Gaussian2DParam.h>
00034 #include <scimath/Functionals/Function.h>
00035 #include <scimath/Mathematics/AutoDiff.h>
00036 #include <scimath/Mathematics/AutoDiffMath.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 //# Forward declarations
00041 template<class T> class Vector;
00042 
00043 // <summary> A two dimensional Gaussian class.</summary>
00044 
00045 // <use visibility=export>
00046 
00047 // <reviewed reviewer="tcornwel" date="1996/02/22" tests="tGaussian2D" 
00048 // demos="">
00049 // </reviewed>
00050 
00051 // <prerequisite>
00052 //   <li> <linkto class="Gaussian2DParam">Gaussian2DParam</linkto>
00053 //   <li> <linkto class="Function">Function</linkto>
00054 // </prerequisite>
00055 
00056 // <etymology> 
00057 // A Gaussian2D functional is designed exclusively for calculating a
00058 // Gaussian (or Normal) distribution in two dimensions. Other classes exist
00059 // for calculating these functions in two
00060 // (<linkto class=Gaussian1D>Gaussian1D</linkto>) and N 
00061 // (<linkto class=GaussianND>GaussianND</linkto>) dimensions.
00062 // </etymology>
00063 
00064 // <synopsis> 
00065 // A <src>Gaussian2D</src> is described by a height, center, and width,
00066 // and position angle. Its fundamental operation is evaluating itself
00067 // at some <src>(x,y)</src>
00068 // coordinate. Its parameters (height, center and width, position angle) may
00069 // be changed at run time.
00070 //
00071 // The width of the Gaussian (for the constructors or the <src> setWidth
00072 // </src> function) is always specified in terms of the full width at half
00073 // maximum (FWHM). The major axis is parallel with the y axis when the
00074 // position angle is zero. The major axis will always have a larger width
00075 // than the minor axis. 
00076 //
00077 // It is not possible to set the width of the major axis (using the <src>
00078 // setMajorAxis </src> function) smaller than the width of the current minor
00079 // axis. Similarly it is not possible to set the width of the minor axis
00080 // (using the <src> setMinorAxis </src> function) to be larger than the
00081 // current major axis. Exceptions are thrown if these rules are violated or
00082 // if the either the major or minor axis is set to a non-positive width. To
00083 // set both axis in one hit use the <src> setWidth </src> function. All
00084 // these restrictions can be overcome when the parameters interface is used
00085 // (see below).
00086 //
00087 // The position angle is the angle between the y axis and the major axis and
00088 // is measured counterclockwise, so a position angle of 45 degrees rotates
00089 // the major axis to the line where y=-x. The position angle is always
00090 // specified and returned in radians. When using the <src> setPA </src>
00091 // function its value must be between -2pi and + 2pi, and the returned value
00092 // from the <src> pa </src> function will always be a value between 0 and
00093 // pi. 
00094 //
00095 // The axial ratio can be used as an alternative to specifying the width of
00096 // the minor axis. It is the ratio between the minor and major axis
00097 // widths. The axial ratio is constrained to be between zero and one, and
00098 // specifying something different (using setAxialRatio) will throw an
00099 // exception.
00100 //
00101 // The peak height of the Gaussian can be specified at construction time or
00102 // by using the <src> setHeight </src> function. Alternatively the <src>
00103 // setFlux </src> function can be used to implicitly set the peak height by
00104 // specifying the integrated area under the Gaussian. The height (or flux)
00105 // can be positive, negative or zero, as this class makes no assumptions on
00106 // what quantity the height represents. 
00107 //
00108 // <note role=tip> Changing the width of the Gaussian will not affect
00109 // its peak height but will change its flux. So you should always set the
00110 // width before setting the flux. </note>
00111 //
00112 // The parameter interface (see 
00113 // <linkto class="Gaussian2DParam">Gaussian2DParam</linkto> class), 
00114 // is used to provide an interface to the
00115 // <linkto module="Fitting">Fitting</linkto> classes. 
00116 //
00117 // There are 6 parameters that are used to describe the Gaussian:
00118 // <ol>
00119 // <li> The height of the Gaussian. This is identical to the value 
00120 //      returned using the <src> height </src> member function.
00121 // <li> The center of the Gaussian in the x direction. This is identical to
00122 //      the value returned using the <src> xCenter </src> member function. 
00123 // <li> The center of the Gaussian in the y direction. This is identical to
00124 //      the value returned using the <src> yCenter </src> member function. 
00125 // <li> The width (FWHM) of the Gaussian on one axis. Initially this will be
00126 //      the major axis, but if the parameters are adjusted by a Fitting
00127 //      class, it may become the axis with the smaller width. To aid
00128 //      convergence of the non-linear fitting routines this parameter is
00129 //      allowed to be negative. This does not affect the shape of the
00130 //      Gaussian as the squares of the widths are used when evaluating the
00131 //      function.
00132 // <li> A modified axial ratio. This parameter is the ratio of the width on
00133 //      the 'other' axis (which initially is the minor axis) and axis given
00134 //      by parameter YWIDTH. Because these internal widths are allowed to be
00135 //      negative and because there is no constraints on which axis is the
00136 //      larger one the modified axial ratio is not constrained to be between
00137 //      zero and one.
00138 // <li> The position angle. This represents the angle (in radians) between
00139 //      the axis used by parameter 4, and the y axis, measured
00140 //      counterclockwise. If parameter 4 represents the major axis width
00141 //      then this parameter will be identical to the position angle,
00142 //      otherwise it will be different by 90 degrees. The tight constraints
00143 //      on the value of the rotation angle enforced by the setPA() function
00144 //      are relaxed so that any value between -6000 and 6000 is allowed. It
00145 //      is still interpreted in radians. 
00146 // </ol>
00147 //
00148 // An enumeration for the parameter index is provided, enabling the setting
00149 // and reading of parameters with the <src>[]</src> operator. The 
00150 // <src>mask()</src> methods can be used to check and set the parameter masks.
00151 //
00152 // </synopsis>
00153 
00154 // <example>
00155 // <srcblock>
00156 //   Gaussian2D<Double> g(10.0, 0.0, 0.0, 2.0, 1.0, 0.0);
00157 //   Vector<Double> x(2);
00158 //   x(0) = 1.0; x(1) = 0.5;
00159 //   cout << "g(" << x(0) << "," << x(1) << ") = " << g(x) << endl;
00160 // </srcblock>
00161 // </example>
00162 
00163 // <templating arg=T>
00164 //  <li> T should have standard numerical operators and exp() function. Current
00165 //      implementation only tested for real types.
00166 //  <li> To obtain derivatives, the derivatives should be defined.
00167 // </templating>
00168 
00169 // <thrown>
00170 //    <li> Assertion in debug mode if attempt is made to set a negative width
00171 //    <li> AipsError if incorrect parameter number specified.
00172 //    <li> Assertion in debug mode if operator(Vector<>) with empty Vector
00173 // </thrown>
00174 
00175 // <todo asof="2001/08/19">
00176 //   <li> Gaussians that know about their DFT's could be required eventually.
00177 // </todo>
00178 
00179 template<class T> class Gaussian2D : public Gaussian2DParam<T>
00180 {
00181 public:
00182   //# Enumerations
00183   
00184   //# Constructors
00185   // Constructs the two dimensional Gaussians. Defaults:
00186   // height=1, center=0, width(FWHM)=1, PA=0. The center and width vectors
00187   // must have two elements  
00188   // <note role=warning> Could not use default arguments
00189   // that worked both with gcc and IRIX </note>
00190   // <group>
00191   Gaussian2D() : Gaussian2DParam<T>() {}
00192   Gaussian2D(const T &height, const Vector<T> &center, 
00193                const Vector<T> &width, const T &pa) :
00194     Gaussian2DParam<T>(height, center, width, pa) {}
00195   Gaussian2D(const T &height, const T &xCenter, const T &yCenter,
00196                const T &majorAxis, const T &axialRatio, const T &pa) :
00197     Gaussian2DParam<T>(height, xCenter, yCenter, majorAxis,
00198                        axialRatio, pa) {}
00199   // </group>
00200 
00201   // Copy constructor (deep copy)
00202   // <group>
00203   Gaussian2D(const Gaussian2D<T> &other) : Gaussian2DParam<T>(other) {}
00204   template <class W>
00205     Gaussian2D(const Gaussian2D<W> &other) : Gaussian2DParam<T>(other) {}
00206   // </group>
00207 
00208   // Copy assignment (deep copy)
00209   Gaussian2D<T> &operator=(const Gaussian2D<T> &other) {
00210     Gaussian2DParam<T>::operator=(other); return *this; }
00211     
00212   // Destructor
00213   virtual ~Gaussian2D() {}
00214 
00215   //# Operators  
00216   // Evaluate the Gaussian at <src>x</src>.
00217   // <group>
00218   virtual T eval(typename Function<T>::FunctionArg x) const;
00219   // </group>
00220 
00221   //# Member functions
00222   // Return a copy of this object from the heap. The caller is responsible 
00223   // for deleting this pointer.
00224   // <group>
00225   virtual Function<T> *clone() const { return new Gaussian2D<T>(*this); }
00226   virtual Function<typename FunctionTraits<T>::DiffType> *cloneAD() const {
00227     return new Gaussian2D<typename FunctionTraits<T>::DiffType>(*this); }
00228   virtual Function<typename FunctionTraits<T>::BaseType> *cloneNonAD() const {
00229     return new Gaussian2D<typename FunctionTraits<T>::BaseType>(*this); }
00230   // </group>
00231 
00232   //# Make members of parent classes known.
00233 protected:
00234   using Gaussian2DParam<T>::param_p;
00235   using Gaussian2DParam<T>::thePA;
00236   using Gaussian2DParam<T>::theCpa;
00237   using Gaussian2DParam<T>::theSpa;
00238   using Gaussian2DParam<T>::theXwidth;
00239 public:
00240   using Gaussian2DParam<T>::HEIGHT;
00241   using Gaussian2DParam<T>::XCENTER;
00242   using Gaussian2DParam<T>::YCENTER;
00243   using Gaussian2DParam<T>::YWIDTH;
00244   using Gaussian2DParam<T>::RATIO;
00245   using Gaussian2DParam<T>::PANGLE;
00246   using Gaussian2DParam<T>::fwhm2int;
00247 };
00248 
00249 #define Gaussian2D_PS Gaussian2D
00250 
00251 // <summary> Partial specialization of Gaussian2D for <src>AutoDiff</src>
00252 // </summary>
00253 
00254 // <synopsis>
00255 // <note role=warning> The name <src>Gaussian2D_PS</src> is only for cxx2html
00256 // documentation problems. Use <src>Gaussian2D</src> in your code.</note>
00257 // </synopsis>
00258 
00259 template <class T> class Gaussian2D_PS<AutoDiff<T> > : 
00260 public Gaussian2DParam<AutoDiff<T> >
00261 {
00262 public:
00263   //# Constructors
00264   // Constructs two dimensional Gaussians.
00265   // <group>
00266   Gaussian2D_PS() : Gaussian2DParam<AutoDiff<T> >() {}
00267   Gaussian2D_PS(const AutoDiff<T> &height,
00268                   const Vector<AutoDiff<T> > &center, 
00269                   const Vector<AutoDiff<T> > &width,
00270                   const AutoDiff<T> &pa) :
00271     Gaussian2DParam<AutoDiff<T> >(height, center, width, pa) {}
00272   Gaussian2D_PS(const AutoDiff<T> &height, const AutoDiff<T> &xCenter,
00273                   const AutoDiff<T> &yCenter, const AutoDiff<T> &majorAxis,
00274                   const AutoDiff<T> &axialRatio, const AutoDiff<T> &pa) :
00275     Gaussian2DParam<AutoDiff<T> >(height, xCenter, yCenter, majorAxis,
00276                        axialRatio, pa) {}
00277   // </group>
00278 
00279   // Copy constructor (deep copy)
00280   // <group>
00281   Gaussian2D_PS(const Gaussian2D_PS &other) :
00282     Gaussian2DParam<AutoDiff<T> >(other) {}
00283   template <class W>
00284   Gaussian2D_PS(const Gaussian2D_PS<W> &other) :
00285     Gaussian2DParam<AutoDiff<T> >(other) {}
00286   // </group>
00287 
00288   // Copy assignment (deep copy)
00289   Gaussian2D_PS<AutoDiff<T> > &
00290     operator=(const Gaussian2D_PS<AutoDiff<T> > &other) {
00291     Gaussian2DParam<AutoDiff<T> >::operator=(other); return *this; }
00292     
00293   // Destructor
00294   virtual ~Gaussian2D_PS() {}
00295 
00296   //# Operators    
00297   // Evaluate the Gaussian and its derivatives at <src>x</src>.
00298   // <group>
00299   virtual AutoDiff<T> eval(typename Function<AutoDiff<T> >::FunctionArg x) const;
00300   // </group>
00301 
00302   //# Member functions
00303   // Return a copy of this object from the heap. The caller is responsible 
00304   // for deleting this pointer.
00305   // <group>
00306   virtual Function<AutoDiff<T> > *clone() const {
00307     return new Gaussian2D<AutoDiff<T> >(*this); }
00308   virtual Function<typename FunctionTraits<AutoDiff<T> >::DiffType>
00309     *cloneAD() const {
00310     return new Gaussian2D<typename FunctionTraits<AutoDiff<T> >::DiffType>
00311       (*this); }
00312   virtual Function<typename FunctionTraits<AutoDiff<T> >::BaseType>
00313     *cloneNonAD() const {
00314     return new Gaussian2D<typename FunctionTraits<AutoDiff<T> >::BaseType>
00315       (*this); }
00316   // </group>
00317 
00318   //# Make members of parent classes known.
00319 protected:
00320   using Gaussian2DParam<AutoDiff<T> >::param_p;
00321   using Gaussian2DParam<AutoDiff<T> >::thePA;
00322   using Gaussian2DParam<AutoDiff<T> >::theCpa;
00323   using Gaussian2DParam<AutoDiff<T> >::theSpa;
00324   using Gaussian2DParam<AutoDiff<T> >::theXwidth;
00325 public:
00326   using Gaussian2DParam<AutoDiff<T> >::HEIGHT;
00327   using Gaussian2DParam<AutoDiff<T> >::XCENTER;
00328   using Gaussian2DParam<AutoDiff<T> >::YCENTER;
00329   using Gaussian2DParam<AutoDiff<T> >::YWIDTH;
00330   using Gaussian2DParam<AutoDiff<T> >::RATIO;
00331   using Gaussian2DParam<AutoDiff<T> >::PANGLE;
00332   using Gaussian2DParam<AutoDiff<T> >::fwhm2int;
00333 };
00334 
00335 #undef Gaussian2D_PS
00336 
00337 
00338 } //# NAMESPACE CASA - END
00339 
00340 #ifndef CASACORE_NO_AUTO_TEMPLATES
00341 #include <scimath/Functionals/Gaussian2D.tcc>
00342 #include <scimath/Functionals/Gaussian2D2.tcc>
00343 #endif //# CASACORE_NO_AUTO_TEMPLATES
00344 #endif