/***************************************************************************** * Project: RooFit * * Package: RooFitCore * * @(#)root/roofitcore:$Id$ * Authors: * * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * * * * Copyright (c) 2000-2005, Regents of the University of California * * and Stanford University. All rights reserved. * * * * Redistribution and use in source and binary forms, * * with or without modification, are permitted according to the terms * * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * *****************************************************************************/ ////////////////////////////////////////////////////////////////////////////// // // BEGIN_HTML // This class generates the quasi-random (aka "low discrepancy") // sequence for dimensions up to 12 using the Niederreiter base 2 // algorithm described in Bratley, Fox, Niederreiter, ACM Trans. // Model. Comp. Sim. 2, 195 (1992). This implementation was adapted // from the 0.9 beta release of the GNU scientific library. // Quasi-random number sequences are useful for improving the // convergence of a Monte Carlo integration. // END_HTML // #include "RooFit.h" #include "RooQuasiRandomGenerator.h" #include "RooQuasiRandomGenerator.h" #include "RooMsgService.h" #include "TMath.h" #include "Riostream.h" #include using namespace std; ClassImp(RooQuasiRandomGenerator) ; //_____________________________________________________________________________ RooQuasiRandomGenerator::RooQuasiRandomGenerator() { // Perform one-time initialization of our static coefficient array if necessary // and initialize our workspace. if(!_coefsCalculated) { calculateCoefs(MaxDimension); _coefsCalculated= kTRUE; } // allocate workspace memory _nextq= new Int_t[MaxDimension]; reset(); } //_____________________________________________________________________________ RooQuasiRandomGenerator::~RooQuasiRandomGenerator() { // Destructor delete[] _nextq; } //_____________________________________________________________________________ void RooQuasiRandomGenerator::reset() { // Reset the workspace to its initial state. _sequenceCount= 0; for(Int_t dim= 0; dim < MaxDimension; dim++) _nextq[dim]= 0; } //_____________________________________________________________________________ Bool_t RooQuasiRandomGenerator::generate(UInt_t dimension, Double_t vector[]) { // Generate the next number in the sequence for the specified dimension. // The maximum dimension supported is 12. /* Load the result from the saved state. */ static const Double_t recip = 1.0/(double)(1U << NBits); /* 2^(-nbits) */ UInt_t dim; for(dim=0; dim < dimension; dim++) { vector[dim] = _nextq[dim] * recip; } /* Find the position of the least-significant zero in sequence_count. * This is the bit that changes in the Gray-code representation as * the count is advanced. */ Int_t r(0),c(_sequenceCount); while(1) { if((c % 2) == 1) { ++r; c /= 2; } else break; } if(r >= NBits) { oocoutE((TObject*)0,Integration) << "RooQuasiRandomGenerator::generate: internal error!" << endl; return kFALSE; } /* Calculate the next state. */ for(dim=0; dim= bigm) { for(r=kj+1; r