casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Gaussian3D.h
Go to the documentation of this file.
00001 //# Gaussian3D.h: A three-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: Gaussian3D.h 21024 2011-03-01 11:46:18Z gervandiepen $
00027 
00028 #ifndef SCIMATH_GAUSSIAN3D_H
00029 #define SCIMATH_GAUSSIAN3D_H
00030 
00031 #include <casa/aips.h>
00032 #include <scimath/Functionals/Gaussian3DParam.h>
00033 #include <scimath/Functionals/Function.h>
00034 #include <scimath/Mathematics/AutoDiff.h>
00035 #include <scimath/Mathematics/AutoDiffMath.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038   //# Forward Declarations.
00039   template<class T> class Vector;
00040 
00041 
00042 // <summary> A three dimensional Gaussian class.</summary>
00043 
00044 // <use visibility=export>
00045 
00046 // <reviewed reviewer="" date="" tests="tGaussian3D" 
00047 // demos="">
00048 // </reviewed>
00049 
00050 // <prerequisite>
00051 //   <li> <linkto class="Gaussian3DParam">Gaussian3DParam</linkto>
00052 //   <li> <linkto class="Function">Function</linkto>
00053 // </prerequisite>
00054 
00055 // <etymology> 
00056 // A Gaussian3D functional is designed exclusively for calculating a
00057 // Gaussian (or Normal) distribution in three dimensions. Other classes exist
00058 // for calculating these functions in one
00059 // (<linkto class=Gaussian1D>Gaussian1D</linkto>), two
00060 // (<linkto class=Gaussian2D>Gaussian2D</linkto>), and N
00061 // (<linkto class=GaussianND>GaussianND</linkto>) dimensions.
00062 // </etymology>
00063 
00064 // <synopsis> 
00065 // A <src>Gaussian3D</src> is described by a height, center, and width,
00066 // and position angles. Its fundamental operation is evaluating itself
00067 // at some <src>(x,y,z)</src>
00068 // coordinate. Its parameters (height, center and width, position angles) may
00069 // be changed at run time.
00070 
00071 // The width of the Gaussian is now specified in terms of the full width 
00072 // at half maximum (FWHM), like the 2D and 1D Gaussian functional classes.  
00073 
00074 // The three axis values refer to the x, y, and z axes, and unlike with the
00075 // 2D Gaussian any of the three axes may be the longest; instead, the position
00076 // angles are restricted.  The first position angle, theta, is the longitudinal
00077 // angle, referring to the rotation (counterclockwise) around the z-axis.  The
00078 // second, phi, is the latidudinal  angle, referring to the rotation around 
00079 // the theta-rotated y axis.  The domain of both angles is -pi/4 < A < pi/4,
00080 // although the angles are not constrained when fitting and can be set outside
00081 // the domain by setting the parameters directly using Functional operator[].
00082 // (Note that the use of theta and phi corresponds to the mathematics
00083 // convention for these angles, not the physics convention.)
00084 
00085 // The parameter interface (see 
00086 // <linkto class="Gaussian3DParam">Gaussian3DParam</linkto> class), 
00087 // is used to provide an interface to the
00088 // <linkto module="Fitting">Fitting</linkto> classes. 
00089 //
00090 // There are 9 parameters that are used to describe the Gaussian:
00091 // <ol>
00092 // <li> The height of the Gaussian. This is identical to the value
00093 //      returned using the <src> height </src> member function.
00094 // <li> The center of the Gaussian in the x direction. This is identical to
00095 //      the value returned using the <src> xCenter </src> member function.
00096 // <li> The center of the Gaussian in the y direction. This is identical to
00097 //      the value returned using the <src> yCenter </src> member function.
00098 // <li> The center of the Gaussian in the z direction. This is identical to
00099 //      the value returned using the <src> zCenter </src> member function.
00100 // <li> The width of the Gaussian along the x-axis.
00101 // <li> The width of the Gaussian along the y-axis.
00102 // <li> The width of the Gaussian along the z-axis.
00103 // <li> The longitudinal position angle, theta (in radians)
00104 // <li> The latitudinal position angle, phi (also in radians). 
00105 // </ol>
00106 
00107 // An enumeration for the parameter index is provided, enabling the setting
00108 // and reading of parameters with the <src>[]</src> operator. The 
00109 // <src>mask()</src> methods can be used to check and set the parameter masks.
00110 //
00111 // </synopsis>
00112 
00113 // <example>
00114 // <srcblock>
00115 // Gaussian3D<Double> g(9.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0);
00116 // Vector<Double> x(3);
00117 // x(0) = 1.0; x(1) = 0.5; x(2) = 0.0
00118 // cout << "g(" << x(0) << "," << x(1) << "," << x(2) << ")=" << g(x) << endl;
00119 // </srcblock>
00120 // </example>
00121 
00122 // <motivation>
00123 // The GaussianND class does not contain explicit derivatives
00124 // and was insufficient for fitting 3D Gaussians to data.
00125 // </motivation>
00126 
00127 // <templating arg=T>
00128 //  <li> T should have standard numerical operators and exp() function. Current
00129 //      implementation only tested for real types.
00130 //  <li> To obtain derivatives, the derivatives should be defined.
00131 // </templating>
00132 
00133 // <thrown>
00134 //  <li> Assertion in debug mode if attempt is made to set a negative width
00135 //  <li> AipsError if incorrect parameter number specified.
00136 //  <li> Assertion in debug mode if operator(Vector<>) with empty Vector
00137 // </thrown>
00138 
00139 // <todo asof="2002/07/22">
00140 //   <li> Optimize derivative calculations for faster fitting?
00141 // </todo>
00142 
00143 
00144 
00145 template<class T> class Gaussian3D : public Gaussian3DParam<T>
00146 {
00147 public:
00148   // A functional for a rotated, 3D Gaussian. Similar to Gaussian2D, but
00149   // the xWidth, yWidth, and zWidth parameters are not adjusted for FWHM;
00150   // they are identical to the parameters used in the function.
00151 
00152   // Constructs the three-dimensional Gaussians.  Defaults:
00153   // height = 1, center = {0,0,0}, width = {1,1,1}, theta = phi = 0.
00154   // The center and width vectors must have three elements.
00155   // <group>
00156   Gaussian3D();
00157   Gaussian3D(T height, const Vector<T>& center, 
00158              const Vector<T>& width, T theta, T phi);
00159   Gaussian3D(T &height, T &xCenter, T &yCenter, T &zCenter,
00160              T &xWidth, T &yWidth, T &zWidth, T &theta, T &phi);
00161   // </group>
00162 
00163   // Copy constructor
00164   // <group>
00165   Gaussian3D(const Gaussian3D<T> &other);
00166   template <class W>
00167     Gaussian3D(const Gaussian3D<W> &other) : Gaussian3DParam<T>(other) {}
00168   // </group>
00169 
00170   // Destructor
00171   virtual ~Gaussian3D();
00172 
00173   // Assignment operator
00174   Gaussian3D<T> &operator=(const Gaussian3D<T> &other);
00175 
00176   // Evaluate the Gaussian at <src>x</src>.
00177   virtual T eval(typename Function<T>::FunctionArg x) const;
00178 
00179   // Return a copy of this object from the heap.  The caller is responsible
00180   // for deleting this pointer.
00181   // <group>
00182   virtual Function<T> *clone() const;
00183   virtual Function<typename FunctionTraits<T>::DiffType> *cloneAD() const {
00184     return new Gaussian3D<typename FunctionTraits<T>::DiffType>(*this); }
00185   virtual Function<typename FunctionTraits<T>::BaseType> *cloneNonAD() const {
00186     return new Gaussian3D<typename FunctionTraits<T>::BaseType>(*this); }
00187   // </group>
00188 
00189 private:
00190   // AutoDiff does not have a square() function, so one is provided here.
00191   T sq(T v) const;
00192 
00193   //# Make members of parent classes known.
00194 protected:
00195   using Gaussian3DParam<T>::param_p;
00196   using Gaussian3DParam<T>::stoT_p;
00197   using Gaussian3DParam<T>::stoP_p;
00198   using Gaussian3DParam<T>::cosT_p;
00199   using Gaussian3DParam<T>::cosP_p;
00200   using Gaussian3DParam<T>::sinT_p;
00201   using Gaussian3DParam<T>::sinP_p;
00202   using Gaussian3DParam<T>::cosTcosP_p;
00203   using Gaussian3DParam<T>::cosTsinP_p;
00204   using Gaussian3DParam<T>::sinTcosP_p;
00205   using Gaussian3DParam<T>::sinTsinP_p;
00206 public:
00207   using Gaussian3DParam<T>::H;
00208   using Gaussian3DParam<T>::CX;
00209   using Gaussian3DParam<T>::CY;
00210   using Gaussian3DParam<T>::CZ;
00211   using Gaussian3DParam<T>::AX;
00212   using Gaussian3DParam<T>::AY;
00213   using Gaussian3DParam<T>::AZ;
00214   using Gaussian3DParam<T>::THETA;
00215   using Gaussian3DParam<T>::PHI;
00216   using Gaussian3DParam<T>::fwhm2int;
00217   using Gaussian3DParam<T>::settrigvals;
00218 };
00219 
00220 
00221 // AUTODIFF SPECIALIZATION
00222 
00223 #define Gaussian3D_PS Gaussian3D  
00224 
00225 // <summary> Partial specialization of Gaussian3D for <src>AutoDiff</src>
00226 // </summary>
00227 
00228 // <synopsis>
00229 // <note role=warning> The name <src>Gaussian3D_PS</src> is only for cxx2html
00230 // documentation problems. Use <src>Gaussian3D</src> in your code.</note>
00231 // </synopsis>
00232 
00233 
00234 template <class T> class Gaussian3D_PS<AutoDiff<T> > : public Gaussian3DParam<AutoDiff<T> > 
00235 {
00236 public:
00237   Gaussian3D_PS();
00238   Gaussian3D_PS(const AutoDiff<T> &height, 
00239                 const Vector<AutoDiff<T> >& center, 
00240                 const Vector<AutoDiff<T> >& width, 
00241                 const AutoDiff<T>& theta,   
00242                 const AutoDiff<T>& phi);
00243   Gaussian3D_PS(AutoDiff<T>& height,  AutoDiff<T>& xCenter,
00244                 AutoDiff<T>& yCenter, AutoDiff<T>& zCenter,
00245                 AutoDiff<T>& xWidth,  AutoDiff<T>& yWidth,
00246                 AutoDiff<T>& zWidth,  AutoDiff<T>& theta,
00247                 AutoDiff<T>& phi);
00248   Gaussian3D_PS(const Gaussian3D_PS<AutoDiff<T> > &other);
00249   template <class W>
00250   Gaussian3D_PS(const Gaussian3D_PS<W> &other) :
00251     Gaussian3DParam<AutoDiff<T> >(other) {}
00252    virtual ~Gaussian3D_PS();
00253 //
00254   Gaussian3D_PS<AutoDiff<T> > &operator=(const Gaussian3D_PS<AutoDiff<T> > &other);
00255 //
00256   virtual AutoDiff<T> eval(typename Function<AutoDiff<T> >::FunctionArg x) const;
00257   virtual Function<AutoDiff<T> > *clone() const;
00258   virtual Function<typename FunctionTraits<AutoDiff<T> >::DiffType>
00259     *cloneAD() const {
00260     return new Gaussian3D<typename FunctionTraits<AutoDiff<T> >::DiffType>
00261       (*this); }
00262   virtual Function<typename FunctionTraits<AutoDiff<T> >::BaseType>
00263     *cloneNonAD() const {
00264     return new Gaussian3D<typename FunctionTraits<AutoDiff<T> >::BaseType>
00265       (*this); }
00266 
00267 private:
00268   T sq(T v) const;  
00269 
00270   //# Make members of parent classes known.
00271 protected:
00272   using Gaussian3DParam<AutoDiff<T> >::param_p;
00273   using Gaussian3DParam<AutoDiff<T> >::stoT_p;
00274   using Gaussian3DParam<AutoDiff<T> >::stoP_p;
00275   using Gaussian3DParam<AutoDiff<T> >::cosT_p;
00276   using Gaussian3DParam<AutoDiff<T> >::cosP_p;
00277   using Gaussian3DParam<AutoDiff<T> >::sinT_p;
00278   using Gaussian3DParam<AutoDiff<T> >::sinP_p;
00279   using Gaussian3DParam<AutoDiff<T> >::cosTcosP_p;
00280   using Gaussian3DParam<AutoDiff<T> >::cosTsinP_p;
00281   using Gaussian3DParam<AutoDiff<T> >::sinTcosP_p;
00282   using Gaussian3DParam<AutoDiff<T> >::sinTsinP_p;
00283 public:
00284   using Gaussian3DParam<AutoDiff<T> >::H;
00285   using Gaussian3DParam<AutoDiff<T> >::CX;
00286   using Gaussian3DParam<AutoDiff<T> >::CY;
00287   using Gaussian3DParam<AutoDiff<T> >::CZ;
00288   using Gaussian3DParam<AutoDiff<T> >::AX;
00289   using Gaussian3DParam<AutoDiff<T> >::AY;
00290   using Gaussian3DParam<AutoDiff<T> >::AZ;
00291   using Gaussian3DParam<AutoDiff<T> >::THETA;
00292   using Gaussian3DParam<AutoDiff<T> >::PHI;
00293   using Gaussian3DParam<AutoDiff<T> >::fwhm2int;
00294   using Gaussian3DParam<AutoDiff<T> >::settrigvals;
00295 };
00296 
00297 #undef Gaussian3D_PS
00298 
00299 
00300 } //# NAMESPACE CASA - END
00301 
00302 #ifndef CASACORE_NO_AUTO_TEMPLATES
00303 #include <scimath/Functionals/Gaussian3D.tcc>
00304 #include <scimath/Functionals/Gaussian3D2.tcc>
00305 #endif //# CASACORE_NO_AUTO_TEMPLATES
00306 #endif
00307 
00308 
00309 
00310 
00311