Esempio n. 1
0
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]);
}
Esempio n. 2
0
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;
    }
  }
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}