00001 // @(#)root/mathmore:$Id: VavilovAccurate.h 34123 2010-06-25 08:21:13Z moneta $ 00002 // Authors: B. List 29.4.2010 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2004 ROOT Foundation, CERN/PH-SFT * 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU General Public License * 00010 * as published by the Free Software Foundation; either version 2 * 00011 * of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this library (see file COPYING); if not, write * 00020 * to the Free Software Foundation, Inc., 59 Temple Place, Suite * 00021 * 330, Boston, MA 02111-1307 USA, or contact the author. * 00022 * * 00023 **********************************************************************/ 00024 00025 // Header file for class VavilovAccurate 00026 // 00027 // Created by: blist at Thu Apr 29 11:19:00 2010 00028 // 00029 // Last update: Thu Apr 29 11:19:00 2010 00030 // 00031 #ifndef ROOT_Math_VavilovAccurate 00032 #define ROOT_Math_VavilovAccurate 00033 00034 00035 #include "Math/Vavilov.h" 00036 00037 namespace ROOT { 00038 namespace Math { 00039 00040 //____________________________________________________________________________ 00041 /** 00042 Class describing a Vavilov distribution. 00043 00044 The probability density function of the Vavilov distribution 00045 as function of Landau's parameter is given by: 00046 \f[ p(\lambda_L; \kappa, \beta^2) = 00047 \frac{1}{2 \pi i}\int_{c-i\infty}^{c+i\infty} \phi(s) e^{\lambda_L s} ds\f] 00048 where \f$\phi(s) = e^{C} e^{\psi(s)}\f$ 00049 with \f$ C = \kappa (1+\beta^2 \gamma )\f$ 00050 and \f$\psi(s)= s \ln \kappa + (s+\beta^2 \kappa) 00051 \cdot \left ( \int \limits_{0}^{1} 00052 \frac{1 - e^{\frac{-st}{\kappa}}}{t} \,d t- \gamma \right ) 00053 - \kappa \, e^{\frac{-s}{\kappa}}\f$. 00054 \f$ \gamma = 0.5772156649\dots\f$ is Euler's constant. 00055 00056 For the class VavilovAccurate, 00057 Pdf returns the Vavilov distribution as function of Landau's parameter 00058 \f$\lambda_L = \lambda_V/\kappa - \ln \kappa\f$, 00059 which is the convention used in the CERNLIB routines, and in the tables 00060 by S.M. Seltzer and M.J. Berger: Energy loss stragglin of protons and mesons: 00061 Tabulation of the Vavilov distribution, pp 187-203 00062 in: National Research Council (U.S.), Committee on Nuclear Science: 00063 Studies in penetration of charged particles in matter, 00064 Nat. Akad. Sci. Publication 1133, 00065 Nucl. Sci. Series Report No. 39, 00066 Washington (Nat. Akad. Sci.) 1964, 388 pp. 00067 Available from 00068 <A HREF="http://books.google.de/books?id=kmMrAAAAYAAJ&lpg=PP9&pg=PA187#v=onepage&q&f=false">Google books</A> 00069 00070 Therefore, for small values of \f$\kappa < 0.01\f$, 00071 pdf approaches the Landau distribution. 00072 00073 For values \f$\kappa > 10\f$, the Gauss approximation should be used 00074 with \f$\mu\f$ and \f$\sigma\f$ given by Vavilov::mean(kappa, beta2) 00075 and sqrt(Vavilov::variance(kappa, beta2). 00076 00077 The original Vavilov pdf is obtained by 00078 v.Pdf(lambdaV/kappa-log(kappa))/kappa. 00079 00080 For detailed description see 00081 B. Schorr, Programs for the Landau and the Vavilov distributions and the corresponding random numbers, 00082 <A HREF="http://dx.doi.org/10.1016/0010-4655(74)90091-5">Computer Phys. Comm. 7 (1974) 215-224</A>, 00083 which has been implemented in 00084 <A HREF="http://wwwasdoc.web.cern.ch/wwwasdoc/shortwrupsdir/g116/top.html"> 00085 CERNLIB (G116)</A>. 00086 00087 The class stores coefficients needed to calculate \f$p(\lambda; \kappa, \beta^2)\f$ 00088 for fixed values of \f$\kappa\f$ and \f$\beta^2\f$. 00089 Changing these values is computationally expensive. 00090 00091 The parameter \f$\kappa\f$ should be in the range \f$0.01 \le \kappa \le 10\f$. 00092 In contrast to the CERNLIB implementation, all values of \f$\kappa \ge 0.001\f$ may be used, 00093 but may result in slower running and/or inaccurate results. 00094 00095 The parameter \f$\beta^2\f$ must be in the range \f$0 \le \beta^2 \le 1\f$. 00096 00097 Two parameters which are fixed in the CERNLIB implementation may be set by the user: 00098 - epsilonPM corresponds to \f$\epsilon^+ = \epsilon^-\f$ in Eqs. (2.1) and (2.2) of Schorr's paper. 00099 epsilonPM gives an estimate on the integral of the cummulative distribution function 00100 outside the range \f$\lambda_{min} \le \lambda \le \lambda_{max}\f$ 00101 where the approximation is valid. 00102 Thus, it determines the support of the approximation used here (called $T_0 - T_1$ in the paper). 00103 Schorr recommends \f$\epsilon^+ = \epsilon^- = 5\cdot 10^{-4}\f$. 00104 The code from CERNLIB has been extended such that also smaller values are possible. 00105 00106 - epsilon corresponds to \f$\epsilon\f$ in Eq. (4.10) of Schorr's paper. 00107 It determines the accuracy of the series expansion. 00108 Schorr recommends \f$\epsilon = 10^{-5}\f$. 00109 00110 For the quantile calculation, the algorithm given by Schorr is not used, 00111 because it turns out to be very slow and still inaccurate. 00112 Instead, an initial estimate is calculated based on a precalculated table, 00113 which is subsequently improved by Newton iterations. 00114 00115 While the CERNLIB implementation calculates at most 156 terms in the series expansion 00116 for the pdf and cdf calculation, this class calculates up to 500 terms, depending 00117 on the values of epsilonPM and epsilon. 00118 00119 Average times on a Pentium Core2 Duo P8400 2.26GHz: 00120 - 38us per call to SetKappaBeta2 or constructor 00121 - 0.49us per call to Pdf, Cdf 00122 - 8.2us per first call to Quantile after SetKappaBeta2 or constructor 00123 - 0.83us per subsequent call to Quantile 00124 00125 Benno List, June 2010 00126 00127 @ingroup StatFunc 00128 */ 00129 00130 00131 class VavilovAccurate: public Vavilov { 00132 00133 public: 00134 00135 00136 /** 00137 Initialize an object to calculate the Vavilov distribution 00138 00139 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00140 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00141 @param epsilonPM: \f$\epsilon^+ = \epsilon^-\f$ in Eqs. (2.1) and (2.2) of Schorr's paper; gives an estimate on the integral of the cummulative distribution function 00142 outside the range \f$\lambda_{min} \le \lambda \le \lambda_{max}\f$ 00143 where the approximation is valid. 00144 @param epsilon: \f$\epsilon\f$ in Eq. (4.10) of Schorr's paper; determines the accuracy of the series expansion. 00145 */ 00146 00147 VavilovAccurate(double kappa=1, double beta2=1, double epsilonPM=5E-4, double epsilon=1E-5); 00148 00149 /** 00150 Destructor 00151 */ 00152 virtual ~VavilovAccurate(); 00153 00154 00155 public: 00156 00157 /** 00158 Evaluate the Vavilov probability density function 00159 00160 @param x The Landau parameter \f$x = \lambda_L\f$ 00161 */ 00162 double Pdf (double x) const; 00163 00164 /** 00165 Evaluate the Vavilov probability density function, 00166 and set kappa and beta2, if necessary 00167 00168 @param x The Landau parameter \f$x = \lambda_L\f$ 00169 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00170 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00171 */ 00172 double Pdf (double x, double kappa, double beta2); 00173 00174 /** 00175 Evaluate the Vavilov cummulative probability density function 00176 00177 @param x The Landau parameter \f$x = \lambda_L\f$ 00178 */ 00179 double Cdf (double x) const; 00180 00181 /** 00182 Evaluate the Vavilov cummulative probability density function, 00183 and set kappa and beta2, if necessary 00184 00185 @param x The Landau parameter \f$x = \lambda_L\f$ 00186 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00187 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00188 */ 00189 double Cdf (double x, double kappa, double beta2); 00190 00191 /** 00192 Evaluate the Vavilov complementary cummulative probability density function 00193 00194 @param x The Landau parameter \f$x = \lambda_L\f$ 00195 */ 00196 double Cdf_c (double x) const; 00197 00198 /** 00199 Evaluate the Vavilov complementary cummulative probability density function, 00200 and set kappa and beta2, if necessary 00201 00202 @param x The Landau parameter \f$x = \lambda_L\f$ 00203 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00204 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00205 */ 00206 double Cdf_c (double x, double kappa, double beta2); 00207 00208 /** 00209 Evaluate the inverse of the Vavilov cummulative probability density function 00210 00211 @param z The argument \f$z\f$, which must be in the range \f$0 \le z \le 1\f$ 00212 */ 00213 double Quantile (double z) const; 00214 00215 /** 00216 Evaluate the inverse of the Vavilov cummulative probability density function, 00217 and set kappa and beta2, if necessary 00218 00219 @param z The argument \f$z\f$, which must be in the range \f$0 \le z \le 1\f$ 00220 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00221 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00222 */ 00223 double Quantile (double z, double kappa, double beta2); 00224 00225 /** 00226 Evaluate the inverse of the complementary Vavilov cummulative probability density function 00227 00228 @param z The argument \f$z\f$, which must be in the range \f$0 \le z \le 1\f$ 00229 */ 00230 double Quantile_c (double z) const; 00231 00232 /** 00233 Evaluate the inverse of the complementary Vavilov cummulative probability density function, 00234 and set kappa and beta2, if necessary 00235 00236 @param z The argument \f$z\f$, which must be in the range \f$0 \le z \le 1\f$ 00237 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00238 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00239 */ 00240 double Quantile_c (double z, double kappa, double beta2); 00241 00242 /** 00243 Change \f$\kappa\f$ and \f$\beta^2\f$ and recalculate coefficients if necessary 00244 00245 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00246 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00247 */ 00248 virtual void SetKappaBeta2 (double kappa, double beta2); 00249 00250 00251 /** 00252 (Re)Initialize the object 00253 00254 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00255 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00256 @param epsilonPM \f$\epsilon^+ = \epsilon^-\f$ in Eqs. (2.1) and (2.2) of Schorr's paper; gives an estimate on the integral of the cummulative distribution function 00257 outside the range \f$\lambda_{min} \le \lambda \le \lambda_{max}\f$ 00258 where the approximation is valid. 00259 @param epsilon \f$\epsilon\f$ in Eq. (4.10) of Schorr's paper; determines the accuracy of the series expansion. 00260 */ 00261 void Set(double kappa, double beta2, double epsilonPM=5E-4, double epsilon=1E-5); 00262 00263 00264 /** 00265 Return the minimum value of \f$\lambda\f$ for which \f$p(\lambda; \kappa, \beta^2)\f$ 00266 is nonzero in the current approximation 00267 */ 00268 virtual double GetLambdaMin() const; 00269 00270 /** 00271 Return the maximum value of \f$\lambda\f$ for which \f$p(\lambda; \kappa, \beta^2)\f$ 00272 is nonzero in the current approximation 00273 */ 00274 virtual double GetLambdaMax() const; 00275 00276 /** 00277 Return the current value of \f$\kappa\f$ 00278 */ 00279 virtual double GetKappa() const; 00280 00281 /** 00282 Return the current value of \f$\beta^2\f$ 00283 */ 00284 virtual double GetBeta2() const; 00285 00286 /** 00287 Return the value of \f$\lambda\f$ where the pdf is maximal 00288 */ 00289 virtual double Mode() const; 00290 00291 /** 00292 Return the value of \f$\lambda\f$ where the pdf is maximal function, 00293 and set kappa and beta2, if necessary 00294 00295 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00296 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00297 */ 00298 virtual double Mode(double kappa, double beta2); 00299 00300 /** 00301 Return the current value of \f$\epsilon^+ = \epsilon^-\f$ 00302 */ 00303 00304 double GetEpsilonPM() const; 00305 00306 /** 00307 Return the current value of \f$\epsilon\f$ 00308 */ 00309 double GetEpsilon() const; 00310 00311 /** 00312 Return the number of terms used in the series expansion 00313 */ 00314 double GetNTerms() const; 00315 00316 /** 00317 Returns a static instance of class VavilovFast 00318 */ 00319 static VavilovAccurate *GetInstance(); 00320 00321 /** 00322 Returns a static instance of class VavilovFast, 00323 and sets the values of kappa and beta2 00324 00325 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00326 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00327 */ 00328 static VavilovAccurate *GetInstance(double kappa, double beta2); 00329 00330 00331 private: 00332 enum{MAXTERMS=500}; 00333 double fH[8], fT0, fT1, fT, fOmega, fA_pdf[MAXTERMS+1], fB_pdf[MAXTERMS+1], fA_cdf[MAXTERMS+1], fB_cdf[MAXTERMS+1], fX0; 00334 double fKappa, fBeta2; 00335 double fEpsilonPM, fEpsilon; 00336 00337 mutable bool fQuantileInit; 00338 mutable int fNQuant; 00339 enum{kNquantMax=32}; 00340 mutable double fQuant[kNquantMax]; 00341 mutable double fLambda[kNquantMax]; 00342 00343 void InitQuantile() const; 00344 00345 static VavilovAccurate *fgInstance; 00346 00347 double G116f1 (double x) const; 00348 double G116f2 (double x) const; 00349 00350 int Rzero (double a, double b, double& x0, 00351 double eps, int mxf, double (VavilovAccurate::*f)(double)const) const; 00352 static double E1plLog (double x); // Calculates log(|x|)+E_1(x) 00353 00354 }; 00355 00356 /** 00357 The Vavilov probability density function 00358 00359 @param x The Landau parameter \f$x = \lambda_L\f$ 00360 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00361 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00362 00363 @ingroup PdfFunc 00364 */ 00365 double vavilov_accurate_pdf (double x, double kappa, double beta2); 00366 00367 /** 00368 The Vavilov cummulative probability density function 00369 00370 @param x The Landau parameter \f$x = \lambda_L\f$ 00371 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00372 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00373 00374 @ingroup ProbFunc 00375 */ 00376 double vavilov_accurate_cdf (double x, double kappa, double beta2); 00377 00378 /** 00379 The Vavilov complementary cummulative probability density function 00380 00381 @param x The Landau parameter \f$x = \lambda_L\f$ 00382 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00383 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00384 00385 @ingroup ProbFunc 00386 */ 00387 double vavilov_accurate_cdf_c (double x, double kappa, double beta2); 00388 00389 /** 00390 The inverse of the Vavilov cummulative probability density function 00391 00392 @param z The argument \f$z\f$, which must be in the range \f$0 \le z \le 1\f$ 00393 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00394 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00395 00396 @ingroup QuantFunc 00397 */ 00398 double vavilov_accurate_quantile (double z, double kappa, double beta2); 00399 00400 /** 00401 The inverse of the complementary Vavilov cummulative probability density function 00402 00403 @param z The argument \f$z\f$, which must be in the range \f$0 \le z \le 1\f$ 00404 @param kappa The parameter \f$\kappa\f$, which must be in the range \f$\kappa \ge 0.001 \f$ 00405 @param beta2 The parameter \f$\beta^2\f$, which must be in the range \f$0 \le \beta^2 \le 1 \f$ 00406 00407 @ingroup QuantFunc 00408 */ 00409 double vavilov_accurate_quantile_c (double z, double kappa, double beta2); 00410 00411 } // namespace Math 00412 } // namespace ROOT 00413 00414 #endif /* ROOT_Math_VavilovAccurate */