VavilovAccurate.h

Go to the documentation of this file.
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 */

Generated on Tue Jul 5 14:25:39 2011 for ROOT_528-00b_version by  doxygen 1.5.1