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