RandStudentT.cc

Go to the documentation of this file.
00001 // $Id:$
00002 // -*- C++ -*-
00003 //
00004 // -----------------------------------------------------------------------
00005 //                             HEP Random
00006 //                          --- RandStudentT ---
00007 //                      class implementation file
00008 // -----------------------------------------------------------------------
00009 
00010 // =======================================================================
00011 // John Marraffino - Created: 12th May 1998
00012 // G.Cosmo         - Fixed minor bug on inline definition for shoot()
00013 //                   methods : 20th Aug 1998
00014 // M Fischler      - put and get to/from streams 12/13/04
00015 // M Fischler         - put/get to/from streams uses pairs of ulongs when
00016 //                      + storing doubles avoid problems with precision 
00017 //                      4/14/05
00018 // =======================================================================
00019 
00020 #include <float.h>
00021 #include <cmath>        // for std::log() std::exp()
00022 #include "CLHEP/Random/RandStudentT.h"
00023 #include "CLHEP/Random/DoubConv.h"
00024 
00025 namespace CLHEP {
00026 
00027 std::string RandStudentT::name() const {return "RandStudentT";}
00028 HepRandomEngine & RandStudentT::engine() {return *localEngine;}
00029 
00030 RandStudentT::~RandStudentT()
00031 {
00032 }
00033 
00034 double RandStudentT::operator()() {
00035   return fire( defaultA );
00036 }
00037 
00038 double RandStudentT::operator()( double a ) {
00039   return fire( a );
00040 }
00041 
00042 double RandStudentT::shoot( double a ) {
00043 /******************************************************************
00044  *                                                                *
00045  *           Student-t Distribution - Polar Method                *
00046  *                                                                *
00047  ******************************************************************
00048  *                                                                *
00049  * The polar method of Box/Muller for generating Normal variates  *
00050  * is adapted to the Student-t distribution. The two generated    *
00051  * variates are not independent and the expected no. of uniforms  *
00052  * per variate is 2.5464.                                         *
00053  *                                                                *
00054  ******************************************************************
00055  *                                                                *
00056  * FUNCTION :   - tpol  samples a random number from the          *
00057  *                Student-t distribution with parameter a > 0.    *
00058  * REFERENCE :  - R.W. Bailey (1994): Polar generation of random  *
00059  *                variates with the t-distribution, Mathematics   *
00060  *                of Computation 62, 779-781.                     *
00061  * SUBPROGRAM : -  ... (0,1)-Uniform generator                    *
00062  *                                                                *
00063  *                                                                *
00064  * Implemented by F. Niederl, 1994                                *
00065  ******************************************************************/
00066 
00067  double u,v,w;
00068 
00069 // Check for valid input value
00070 
00071  if( a < 0.0) return (DBL_MAX);
00072 
00073  do
00074  {
00075          u = 2.0 * HepRandom::getTheEngine()->flat() - 1.0;
00076          v = 2.0 * HepRandom::getTheEngine()->flat() - 1.0;
00077  }
00078  while ((w = u * u + v * v) > 1.0);
00079 
00080  return(u * std::sqrt( a * ( std::exp(- 2.0 / a * std::log(w)) - 1.0) / w));
00081 }
00082 
00083 void RandStudentT::shootArray( const int size, double* vect,
00084                             double a )
00085 {
00086   for( double* v = vect; v != vect + size; ++v )
00087     *v = shoot(a);
00088 }
00089 
00090 void RandStudentT::shootArray( HepRandomEngine* anEngine,
00091                             const int size, double* vect,
00092                             double a )
00093 {
00094   for( double* v = vect; v != vect + size; ++v )
00095     *v = shoot(anEngine,a);
00096 }
00097 
00098 double RandStudentT::fire( double a ) {
00099 
00100  double u,v,w;
00101 
00102  do
00103  {
00104          u = 2.0 * localEngine->flat() - 1.0;
00105          v = 2.0 * localEngine->flat() - 1.0;
00106  }
00107  while ((w = u * u + v * v) > 1.0);
00108 
00109  return(u * std::sqrt( a * ( std::exp(- 2.0 / a * std::log(w)) - 1.0) / w));
00110 }
00111 
00112 void RandStudentT::fireArray( const int size, double* vect)
00113 {
00114   for( double* v = vect; v != vect + size; ++v )
00115     *v = fire(defaultA);
00116 }
00117 
00118 void RandStudentT::fireArray( const int size, double* vect,
00119                            double a )
00120 {
00121   for( double* v = vect; v != vect + size; ++v )
00122     *v = fire(a);
00123 }
00124 
00125 double RandStudentT::shoot( HepRandomEngine *anEngine, double a ) {
00126 
00127  double u,v,w;
00128 
00129  do
00130  {
00131          u = 2.0 * anEngine->flat() - 1.0;
00132          v = 2.0 * anEngine->flat() - 1.0;
00133  }
00134  while ((w = u * u + v * v) > 1.0);
00135 
00136  return(u * std::sqrt( a * ( std::exp(- 2.0 / a * std::log(w)) - 1.0) / w));
00137 }
00138 
00139 std::ostream & RandStudentT::put ( std::ostream & os ) const {
00140   int pr=os.precision(20);
00141   std::vector<unsigned long> t(2);
00142   os << " " << name() << "\n";
00143   os << "Uvec" << "\n";
00144   t = DoubConv::dto2longs(defaultA);
00145   os << defaultA << " " << t[0] << " " << t[1] << "\n";
00146   os.precision(pr);
00147   return os;
00148 }
00149 
00150 std::istream & RandStudentT::get ( std::istream & is ) {
00151   std::string inName;
00152   is >> inName;
00153   if (inName != name()) {
00154     is.clear(std::ios::badbit | is.rdstate());
00155     std::cerr << "Mismatch when expecting to read state of a "
00156               << name() << " distribution\n"
00157               << "Name found was " << inName
00158               << "\nistream is left in the badbit state\n";
00159     return is;
00160   }
00161   if (possibleKeywordInput(is, "Uvec", defaultA)) {
00162     std::vector<unsigned long> t(2);
00163     is >> defaultA >> t[0] >> t[1]; defaultA = DoubConv::longs2double(t); 
00164     return is;
00165   }
00166   // is >> defaultA encompassed by possibleKeywordInput
00167   return is;
00168 }
00169 
00170 }  // namespace CLHEP

Generated on Mon May 27 17:50:33 2013 for Geant4 by  doxygen 1.4.7