43 ClassImp(RooQuasiRandomGenerator);
52 RooQuasiRandomGenerator::RooQuasiRandomGenerator()
54 if(!_coefsCalculated) {
55 calculateCoefs(MaxDimension);
56 _coefsCalculated= kTRUE;
59 _nextq=
new Int_t[MaxDimension];
67 RooQuasiRandomGenerator::~RooQuasiRandomGenerator()
76 void RooQuasiRandomGenerator::reset()
79 for(Int_t dim= 0; dim < MaxDimension; dim++) _nextq[dim]= 0;
87 Bool_t RooQuasiRandomGenerator::generate(UInt_t dimension, Double_t vector[])
90 static const Double_t recip = 1.0/(double)(1U << NBits);
93 for(dim=0; dim < dimension; dim++) {
94 vector[dim] = _nextq[dim] * recip;
101 Int_t r(0),c(_sequenceCount);
110 oocoutE((TObject*)0,Integration) <<
"RooQuasiRandomGenerator::generate: internal error!" << endl;
115 for(dim=0; dim<dimension; dim++) {
116 _nextq[dim] ^= _cj[r][dim];
127 void RooQuasiRandomGenerator::calculateCoefs(UInt_t dimension)
129 int ci[NBits][NBits];
130 int v[NBits+MaxDegree+1];
134 for(i_dim=0; i_dim<dimension; i_dim++) {
136 const int poly_index = i_dim + 1;
155 int px_degree = _polyDegree[poly_index];
158 for(k=0; k<=px_degree; k++) {
159 px[k] = _primitivePoly[poly_index][k];
164 for(j=0; j<NBits; j++) {
169 if(u == 0) calculateV(px, px_degree, pb, &pb_degree, v, NBits+MaxDegree);
177 for(r=0; r<NBits; r++) {
183 if(u == px_degree) u = 0;
190 for(r=0; r<NBits; r++) {
192 for(j=0; j<NBits; j++) {
193 term = 2*term + ci[r][j];
195 _cj[r][i_dim] = term;
205 void RooQuasiRandomGenerator::calculateV(
const int px[],
int px_degree,
206 int pb[],
int * pb_degree,
int v[],
int maxv)
208 const int nonzero_element = 1;
209 const int arbitrary_element = 1;
217 int bigm = *pb_degree;
221 for(k=0; k<=MaxDegree; k++) {
229 polyMultiply(px, px_degree, pb, *pb_degree, pb, pb_degree);
248 for(r=0; r<kj; r++) {
255 for(r=kj+1; r<m; r++) {
256 v[r] = arbitrary_element;
262 int term = sub(0, ph[kj]);
264 for(r=kj+1; r<bigm; r++) {
265 v[r] = arbitrary_element;
270 term = sub(term, mul(ph[r], v[r]));
274 v[bigm] = add(nonzero_element, term);
276 for(r=bigm+1; r<m; r++) {
277 v[r] = arbitrary_element;
284 for(r=0; r<=maxv-m; r++) {
287 term = sub(term, mul(pb[k], v[r+k]));
297 void RooQuasiRandomGenerator::polyMultiply(
const int pa[],
int pa_degree,
const int pb[],
298 int pb_degree,
int pc[],
int * pc_degree)
302 int pt_degree = pa_degree + pb_degree;
304 for(k=0; k<=pt_degree; k++) {
306 for(j=0; j<=k; j++) {
307 const int conv_term = mul(pa[k-j], pb[j]);
308 term = add(term, conv_term);
313 for(k=0; k<=pt_degree; k++) {
316 for(k=pt_degree+1; k<=MaxDegree; k++) {
320 *pc_degree = pt_degree;
326 Int_t RooQuasiRandomGenerator::_cj[RooQuasiRandomGenerator::NBits]
327 [RooQuasiRandomGenerator::MaxDimension];
333 const Int_t RooQuasiRandomGenerator::_primitivePoly[RooQuasiRandomGenerator::MaxDimension+1]
337 [RooQuasiRandomGenerator::MaxPrimitiveDegree+1] =
339 { 1, 0, 0, 0, 0, 0 },
340 { 0, 1, 0, 0, 0, 0 },
341 { 1, 1, 0, 0, 0, 0 },
342 { 1, 1, 1, 0, 0, 0 },
343 { 1, 1, 0, 1, 0, 0 },
344 { 1, 0, 1, 1, 0, 0 },
345 { 1, 1, 0, 0, 1, 0 },
346 { 1, 0, 0, 1, 1, 0 },
347 { 1, 1, 1, 1, 1, 0 },
348 { 1, 0, 1, 0, 0, 1 },
349 { 1, 0, 0, 1, 0, 1 },
350 { 1, 1, 1, 1, 0, 1 },
358 const Int_t RooQuasiRandomGenerator::_polyDegree[RooQuasiRandomGenerator::MaxDimension+1] =
360 0, 1, 1, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5
363 Bool_t RooQuasiRandomGenerator::_coefsCalculated= kFALSE;