casa
$Rev:20696$
|
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> ¢er, 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> > ¢er, 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