00001 //# Lorentzian1D.h: A one-dimensional Lorentzian 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$ 00027 00028 #ifndef SCIMATH_LORENTZIAN1D_H 00029 #define SCIMATH_LORENTZIAN1D_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/scimath/Functionals/Lorentzian1DParam.h> 00034 #include <casacore/scimath/Functionals/Function1D.h> 00035 #include <casacore/scimath/Mathematics/AutoDiff.h> 00036 #include <casacore/scimath/Mathematics/AutoDiffMath.h> 00037 00038 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00039 00040 //# Forward declarations 00041 00042 // <summary> A one dimensional Lorentzian class.</summary> 00043 00044 // <use visibility=export> 00045 00046 // <reviewed reviewer="tcornwel" date="1996/02/22" tests="tLorentzian1D" 00047 // demos=""> 00048 // </reviewed> 00049 00050 // <prerequisite> 00051 // <li> <linkto class="Lorentzian1DParam">Lorentzian1DParam</linkto> 00052 // <li> <linkto class="Function">Function</linkto> 00053 // </prerequisite> 00054 00055 // <etymology> 00056 // A Lorentzian1D functional is designed exclusively for calculating a 00057 // Lorentzian (or Normal) distribution in one dimension. 00058 //# Other classes exist (not yet!) 00059 //# for calculating these functions in two 00060 //# (<linkto class=Lorentzian2D>Lorentzian2D</linkto>) and N 00061 //# (<linkto class=LorentzianND>LorentzianND</linkto>) dimensions. 00062 // </etymology> 00063 00064 // <synopsis> 00065 // A <src>Lorentzian1D</src> is described by a height, center, and width. Its 00066 // fundamental operation is evaluating itself at some <src>x</src>. 00067 // The parameters (height, center and width) may be changed at run time. 00068 // 00069 // The width of the Lorentzian (for the constructors or the <src>setWidth 00070 // </src> function) is always specified in terms of the full width at half 00071 // maximum (FWHM). It is always positive and attempts to set a non-positive 00072 // width will throw an assertion when in debug mode. 00073 // 00074 // The peak height of the Lorentzian can be specified at construction time or 00075 // by using the <src> setHeight </src> function. Alternatively the <src> 00076 // setFlux </src> function can be used to implicitly set the peak height by 00077 // specifying the integrated area under the Lorentzian. The height (or flux) 00078 // can be positive, negative or zero, as this class makes no assumptions on 00079 // what quantity the height represents. 00080 // 00081 // <note role=tip> Changing the width of the Lorentzian will not affect 00082 // its peak height but will change its flux. So you should always set the 00083 // width before setting the flux. </note> 00084 // 00085 // The parameter interface (see 00086 // <linkto class="Lorentzian1DParam">Lorentzian1DParam</linkto> class), 00087 // is used to provide an interface to the 00088 // <linkto module="Fitting">Fitting</linkto> classes. 00089 // 00090 // There are 3 parameters that are used to describe the Lorentzian: 00091 // <ol> 00092 // <li> The height of the Lorentzian. This is identical to the value 00093 // returned using the <src>height()</src> member function. 00094 // <li> The center of the Lorentzian in the x direction. This is identical to 00095 // the value returned using the <src>center()</src> member function. 00096 // <li> The width (FWHM) of the Lorentzian. To aid convergence of 00097 // the non-linear fitting routines this parameter is allowed to be 00098 // negative. This does not affect the shape of the Lorentzian as the 00099 // square of the width is used when evaluating the function. 00100 // </ol> 00101 // 00102 // An enumeration for the <src>HEIGHT</src>, <src>WIDTH</src> and 00103 // <src>CENTER</src> parameter index is provided, enabling the setting 00104 // and reading of parameters with the <src>[]</src> operator. The 00105 // <src>mask()</src> methods can be used to check and set the parameter masks. 00106 // 00107 // </synopsis> 00108 00109 // <example> 00110 // <srcblock> 00111 // Lorentzian<Double> gf(5.0, 25.0, 7); 00112 // gf(25); // = 5.0 00113 // gf[HEIGHT](1.0); 00114 // gf.setWidth(2.0); 00115 // gf[CENTER](0.0); 00116 // gf(1); // = 0.5*height = 0.5 00117 // </srcblock> 00118 // </example> 00119 00120 // <templating arg=T> 00121 // <li> T should have standard numerical operators and exp() function. Current 00122 // implementation only tested for real types. 00123 // <li> To obtain derivatives, the derivatives should be defined. 00124 // </templating> 00125 00126 // <thrown> 00127 // <li> Assertion in debug mode if attempt is made to set a negative width 00128 // <li> AipsError if incorrect parameter number specified. 00129 // <li> Assertion in debug mode if operator(Vector<>) with empty Vector 00130 // </thrown> 00131 00132 // <todo asof="2001/08/19"> 00133 // <li> Lorentzians that know about their DFT's could be required eventually. 00134 // </todo> 00135 00136 template<class T> class Lorentzian1D : public Lorentzian1DParam<T> { 00137 public: 00138 //# Enumerations 00139 00140 //# Constructors 00141 // Constructs the one dimensional Lorentzians. Defaults: 00142 // height=1, center=0, width(FWHM)=1. 00143 // <note role=warning> Could not use default arguments 00144 // that worked both with gcc and IRIX </note> 00145 // <group> 00146 Lorentzian1D() : Lorentzian1DParam<T>() {}; 00147 explicit Lorentzian1D(const T &height) : Lorentzian1DParam<T>(height) {}; 00148 Lorentzian1D(const T &height, const T ¢er) : 00149 Lorentzian1DParam<T>(height, center) {}; 00150 Lorentzian1D(const T &height, const T ¢er, const T &width) : 00151 Lorentzian1DParam<T>(height, center, width) {}; 00152 // </group> 00153 00154 // Copy constructor (deep copy) 00155 // <group> 00156 Lorentzian1D(const Lorentzian1D<T> &other) : Lorentzian1DParam<T>(other) {}; 00157 template <class W> 00158 Lorentzian1D(const Lorentzian1D<W> &other) : Lorentzian1DParam<T>(other) {} 00159 // </group> 00160 00161 // Copy assignment (deep copy) 00162 Lorentzian1D<T> &operator=(const Lorentzian1D<T> &other) { 00163 Lorentzian1DParam<T>::operator=(other); return *this; }; 00164 00165 // Destructor 00166 virtual ~Lorentzian1D() {}; 00167 00168 //# Operators 00169 // Evaluate the Lorentzian at <src>x</src>. 00170 // <group> 00171 virtual T eval(typename Function1D<T>::FunctionArg x) const; 00172 // </group> 00173 00174 //# Member functions 00175 // Return a copy of this object from the heap. The caller is responsible 00176 // for deleting this pointer. 00177 // <group> 00178 virtual Function<T> *clone() const { return new Lorentzian1D<T>(*this); }; 00179 virtual Function<typename FunctionTraits<T>::DiffType> *cloneAD() const { 00180 return new Lorentzian1D<typename FunctionTraits<T>::DiffType>(*this); }; 00181 virtual Function<typename FunctionTraits<T>::BaseType> *cloneNonAD() const { 00182 return new Lorentzian1D<typename FunctionTraits<T>::BaseType>(*this); }; 00183 // </group> 00184 00185 //# Make members of parent classes known. 00186 protected: 00187 using Lorentzian1DParam<T>::param_p; 00188 public: 00189 using Lorentzian1DParam<T>::HEIGHT; 00190 using Lorentzian1DParam<T>::CENTER; 00191 using Lorentzian1DParam<T>::WIDTH; 00192 using Lorentzian1DParam<T>::fwhm2int; 00193 }; 00194 00195 00196 #define Lorentzian1D_PS Lorentzian1D 00197 00198 // <summary> Partial specialization of Lorentzian1D for <src>AutoDiff</src> 00199 // </summary> 00200 00201 // <synopsis> 00202 // <note role=warning> The name <src>Lorentzian1D_PS</src> is only for cxx2html 00203 // documentation problems. Use <src>Lorentzian1D</src> in your code.</note> 00204 // </synopsis> 00205 00206 template <class T> class Lorentzian1D_PS<AutoDiff<T> > : 00207 public Lorentzian1DParam<AutoDiff<T> > 00208 { 00209 public: 00210 //# Constructors 00211 // Constructs one dimensional Lorentzians. 00212 // <group> 00213 Lorentzian1D_PS() : Lorentzian1DParam<AutoDiff<T> >() {}; 00214 explicit Lorentzian1D_PS(const AutoDiff<T> &height) : 00215 Lorentzian1DParam<AutoDiff<T> >(height) {}; 00216 Lorentzian1D_PS(const AutoDiff<T> &height, const AutoDiff<T> ¢er) : 00217 Lorentzian1DParam<AutoDiff<T> >(height, center) {}; 00218 Lorentzian1D_PS(const AutoDiff<T> &height, const AutoDiff<T> ¢er, 00219 const AutoDiff<T> &width) : 00220 Lorentzian1DParam<AutoDiff<T> >(height, center, width) {}; 00221 // </group> 00222 00223 // Copy constructor (deep copy) 00224 // <group> 00225 Lorentzian1D_PS(const Lorentzian1D_PS &other) : 00226 Lorentzian1DParam<AutoDiff<T> >(other) {}; 00227 template <class W> 00228 Lorentzian1D_PS(const Lorentzian1D_PS<W> &other) : 00229 Lorentzian1DParam<AutoDiff<T> >(other) {} 00230 // </group> 00231 00232 // Copy assignment (deep copy) 00233 Lorentzian1D_PS<AutoDiff<T> > & 00234 operator=(const Lorentzian1D_PS<AutoDiff<T> > &other) { 00235 Lorentzian1DParam<AutoDiff<T> >::operator=(other); return *this; }; 00236 00237 // Destructor 00238 virtual ~Lorentzian1D_PS() {}; 00239 00240 //# Operators 00241 // Evaluate the Lorentzian and its derivatives at <src>x</src>. 00242 // <group> 00243 virtual AutoDiff<T> eval(typename Function<AutoDiff<T> >::FunctionArg x) const; 00244 // </group> 00245 00246 //# Member functions 00247 // Return a copy of this object from the heap. The caller is responsible 00248 // for deleting this pointer. 00249 // <group> 00250 virtual Function<AutoDiff<T> > *clone() const { 00251 return new Lorentzian1D<AutoDiff<T> >(*this); }; 00252 virtual Function<typename FunctionTraits<AutoDiff<T> >::DiffType> 00253 *cloneAD() const { 00254 return new Lorentzian1D<typename FunctionTraits<AutoDiff<T> >::DiffType> 00255 (*this); }; 00256 virtual Function<typename FunctionTraits<AutoDiff<T> >::BaseType> 00257 *cloneNonAD() const { 00258 return new Lorentzian1D<typename FunctionTraits<AutoDiff<T> >::BaseType> 00259 (*this); }; 00260 // </group> 00261 00262 //# Make members of parent classes known. 00263 protected: 00264 using Lorentzian1DParam<AutoDiff<T> >::param_p; 00265 public: 00266 using Lorentzian1DParam<AutoDiff<T> >::HEIGHT; 00267 using Lorentzian1DParam<AutoDiff<T> >::CENTER; 00268 using Lorentzian1DParam<AutoDiff<T> >::WIDTH; 00269 using Lorentzian1DParam<AutoDiff<T> >::fwhm2int; 00270 }; 00271 00272 #undef Lorentzian1D_PS 00273 00274 00275 } //# NAMESPACE CASACORE - END 00276 00277 #ifndef CASACORE_NO_AUTO_TEMPLATES 00278 #include "Lorentzian1D.tcc" 00279 #include "Lorentzian1D2.tcc" 00280 #endif //# CASACORE_NO_AUTO_TEMPLATES 00281 #endif