static void Reweight(cThis *t, Bounds *b, creal *w, creal *f, creal *lastf, cResult *total) { Vector(Grid, margsum, NDIM); Vector(real, scale, NCOMP); cbin_t *bin = (cbin_t *)lastf; count dim, comp; if( t->ncomp == 1 ) scale[0] = 1; else { for( comp = 0; comp < t->ncomp; ++comp ) scale[comp] = (total[comp].avg == 0) ? 0 : 1/total[comp].avg; } XClear(margsum); while( f < lastf ) { real fsq = 0; for( comp = 0; comp < t->ncomp; ++comp ) fsq += Sq(*f++*scale[comp]); fsq *= Sq(*w++); if( fsq != 0 ) for( dim = 0; dim < t->ndim; ++dim ) margsum[dim][bin[dim]] += fsq; bin += t->ndim; } for( dim = 0; dim < t->ndim; ++dim ) RefineGrid(t, b[dim].grid, margsum[dim]); }
static int Integrate(This *t, real *integral, real *error, real *prob) { bin_t *bins; count dim, comp; int fail; StateDecl; csize_t statesize = sizeof(State) + NCOMP*sizeof(Cumulants) + NDIM*sizeof(Grid); Sized(State, state, statesize); Cumulants *c, *C = state->cumul + t->ncomp; Grid *state_grid = (Grid *)C; Array(Grid, margsum, NCOMP, NDIM); Vector(char, out, 128*NCOMP + 256); if( VERBOSE > 1 ) { sprintf(out, "Vegas input parameters:\n" " ndim " COUNT "\n ncomp " COUNT "\n" " epsrel " REAL "\n epsabs " REAL "\n" " flags %d\n seed %d\n" " mineval " NUMBER "\n maxeval " NUMBER "\n" " nstart " NUMBER "\n nincrease " NUMBER "\n" " nbatch " NUMBER "\n gridno %d\n" " statefile \"%s\"", t->ndim, t->ncomp, t->epsrel, t->epsabs, t->flags, t->seed, t->mineval, t->maxeval, t->nstart, t->nincrease, t->nbatch, t->gridno, t->statefile); Print(out); } if( BadComponent(t) ) return -2; if( BadDimension(t) ) return -1; FrameAlloc(t, ShmRm(t)); ForkCores(t); Alloc(bins, t->nbatch*t->ndim); if( (fail = setjmp(t->abort)) ) goto abort; IniRandom(t); StateSetup(t); if( StateReadTest(t) ) { StateReadOpen(t, fd) { if( read(fd, state, statesize) != statesize || state->signature != StateSignature(t, 1) ) break; } StateReadClose(t, fd); t->neval = state->neval; t->rng.skiprandom(t, t->neval); } if( ini ) { state->niter = 0; state->nsamples = t->nstart; FClear(state->cumul); GetGrid(t, state_grid); t->neval = 0; } /* main iteration loop */ for( ; ; ) { number nsamples = state->nsamples; creal jacobian = 1./nsamples; FClear(margsum); for( ; nsamples > 0; nsamples -= t->nbatch ) { cnumber n = IMin(t->nbatch, nsamples); real *w = t->frame; real *x = w + n; real *f = x + n*t->ndim; real *lastf = f + n*t->ncomp; bin_t *bin = bins; while( x < f ) { real weight = jacobian; t->rng.getrandom(t, x); for( dim = 0; dim < t->ndim; ++dim ) { creal pos = *x*NBINS; ccount ipos = (count)pos; creal prev = (ipos == 0) ? 0 : state_grid[dim][ipos - 1]; creal diff = state_grid[dim][ipos] - prev; *x++ = prev + (pos - ipos)*diff; *bin++ = ipos; weight *= diff*NBINS; } *w++ = weight; } DoSample(t, n, w, f, t->frame, state->niter + 1); bin = bins; w = t->frame; while( f < lastf ) { creal weight = *w++; Grid *m = &margsum[0][0]; for( c = state->cumul; c < C; ++c ) { real wfun = weight*(*f++); if( wfun ) { c->sum += wfun; c->sqsum += wfun *= wfun; for( dim = 0; dim < t->ndim; ++dim ) m[dim][bin[dim]] += wfun; } m += t->ndim; } bin += t->ndim; } } fail = 0; /* compute the integral and error values */ for( c = state->cumul; c < C; ++c ) { real w = Weight(c->sum, c->sqsum, state->nsamples); real sigsq = 1/(c->weightsum += w); real avg = sigsq*(c->avgsum += w*c->sum); c->avg = LAST ? (sigsq = 1/w, c->sum) : avg; c->err = sqrt(sigsq); fail |= (c->err > MaxErr(c->avg)); if( state->niter == 0 ) c->guess = c->sum; else { c->chisum += w *= c->sum - c->guess; c->chisqsum += w*c->sum; } c->chisq = c->chisqsum - avg*c->chisum; c->sum = c->sqsum = 0; } if( VERBOSE ) { char *oe = out + sprintf(out, "\n" "Iteration " COUNT ": " NUMBER " integrand evaluations so far", state->niter + 1, t->neval); for( c = state->cumul, comp = 0; c < C; ++c ) oe += sprintf(oe, "\n[" COUNT "] " REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)", ++comp, c->avg, c->err, c->chisq, state->niter); Print(out); } if( fail == 0 && t->neval >= t->mineval ) break; if( t->neval >= t->maxeval && !StateWriteTest(t) ) break; if( t->ncomp == 1 ) for( dim = 0; dim < t->ndim; ++dim ) RefineGrid(t, state_grid[dim], margsum[0][dim]); else { for( dim = 0; dim < t->ndim; ++dim ) { Grid wmargsum; Zap(wmargsum); for( comp = 0; comp < t->ncomp; ++comp ) { real w = state->cumul[comp].avg; if( w != 0 ) { creal *m = margsum[comp][dim]; count bin; w = 1/Sq(w); for( bin = 0; bin < NBINS; ++bin ) wmargsum[bin] += w*m[bin]; } } RefineGrid(t, state_grid[dim], wmargsum); } } ++state->niter; state->nsamples += t->nincrease; if( StateWriteTest(t) ) { state->signature = StateSignature(t, 1); state->neval = t->neval; StateWriteOpen(t, fd) { StateWrite(fd, state, statesize); } StateWriteClose(t, fd); if( t->neval >= t->maxeval ) break; } }
void MonteCarloIntegral::Integrate(double* I, double* param, double* errorout, int* nevalout, double epsrel, double epsabs) const { /* Make sure error thresholds are sensible */ if(epsrel <= 0) epsrel = DEFAULT_EPSREL; if(epsabs <= 0) epsabs = DEFAULT_EPSABS; int neval = 0; /* Compute Jacobian */ double jacobian = 1; for(int i = 0; i < n; i++) jacobian *= (V[i].b - V[i].a); /* Initialize state */ State state; state.niter = 0; state.nsamples = nstart; state.cumul.resize(m); state.grid.resize(n); for(int i = 0; i < n; i++) for(int bin = 0; bin < NBINS; bin++) state.grid[i][bin] = (bin + 1)/(double)NBINS; /* Initialize quasi-random number generator */ Sobol qrng; rng_sobol_init(&qrng, n); /* Initialize sample buffer */ int samplebufsize = nbatch*((1 + n + m)*sizeof(double) + n*sizeof(short)); char* samplebuf = (char*)malloc(samplebufsize); /* Main iteration loop */ int notdone = 1; while(notdone) { int nsamples = state.nsamples; Grid margsum[m][n]; memset(margsum, 0, sizeof(margsum)); double base_weight = 1./nsamples; /* Sample integrand one batch at a time */ while(nsamples > 0) { int size = (nbatch < nsamples) ? nbatch : nsamples; // size of current batch double* w = (double*)samplebuf; double* x = w + size; double* f = x + size*n; double* lastf = f + size*m; short* bin = (short*)lastf; /* Prepare positions and weights for sampling */ while(x < f) { double weight = base_weight; rng_sobol_get(&qrng, x); for(int i = 0; i < n; i++) { double pos = (*x)*NBINS; int ipos = (int)pos; double prev = (ipos == 0) ? 0 : state.grid[i][ipos-1]; double diff = state.grid[i][ipos] - prev; *x++ = prev + (pos - ipos)*diff; *bin++ = ipos; weight *= diff*NBINS; } *w++ = weight; } /* Sample integrand (why does Cuba's DoSample() pass w to the integrand?) */ f = x; x = w; double y[n]; for(int s = 0; s < size; s++) { for(int i = 0; i < n; i++) y[i] = V[i].a + x[i]*(V[i].b - V[i].a); Integrand(y, f, param); x += n; f += m; } neval += size; /* Adjust weights */ f = x; w = (double*)samplebuf; bin = (short*)lastf; while(f < lastf) { double weight = *w++; for(int j = 0; j < m; j++) { double wfun = weight * (*f++); if(wfun != 0) { Cumulants* c = &state.cumul[j]; Grid* ms = margsum[j]; c->sum += wfun; c->sqsum += wfun*wfun; for(int i = 0; i < n; i++) ms[i][bin[i]] += wfun*wfun; } } bin += n; } nsamples -= nbatch; } notdone = 0; /* Compute the integral and error values */ for(int j = 0; j < m; j++) { Cumulants* c = &state.cumul[j]; double w = Weight(c->sum, c->sqsum, state.nsamples); c->weightsum += w; c->avgsum += w*c->sum; double sigsq = 1/c->weightsum; c->avg = sigsq*c->avgsum; c->err = sqrt(sigsq); notdone |= (c->err > fmax(epsrel*fabs(c->avg), epsabs/jacobian)); if(state.niter == 0) c->guess = c->sum; else { w *= (c->sum - c->guess); c->chisum += w; c->chisqsum += w*c->sum; } c->chisq = c->chisqsum - c->avg*c->chisum; c->sum = c->sqsum = 0; } /* Finish if we're below error thresholds */ if(notdone == 0) break; /* Abort (with a warning) if we've reached the maximum number of evaluations */ if(neval >= maxeval) { warning("MonteCarlo: maximum number of evaluations reached\n"); break; } /* Refine the grid for the next iteration */ if(m == 1) { for(int i = 0; i < n; i++) RefineGrid(state.grid[i], margsum[0][i]); } else { for(int i = 0; i < n; i++) { Grid wmargsum; memset(wmargsum, 0, sizeof(wmargsum)); for(int j = 0; j < m; j++) { double w = state.cumul[j].avg; if(w != 0) { double* ms = margsum[j][i]; for(int bin = 0; bin < NBINS; bin++) wmargsum[bin] += ms[bin]/(w*w); } } RefineGrid(state.grid[i], wmargsum); } } /* Proceed to the next iteration */ state.niter++; state.nsamples += nincrease; } /* Prepare results */ for(int j = 0; j < m; j++) { Cumulants* c = &state.cumul[j]; I[j] = jacobian * c->avg; if(errorout) errorout[j] = jacobian * c->err; } if(nevalout) *nevalout = neval; }
static int Integrate(This *t, real *integral, real *error, real *prob) { bin_t *bins; count dim, comp; int fail; struct { count niter; number nsamples, neval; Cumulants cumul[NCOMP]; Grid grid[NDIM]; } state; int statemsg = VERBOSE; struct stat st; if( VERBOSE > 1 ) { char s[512]; sprintf(s, "Vegas input parameters:\n" " ndim " COUNT "\n ncomp " COUNT "\n" " epsrel " REAL "\n epsabs " REAL "\n" " flags %d\n seed %d\n" " mineval " NUMBER "\n maxeval " NUMBER "\n" " nstart " NUMBER "\n nincrease " NUMBER "\n" " nbatch " NUMBER "\n gridno %d\n" " statefile \"%s\"", t->ndim, t->ncomp, t->epsrel, t->epsabs, t->flags, t->seed, t->mineval, t->maxeval, t->nstart, t->nincrease, t->nbatch, t->gridno, t->statefile); Print(s); } if( BadComponent(t) ) return -2; if( BadDimension(t) ) return -1; FrameAlloc(t, ShmRm(t)); ForkCores(t); Alloc(bins, t->nbatch*t->ndim); if( (fail = setjmp(t->abort)) ) goto abort; IniRandom(t); if( t->statefile && *t->statefile == 0 ) t->statefile = NULL; if( t->statefile && stat(t->statefile, &st) == 0 && st.st_size == sizeof state && (st.st_mode & 0400) ) { cint h = open(t->statefile, O_RDONLY); read(h, &state, sizeof state); close(h); t->rng.skiprandom(t, t->neval = state.neval); if( VERBOSE ) { char s[256]; sprintf(s, "\nRestoring state from %s.", t->statefile); Print(s); } } else { state.niter = 0; state.nsamples = t->nstart; Zap(state.cumul); GetGrid(t, state.grid); } /* main iteration loop */ for( ; ; ) { number nsamples = state.nsamples; creal jacobian = 1./nsamples; Grid margsum[NCOMP][NDIM]; Zap(margsum); for( ; nsamples > 0; nsamples -= t->nbatch ) { cnumber n = IMin(t->nbatch, nsamples); real *w = t->frame; real *x = w + n; real *f = x + n*t->ndim; real *lastf = f + n*t->ncomp; bin_t *bin = bins; while( x < f ) { real weight = jacobian; t->rng.getrandom(t, x); for( dim = 0; dim < t->ndim; ++dim ) { creal pos = *x*NBINS; ccount ipos = (count)pos; creal prev = (ipos == 0) ? 0 : state.grid[dim][ipos - 1]; creal diff = state.grid[dim][ipos] - prev; *x++ = prev + (pos - ipos)*diff; *bin++ = ipos; weight *= diff*NBINS; } *w++ = weight; } DoSample(t, n, w, f, t->frame, state.niter + 1); bin = bins; w = t->frame; while( f < lastf ) { creal weight = *w++; for( comp = 0; comp < t->ncomp; ++comp ) { real wfun = weight*(*f++); if( wfun ) { Cumulants *c = &state.cumul[comp]; Grid *m = margsum[comp]; c->sum += wfun; c->sqsum += wfun *= wfun; for( dim = 0; dim < t->ndim; ++dim ) m[dim][bin[dim]] += wfun; } } bin += t->ndim; } } fail = 0; /* compute the integral and error values */ for( comp = 0; comp < t->ncomp; ++comp ) { Cumulants *c = &state.cumul[comp]; real avg, sigsq; real w = Weight(c->sum, c->sqsum, state.nsamples); sigsq = 1/(c->weightsum += w); avg = sigsq*(c->avgsum += w*c->sum); c->avg = LAST ? (sigsq = 1/w, c->sum) : avg; c->err = sqrt(sigsq); fail |= (c->err > MaxErr(c->avg)); if( state.niter == 0 ) c->guess = c->sum; else { c->chisum += w *= c->sum - c->guess; c->chisqsum += w*c->sum; } c->chisq = c->chisqsum - avg*c->chisum; c->sum = c->sqsum = 0; } if( VERBOSE ) { char s[128 + 128*NCOMP], *p = s; p += sprintf(p, "\n" "Iteration " COUNT ": " NUMBER " integrand evaluations so far", state.niter + 1, t->neval); for( comp = 0; comp < t->ncomp; ++comp ) { cCumulants *c = &state.cumul[comp]; p += sprintf(p, "\n[" COUNT "] " REAL " +- " REAL " \tchisq " REAL " (" COUNT " df)", comp + 1, c->avg, c->err, c->chisq, state.niter); } Print(s); } if( fail == 0 && t->neval >= t->mineval ) { if( t->statefile && KEEPFILE == 0 ) unlink(t->statefile); break; } if( t->neval >= t->maxeval && t->statefile == NULL ) break; if( t->ncomp == 1 ) for( dim = 0; dim < t->ndim; ++dim ) RefineGrid(t, state.grid[dim], margsum[0][dim]); else { for( dim = 0; dim < t->ndim; ++dim ) { Grid wmargsum; Zap(wmargsum); for( comp = 0; comp < t->ncomp; ++comp ) { real w = state.cumul[comp].avg; if( w != 0 ) { creal *m = margsum[comp][dim]; count bin; w = 1/Sq(w); for( bin = 0; bin < NBINS; ++bin ) wmargsum[bin] += w*m[bin]; } } RefineGrid(t, state.grid[dim], wmargsum); } } ++state.niter; state.nsamples += t->nincrease; if( t->statefile ) { cint h = creat(t->statefile, 0666); if( h != -1 ) { state.neval = t->neval; write(h, &state, sizeof state); close(h); if( statemsg ) { char s[256]; sprintf(s, "\nSaving state to %s.", t->statefile); Print(s); statemsg = false; } } if( t->neval >= t->maxeval ) break; } } for( comp = 0; comp < t->ncomp; ++comp ) { cCumulants *c = &state.cumul[comp]; integral[comp] = c->avg; error[comp] = c->err; prob[comp] = ChiSquare(c->chisq, state.niter); } abort: PutGrid(t, state.grid); free(bins); WaitCores(t); FrameFree(t); return fail; }