casa
$Rev:20696$
|
00001 //# GaussianND.h: A multidimensional Gaussian class 00002 //# Copyright (C) 1995,1996,1998,1999,2001,2002,2004,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: GaussianND.h 21024 2011-03-01 11:46:18Z gervandiepen $ 00027 00028 #ifndef SCIMATH_GAUSSIANND_H 00029 #define SCIMATH_GAUSSIANND_H 00030 00031 #include <casa/aips.h> 00032 #include <scimath/Functionals/GaussianNDParam.h> 00033 #include <scimath/Functionals/Function.h> 00034 00035 namespace casa { //# NAMESPACE CASA - BEGIN 00036 00037 //# Forward declarations 00038 00039 // <summary> A Multi-dimensional Gaussian functional. </summary> 00040 00041 // <use visibility=export> 00042 00043 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tGaussianND" demos="dGaussianND"> 00044 // </reviewed> 00045 00046 // <prerequisite> 00047 // <li> <linkto class="GaussianNDParam">GaussianNDParam</linkto> 00048 // <li> <linkto class="Function">Function</linkto> 00049 // </prerequisite> 00050 00051 // <synopsis> 00052 // A <src>GaussianND</src> is used to calculate Gaussian functions of any 00053 // dimension. A <linkto class=Gaussian1D> Gaussian1D </linkto> class exists 00054 // which is more appropriate for one dimensional Gaussian functions, and a 00055 // <linkto class=Gaussian2D> Gaussian2D </linkto> class exists for two 00056 // dimensional functions. 00057 // 00058 // A statistical description of the multi-dimensional Gaussian is used (see 00059 // Kendall & Stuart "The Advanced Theory of Statistics"). A Gaussian is 00060 // defined in terms of its height, mean (which is the location of the peak 00061 // value), variance, (a measure of the width of the Gaussian), and 00062 // covariance which skews the distribution with respect to the Axes. 00063 // 00064 // In the general description the variance and covariance are specified 00065 // using a covariance matrix. This is defined as (for a 4 dimensional 00066 // Gaussian): 00067 // <srcblock> 00068 // V = | s1*s1 r12*s1*s2 r13*s1*s3 r14*s1*s4 | 00069 // | r12*s1*s2 s2*s2 r23*s2*s3 r24*s2*s4 | 00070 // | r13*s1*s3 r23*s2*s3 s3*s3 r34*s3*s4 | 00071 // | r14*s1*s4 r24*s2*s4 r34*s3*s4 s4*s4 | 00072 // </srcblock> 00073 // where s1 (<src>sigma1</src>) is the standard deviation of the Gaussian with 00074 // respect to the first axis, and r12 (<src>rho12</src>) is the correlation 00075 // between the the first and second axis. The correlation MUST be between -1 00076 // and 1, and this class checks this as well as ensuring that the diagonal 00077 // is positive. 00078 // 00079 // <note role=warning> It is possible to have symmetric matrices that are of 00080 // the above described form (ie. symmetric with <src>-1 <= rho(ij) <=1</src>) 00081 // that do 00082 // not generate a Gaussian function. This is because the Matrix is NOT 00083 // positive definite (The limits on <src>rho(ij)</src> are upper limits). 00084 // This class 00085 // does check that the covariance Matrix is positive definite and will throw 00086 // an exception (AipsError) if it is not.</note> 00087 // 00088 // The covariance Matrix can be specified by only its upper or lower 00089 // triangular regions (ie. with zeros in the other triangle), otherwise it 00090 // MUST be symmetric. 00091 // 00092 // The Gaussian that is constructed from this covariance Matrix (V), along 00093 // with mean (u) and height (h) is: 00094 // <srcblock> 00095 // f(x) = h*exp( -1/2 * (x-u) * V^(-1) * (x-u)) 00096 // </srcblock> 00097 // where x, and u are vectors whose length is the dimensionality of the 00098 // Gaussian and V^(-1) is the inverse of the covariance Matrix defined 00099 // above. For a two dimensional Gaussian with zero mean this expression 00100 // reduces to: 00101 // <srcblock> 00102 // f(x) = h*exp(-1/(2*(1-r12^2))*(x1^2/s1^2 - 2*r12*x1*x2/(s1*s2) + x2^2/s2^2)) 00103 // </srcblock> 00104 // 00105 // The amplitude of the Gaussian can be defined in two ways, either using 00106 // the peak height (as is done in the constructors, and the setHeight 00107 // function) or using the setFlux function. The flux in this context is the 00108 // analytic integral of the Gaussian over all dimensions. Using the setFlux 00109 // function does not modify the shape of the Gaussian just its height. 00110 // 00111 // All the parameters of the Gaussian except its dimensionality can be 00112 // modified using the set/get functions. 00113 // 00114 // The parameter interface (see 00115 // <linkto class="FunctionParam">FunctionParam</linkto> class), 00116 // is used to provide an interface to the 00117 // <linkto module="Fitting"> Fitting </linkto> classes. 00118 // There are always 4 00119 // parameter sets. The parameters are, in order: 00120 // <ol> 00121 // <li> height (1 term). No assumptions on what quantity the height 00122 // represents, and it can be negative 00123 // <li> mean (ndim terms). 00124 // <li> variance (ndim terms). The variance is always positive, and an 00125 // exception (AipsError) will be thrown if you try to set a negative 00126 // value. 00127 // <li> covariance (ndim*(ndim-1)/2 terms) The order is (assuming ndim=5) 00128 // v12,v13,v14,v15,v23,v24,v25,v34,v35,v45. The restrictions described 00129 // above for the covariance (ie. -1 < r12 < +1) are enforced. 00130 // </ol> 00131 // </synopsis> 00132 00133 // <example> 00134 // Construct a two dimensional Gaussian with mean=(0,1), variance=(.1,7) and 00135 // height = 1; 00136 // <srcblock> 00137 // uInt ndim = 2; 00138 // Float height = 1; 00139 // Vector<Float> mean(ndim); mean(0) = 0, mean(1) = 1; 00140 // Vector<Float> variance(ndim); variance(0) = .1, variance(1) = 7; 00141 // GaussianND<Float> g(ndim, height, mean, variance); 00142 // Vector<Float> x(ndim); x = 0; 00143 // cout << "g("<< x <<") = " << g(x) <<endl; // g([0,0])=1*exp(-1/2*1/7); 00144 // x(1)++; 00145 // cout << "g("<< x <<") = " <<g(x) <<endl; // g([0,1])= 1 00146 // cout << "Height: " << g.height() <<endl; // Height: 1 00147 // cout << "Flux: " << g.flux() << endl; // Flux: 2*Pi*Sqrt(.1*7) 00148 // cout << "Mean: " << g.mean() << endl; // Mean: [0, -1] 00149 // cout << "Variance: " << g.variance() <<endl; // Variance: [.1, 7] 00150 // cout << "Covariance: "<< g.covariance()<<endl;// Covariance: [.1, 0] 00151 // // [0, 7] 00152 // g.setFlux(1); 00153 // cout << "g("<< x <<") = " <<g(x) <<endl; //g([0,1])=1/(2*Pi*Sqrt(.7)) 00154 // cout << "Height: " << g.height() <<endl; // Height: 1/(2*Pi*Sqrt(.7)) 00155 // cout << "Flux: " << g.flux() << endl; // Flux: 1 00156 // cout << "Mean: " << g.mean() << endl; // Mean: [0, -1] 00157 // cout << "Variance: " << g.variance() <<endl; // Variance: [.1, 7] 00158 // cout << "Covariance: "<< g.covariance()<<endl;// Covariance: [.1, 0] 00159 // // [0, 7] 00160 // </srcblock> 00161 // </example> 00162 00163 // <motivation> 00164 // A Gaussian Functional was needed for modeling the sky with a series of 00165 // components. It was later realised that it was too general and Gaussian2D 00166 // was written. 00167 // </motivation> 00168 00169 // <templating arg=T> 00170 // <li> T should have standard numerical operators and exp() function. Current 00171 // implementation only tested for real types. 00172 // </templating> 00173 00174 // <todo asof="2001/08/19"> 00175 // <li> Nothing I know off, apart from possible optimization 00176 // </todo> 00177 00178 template<class T> class GaussianND : public GaussianNDParam<T> 00179 { 00180 public: 00181 //# Constructors 00182 // Makes a Gaussian using the indicated height, mean, variance & 00183 // covariance. 00184 // ndim defaults to 2, 00185 // mean defaults to 0, 00186 // height to Pi^(-ndim/2) (the flux is unity) 00187 // variance defaults to 1.0, 00188 // covariance defaults to 0.0, 00189 // <group> 00190 GaussianND() : GaussianNDParam<T>() {} 00191 explicit GaussianND(uInt ndim) : 00192 GaussianNDParam<T>(ndim) {} 00193 GaussianND(uInt ndim, const T &height) : 00194 GaussianNDParam<T>(ndim, height) {} 00195 GaussianND(uInt ndim, const T &height, const Vector<T> &mean) : 00196 GaussianNDParam<T>(ndim, height, mean) {} 00197 GaussianND(uInt ndim, const T &height, const Vector<T> &mean, 00198 const Vector<T> &variance) : 00199 GaussianNDParam<T>(ndim, height, mean, variance) {} 00200 GaussianND(uInt ndim, const T &height, const Vector<T> &mean, 00201 const Matrix<T> &covar) : 00202 GaussianNDParam<T>(ndim, height, mean, covar) {} 00203 // </group> 00204 00205 // Copy constructor (deep copy) 00206 // <group> 00207 GaussianND(const GaussianND &other) : GaussianNDParam<T>(other) {} 00208 // </group> 00209 00210 // Copy assignment (deep copy) 00211 GaussianND<T> &operator=(const GaussianND<T> &other) { 00212 GaussianNDParam<T>::operator=(other); return *this; } 00213 00214 // Destructor 00215 virtual ~GaussianND() {} 00216 00217 //# Operators 00218 // Evaluate the Gaussian at <src>x</src>. 00219 // <group> 00220 virtual T eval(typename Function<T>::FunctionArg x) const; 00221 // </group> 00222 00223 //# Member functions 00224 // Return a copy of this object from the heap. The caller is responsible for 00225 // deleting this pointer. 00226 // <group> 00227 virtual Function<T> *clone() const { return new GaussianND<T>(*this); } 00228 // </group> 00229 00230 //# Make members of parent classes known. 00231 protected: 00232 using GaussianNDParam<T>::param_p; 00233 using GaussianNDParam<T>::itsDim; 00234 public: 00235 using GaussianNDParam<T>::HEIGHT; 00236 using GaussianNDParam<T>::CENTER; 00237 }; 00238 00239 00240 } //# NAMESPACE CASA - END 00241 00242 #ifndef CASACORE_NO_AUTO_TEMPLATES 00243 #include <scimath/Functionals/GaussianND.tcc> 00244 #endif //# CASACORE_NO_AUTO_TEMPLATES 00245 #endif