Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:38

0001 // $Id: RandMultiGauss.h,v 1.3 2003/10/23 21:29:51 garren Exp $
0002 // -*- C++ -*-
0003 //
0004 // -----------------------------------------------------------------------
0005 //                             HEP Random
0006 //                          --- RandMultiGauss ---
0007 //                          class header file
0008 // -----------------------------------------------------------------------
0009 
0010 // Class defining methods for firing multivariate gaussian distributed 
0011 // random values, given a vector of means and a covariance matrix
0012 // Definitions are those from 1998 Review of Particle Physics, section 28.3.3.
0013 //
0014 // This utilizes the following other comonents of CLHEP:  
0015 //  RandGauss from the Random package to get individual deviates
0016 //  HepVector, HepSymMatrix and HepMatrix from the Matrix package
0017 //  HepSymMatrix::similarity(HepMatrix)
0018 //  diagonalize(HepSymMatrix *s)
0019 // The author of this distribution relies on diagonalize() being correct.
0020 //
0021 // Although original distribution classes in the Random package return a 
0022 // double when fire() (or operator()) is done, RandMultiGauss returns a 
0023 // HepVector of values.
0024 //    
0025 // =======================================================================
0026 // Mark Fischler  - Created: 19th September 1999
0027 // =======================================================================
0028 
0029 #ifndef RandMultiGauss_h
0030 #define RandMultiGauss_h 1
0031 
0032 #include "CLHEP/RandomObjects/defs.h"
0033 #include "CLHEP/Random/RandomEngine.h"
0034 #include "CLHEP/RandomObjects/RandomVector.h"
0035 #include "CLHEP/Matrix/Vector.h"
0036 #include "CLHEP/Matrix/Matrix.h"
0037 #include "CLHEP/Matrix/SymMatrix.h"
0038 
0039 namespace CLHEP {
0040 
0041 /**
0042  * @author Mark Fischler <mf@fnal.gov>
0043  * @ingroup robjects
0044  */
0045 class RandMultiGauss : public HepRandomVector {
0046 
0047 public:
0048 
0049   RandMultiGauss ( HepRandomEngine& anEngine, 
0050            const HepVector& mu, 
0051                    const HepSymMatrix& S );
0052         // The symmetric matrix S MUST BE POSITIVE DEFINITE
0053         // and MUST MATCH THE SIZE OF MU.
0054 
0055   RandMultiGauss ( HepRandomEngine* anEngine, 
0056            const HepVector& mu, 
0057                    const HepSymMatrix& S );
0058         // The symmetric matrix S MUST BE POSITIVE DEFINITE
0059         // and MUST MATCH THE SIZE OF MU.
0060 
0061   // These constructors should be used to instantiate a RandMultiGauss
0062   // distribution object defining a local engine for it.
0063   // The static generator will be skipped using the non-static methods
0064   // defined below.
0065   // If the engine is passed by pointer the corresponding engine object
0066   // will be deleted by the RandMultiGauss destructor.
0067   // If the engine is passed by reference the corresponding engine object
0068   // will not be deleted by the RandGauss destructor.
0069 
0070   // The following are provided for convenience in the case where each
0071   // random fired will have a different mu and S.  They set the default mu
0072   // to the zero 2-vector, and the default S to the Unit 2x2 matrix.  
0073   RandMultiGauss ( HepRandomEngine& anEngine );
0074   RandMultiGauss ( HepRandomEngine* anEngine );
0075 
0076   virtual ~RandMultiGauss();
0077   // Destructor
0078 
0079   HepVector fire();
0080 
0081   HepVector fire( const HepVector& mu, const HepSymMatrix& S );
0082         // The symmetric matrix S MUST BE POSITIVE DEFINITE
0083         // and MUST MATCH THE SIZE OF MU.
0084   
0085   // A note on efficient usage when firing many vectors of Multivariate 
0086   // Gaussians:   For n > 2 the work needed to diagonalize S is significant.
0087   // So if you only want a collection of uncorrelated Gaussians, it will be
0088   // quicker to generate them one at a time.
0089   //
0090   // The class saves the diagonalizing matrix for the default S.  
0091   // Thus generating vectors with that same S can be quite efficient.  
0092   // If you require a small number of different S's, known in 
0093   // advance, consider instantiating RandMulitGauss for each different S,
0094   // sharing the same engine.  
0095   // 
0096   // If you require a random using the default S for a distribution but a 
0097   // different mu, it is most efficient to imply use the default fire() and 
0098   // add the difference of the mu's to the returned HepVector.
0099 
0100   void fireArray ( const int size, HepVector* array);
0101   void fireArray ( const int size, HepVector* array,
0102            const HepVector& mu, const HepSymMatrix& S );
0103 
0104   HepVector operator()();
0105   HepVector operator()( const HepVector& mu, const HepSymMatrix& S );
0106         // The symmetric matrix S MUST BE POSITIVE DEFINITE
0107         // and MUST MATCH THE SIZE OF MU.
0108 
0109 private:
0110 
0111   // Private copy constructor. Defining it here disallows use.
0112   RandMultiGauss(const RandMultiGauss &d);
0113 
0114   HepRandomEngine* localEngine;
0115   bool deleteEngine;
0116   HepVector    defaultMu;
0117   HepMatrix    defaultU;
0118   HepVector    defaultSigmas;   // Each sigma is sqrt(D[i,i])
0119 
0120   bool set;
0121   double nextGaussian;
0122 
0123   static void prepareUsigmas (  const HepSymMatrix & S,
0124                 HepMatrix & U,
0125                 HepVector & sigmas );
0126 
0127   static HepVector deviates ( const HepMatrix & U, 
0128                       const HepVector & sigmas, 
0129                       HepRandomEngine * engine,
0130                       bool& available,
0131                   double& next);
0132   // Returns vector of gaussian randoms based on sigmas, rotated by U,
0133   // with means of 0.
0134                
0135 };
0136 
0137 }  // namespace CLHEP
0138 
0139 #ifdef ENABLE_BACKWARDS_COMPATIBILITY
0140 //  backwards compatibility will be enabled ONLY in CLHEP 1.9
0141 using namespace CLHEP;
0142 #endif
0143 
0144 #endif // RandMultiGauss_h