示例#1
0
char* EnigmaCrypt::Encrypt(char* hold, int rot)
{
  if (!GetOneToOneEncode() || InDataset(hold))
  {
      _EnctablePtr = _EncryptionTable;
      strcpy(hold, Zap(hold));
      if (rot % 2)
        _EnctablePtr = Zap(_EnctablePtr);
      strcpy(hold, Encrypt_String(hold, rot));
  }

  return hold;
}
示例#2
0
文件: Rule.c 项目: cran/cubature
static void SampleRule(This *t, ccount iregion)
{
  SAMPLERDEFS;
  Set *first = samples->rule->first;
  Set *last = samples->rule->last;
  Set *s;
  creal *errcoeff = samples->rule->errcoeff;
  count comp, rul, sn;
  csize_t setsize = SetSize;

  for( s = first; s <= last; NextSet(s) )
    if( s->n ) x = ExpandFS(t, b, s->gen, x);

  DoSample(t, n, samples->x, f);

  for( comp = 0; comp < t->ncomp; ++comp ) {
    real sum[nrules];
    creal *f1 = f++;

    Zap(sum);
    for( s = first; s <= last; NextSet(s) )
      for( sn = s->n; sn; --sn ) {
        creal fun = *f1;
        f1 += t->ncomp;
        for( rul = 0; rul < nrules; ++rul )
          sum[rul] += fun*s->weight[rul];
      }

    /* Search for the null rule, in the linear space spanned by two
       successive null rules in our sequence, which gives the greatest
       error estimate among all normalized (1-norm) null rules in this
       space. */

    for( rul = 1; rul < nrules - 1; ++rul ) {
      real maxerr = 0;
      for( s = first; s <= last; NextSet(s) )
        maxerr = Max(maxerr,
          fabsx(sum[rul + 1] + s->scale[rul]*sum[rul])*s->norm[rul]);
      sum[rul] = maxerr;
    }

    res[comp].avg = region->vol*sum[0];
    res[comp].err = region->vol*(
      (errcoeff[0]*sum[1] <= sum[2] && errcoeff[0]*sum[2] <= sum[3]) ?
        errcoeff[1]*sum[1] :
        errcoeff[2]*Max(Max(sum[1], sum[2]), sum[3]) );
  }
}
示例#3
0
void wxTermLine::ZapDel(int begin, int count)
{
	int i;
	int end = width-1;
	// moving back
	for (i=begin+count;i<=end;++i)
	{
		chars[i-count] = chars[i];
		attrs[i-count] = attrs[i];
		//if (attrs[i] > 0) visible_width = i +1;
	}
	if (visible_width - count > 0) visible_width -= count; else visible_width = 0;
	Zap(end-count, end);
	
	dirty = true;
};
示例#4
0
void CLightning::RandomPoint( Vector &vecSrc )
{
	int iLoops = 0;

	for (iLoops = 0; iLoops < 10; iLoops++)
	{
		Vector vecDir1 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) );
		vecDir1 = vecDir1.Normalize();
		TraceResult		tr1;
		UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, ignore_monsters, ENT(pev), &tr1 );

		if ((tr1.vecEndPos - vecSrc).Length() < m_radius * 0.1)
			continue;

		if (tr1.flFraction == 1.0)
			continue;

		Zap( vecSrc, tr1.vecEndPos );
		break;
	}
}
示例#5
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : vecSrc - 
//-----------------------------------------------------------------------------
void CEnvBeam::RandomPoint( const Vector &vecSrc )
{
	int iLoops = 0;

	for (iLoops = 0; iLoops < 10; iLoops++)
	{
		Vector vecDir1 = Vector( random->RandomFloat( -1.0, 1.0 ), random->RandomFloat( -1.0, 1.0 ),random->RandomFloat( -1.0, 1.0 ) );
		VectorNormalize( vecDir1 );
		trace_t	tr1;
		UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr1 );

		if ((tr1.endpos - vecSrc).Length() < m_radius * 0.1)
			continue;

		if (tr1.fraction == 1.0)
			continue;

		Zap( vecSrc, tr1.endpos );
		break;
	}
}
示例#6
0
void CLightning::RandomArea( void )
{
	int iLoops = 0;

	for (iLoops = 0; iLoops < 10; iLoops++)
	{
		Vector vecSrc = pev->origin;

		Vector vecDir1 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) );
		vecDir1 = vecDir1.Normalize();
		TraceResult		tr1;
		UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, ignore_monsters, ENT(pev), &tr1 );

		if (tr1.flFraction == 1.0)
			continue;

		Vector vecDir2;
		do {
			vecDir2 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) );
		} while (DotProduct(vecDir1, vecDir2 ) > 0);
		vecDir2 = vecDir2.Normalize();
		TraceResult		tr2;
		UTIL_TraceLine( vecSrc, vecSrc + vecDir2 * m_radius, ignore_monsters, ENT(pev), &tr2 );

		if (tr2.flFraction == 1.0)
			continue;

		if ((tr1.vecEndPos - tr2.vecEndPos).Length() < m_radius * 0.1)
			continue;

		UTIL_TraceLine( tr1.vecEndPos, tr2.vecEndPos, ignore_monsters, ENT(pev), &tr2 );

		if (tr2.flFraction != 1.0)
			continue;

		Zap( tr1.vecEndPos, tr2.vecEndPos );

		break;
	}
}
示例#7
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CEnvBeam::RandomArea( void )
{
	int iLoops = 0;

	for (iLoops = 0; iLoops < 10; iLoops++)
	{
		Vector vecSrc = GetAbsOrigin();

		Vector vecDir1 = Vector( random->RandomFloat( -1.0, 1.0 ), random->RandomFloat( -1.0, 1.0 ),random->RandomFloat( -1.0, 1.0 ) );
		VectorNormalize( vecDir1 );
		trace_t	tr1;
		UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr1 );

		if (tr1.fraction == 1.0)
			continue;

		Vector vecDir2;
		do {
			vecDir2 = Vector( random->RandomFloat( -1.0, 1.0 ), random->RandomFloat( -1.0, 1.0 ),random->RandomFloat( -1.0, 1.0 ) );
		} while (DotProduct(vecDir1, vecDir2 ) > 0);
		VectorNormalize( vecDir2 );
		trace_t	tr2;
		UTIL_TraceLine( vecSrc, vecSrc + vecDir2 * m_radius, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr2 );

		if (tr2.fraction == 1.0)
			continue;

		if ((tr1.endpos - tr2.endpos).Length() < m_radius * 0.1)
			continue;

		UTIL_TraceLine( tr1.endpos, tr2.endpos, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr2 );

		if (tr2.fraction != 1.0)
			continue;

 		Zap( tr1.endpos, tr2.endpos );

		break;
	}
}
示例#8
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;
    }
  }
示例#9
0
static void Sample(This *t, cnumber nnew, void *voidregion,
                   real *lastw, real *lastx, real *lastf)
{
    TYPEDEFREGION;

    Region *const region = (Region *)voidregion;
    count comp, dim, df;
    number n;
    Cumulants cumul[NCOMP];
    char **ss, *s;
    ccount chars = 128*(region->div + 1);

    creal jacobian = 1/ldexp((real)nnew, region->div);
    real *w = lastw, *f = lastx;
    bin_t *bin = (bin_t *)(lastf + nnew*t->ncomp);

    for( n = nnew; n; --n ) {
        real weight = jacobian;

        t->rng.getrandom(t, f);

        for( dim = 0; dim < t->ndim; ++dim ) {
            cBounds *b = &region->bounds[dim];
            creal pos = *f*NBINS;
            ccount ipos = (count)pos;
            creal prev = (ipos == 0) ? 0 : b->grid[ipos - 1];
            creal diff = b->grid[ipos] - prev;
            *f++ = b->lower + (prev + (pos - ipos)*diff)*(b->upper - b->lower);
            *bin++ = ipos;
            weight *= diff*NBINS;
        }

        *w++ = weight;
    }

    DoSample(t, nnew, lastw, lastx, lastf, region->div + 1);

    w[-1] = -w[-1];
    lastw = w;
    w = region->w;
    region->n = lastw - w;

    if( VERBOSE > 2 ) {
        char *p0;
        MemAlloc(ss, t->ndim*64 + t->ncomp*(sizeof(char *) + chars));
        s = (char *)(ss + t->ncomp);
        p0 = s + t->ndim*64;
        for( comp = 0; comp < t->ncomp; ++comp ) {
            ss[comp] = p0;
            p0 += chars;
        }
    }

    Zap(cumul);
    df = n = 0;

    while( w < lastw ) {
        cbool final = (*w < 0);
        creal weight = fabs(*w++);
        ++n;

        for( comp = 0; comp < t->ncomp; ++comp ) {
            Cumulants *c = &cumul[comp];

            creal wfun = weight*(*f++);
            c->sum += wfun;
            c->sqsum += Sq(wfun);

            if( final ) {
                if( n > 1 ) {
                    real w = Weight(c->sum, c->sqsum, n);
                    c->weightsum += c->weight = w;
                    c->avgsum += c->avg = w*c->sum;

                    if( VERBOSE > 2 ) {
                        creal sig = sqrt(1/w);
                        ss[comp] += (df == 0) ?
                                    sprintf(ss[comp], "\n[" COUNT "] "
                                            REAL " +- " REAL " (" NUMBER ")", comp + 1,
                                            c->sum, sig, n) :
                                    sprintf(ss[comp], "\n    "
                                            REAL " +- " REAL " (" NUMBER ")",
                                            c->sum, sig, n);
                    }

                    if( df == 0 ) c->guess = c->sum;
                    else {
                        c->chisum += w *= c->sum - c->guess;
                        c->chisqsum += w*c->sum;
                    }
                }

                c->sum = c->sqsum = 0;
            }
        }

        if( final ) ++df, n = 0;
    }

    region->df = --df;

    for( comp = 0; comp < t->ncomp; ++comp ) {
        Result *r = &region->result[comp];
        Cumulants *c = &cumul[comp];
        creal sigsq = 1/c->weightsum;
        creal avg = sigsq*c->avgsum;

        if( LAST ) {
            r->sigsq = 1/c->weight;
            r->avg = r->sigsq*c->avg;
        }
        else {
            r->sigsq = sigsq;
            r->avg = avg;
        }
        r->err = sqrt(r->sigsq);

        r->chisq = (sigsq < .9*NOTZERO) ? 0 : c->chisqsum - avg*c->chisum;
        /* This catches the special case where the integrand is constant
           over the entire region.  Unless that constant is zero, only the
           first set of samples will have zero variance, and hence weight
           (n - 1) 1e30 (see above).  All other sets have been sampled
           from a non-constant weight function and therefore inevitably
           show some variance.  This is an artificial effect, brought about
           by the fact that the constancy of the integrand in the region is
           seen only in this subdivision, and can degrade the chi-square
           score quite a bit.  If the constancy was determined from more
           than two samples (hence .9*NOTZERO), the chi-squares from the
           other sets are removed here. */
    }

    if( VERBOSE > 2 ) {
        char *p = s;
        char *p0 = p + t->ndim*64;

        for( dim = 0; dim < t->ndim; ++dim ) {
            cBounds *b = &region->bounds[dim];
            p += sprintf(p,
                         (dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
                         "\n       (" REALF ") - (" REALF ")",
                         b->lower, b->upper);
        }

        for( comp = 0; comp < t->ncomp; ++comp ) {
            cResult *r = &region->result[comp];
            p += sprintf(p, "%s  \tchisq " REAL " (" COUNT " df)",
                         p0, r->chisq, df);
            p0 += chars;
        }

        Print(s);
        free(ss);
    }
}
示例#10
0
STDMETHODIMP CADObjectColl::RemoveAll(void)
{
    Zap();
    return S_OK;
}
示例#11
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;
}
示例#12
0
static void Sample(This *t, void *voidregion)
{
  TYPEDEFREGION;
  TYPEDEFSET;

  Region *const region = (Region *)voidregion;
  creal vol = ldexp(1., -region->div);

  real *x = t->rule.x, *f = t->rule.f;
  Set *first = (Set *)t->rule.first, *last = (Set *)t->rule.last, *s;
  creal *errcoeff = t->rule.errcoeff;
  creal ratio = Sq(first[2].gen[0]/first[1].gen[0]);

  ccount offset = 2*t->ndim*t->ncomp;
  count dim, comp, rul, n, maxdim = 0;
  real maxrange = 0;

  for( dim = 0; dim < t->ndim; ++dim ) {
    cBounds *b = &region->bounds[dim];
    creal range = b->upper - b->lower;
    if( range > maxrange ) {
      maxrange = range;
      maxdim = dim;
    }
  }

  for( s = first; s <= last; ++s )
    if( s->n ) x = ExpandFS(t, region->bounds, s->gen, x);

  DoSample(t, t->rule.n, t->rule.x, f);

  for( comp = 0; comp < t->ncomp; ++comp ) {
    Result *r = &region->result[comp];
    real sum[nrules];
    creal *f1 = f;
    creal base = *f1*2*(1 - ratio);
    real maxdiff = 0;
    count bisectdim = maxdim;

    for( dim = 0; dim < t->ndim; ++dim ) {
      creal *fp = f1 + t->ncomp;
      creal *fm = fp + t->ncomp;
      creal fourthdiff = fabs(base +
        ratio*(fp[0] + fm[0]) - (fp[offset] + fm[offset]));
      f1 = fm;
      if( fourthdiff > maxdiff ) {
        maxdiff = fourthdiff;
        bisectdim = dim;
      }
    }
    r->bisectdim = bisectdim;

    f1 = f++;
    Zap(sum);
    for( s = first; s <= last; ++s )
      for( n = s->n; n; --n ) {
        creal fun = *f1;
        f1 += t->ncomp;
        for( rul = 0; rul < nrules; ++rul )
          sum[rul] += fun*s->weight[rul];
      }

    /* Search for the null rule, in the linear space spanned by two
       successive null rules in our sequence, which gives the greatest
       error estimate among all normalized (1-norm) null rules in this
       space. */

    for( rul = 1; rul < nrules - 1; ++rul ) {
      real maxerr = 0;
      for( s = first; s <= last; ++s )
        maxerr = Max(maxerr,
          fabs(sum[rul + 1] + s->scale[rul]*sum[rul])*s->norm[rul]);
      sum[rul] = maxerr;
    }

    r->avg = vol*sum[0];
    r->err = vol*(
      (errcoeff[0]*sum[1] <= sum[2] && errcoeff[0]*sum[2] <= sum[3]) ?
        errcoeff[1]*sum[1] :
        errcoeff[2]*Max(Max(sum[1], sum[2]), sum[3]) );
  }

  if( VERBOSE > 2 ) {
    char s[64*NDIM + 128*NCOMP], *p = s;

    for( dim = 0; dim < t->ndim; ++dim ) {
      cBounds *b = &region->bounds[dim];
      p += sprintf(p,
        (dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
                     "\n       (" REALF ") - (" REALF ")",
        b->lower, b->upper);
    }

    for( comp = 0; comp < t->ncomp; ++comp ) {
      cResult *r = &region->result[comp];
      p += sprintf(p, "\n[" COUNT "] "
        REAL " +- " REAL, comp + 1, r->avg, r->err);
    }

    Print(s);
  }
}
示例#13
0
static int Integrate(This *t, real *integral, real *error, real *prob)
{
  TYPEDEFREGION;

  Totals totals[NCOMP];
  real nneed, weight;
  count dim, comp, iter, pass = 0, err, iregion;
  number nwant, nmin = INT_MAX;
  int fail;

  if( VERBOSE > 1 ) {
    char s[512];
    sprintf(s, "Divonne 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"
      "  key1 %d\n  key2 %d\n  key3 %d\n  maxpass " COUNT "\n"
      "  border " REAL "\n  maxchisq " REAL "\n  mindeviation " REAL "\n"
      "  ngiven " NUMBER "\n  nextra " NUMBER,
      t->ndim, t->ncomp,
      t->epsrel, t->epsabs,
      t->flags, t->seed,
      t->mineval, t->maxeval,
      t->key1, t->key2, t->key3, t->maxpass,
      t->border.lower, t->maxchisq, t->mindeviation,
      t->ngiven, t->nextra);
    Print(s);
  }

  if( BadComponent(t) ) return -2;
  if( BadDimension(t, t->key1) ||
      BadDimension(t, t->key2) ||   
      ((t->key3 & -2) && BadDimension(t, t->key3)) ) return -1;

  t->neval_opt = t->neval_cut = 0;

  t->size = CHUNKSIZE;
  MemAlloc(t->voidregion, t->size*sizeof(Region));
  for( dim = 0; dim < t->ndim; ++dim ) {
    Bounds *b = &RegionPtr(0)->bounds[dim];
    b->lower = 0;
    b->upper = 1;
  }

  RuleIni(&t->rule7);
  RuleIni(&t->rule9);
  RuleIni(&t->rule11);
  RuleIni(&t->rule13);
  SamplesIni(&t->samples[0]);
  SamplesIni(&t->samples[1]);
  SamplesIni(&t->samples[2]);

  if( (fail = setjmp(t->abort)) ) goto abort;

  t->epsabs = Max(t->epsabs, NOTZERO);

  /* Step 1: partition the integration region */

  if( VERBOSE ) Print("Partitioning phase:");

  if( IsSobol(t->key1) || IsSobol(t->key2) || IsSobol(t->key3) )
    IniRandom(t);

  SamplesLookup(t, &t->samples[0], t->key1,
    (number)47, (number)INT_MAX, (number)0);
  SamplesAlloc(t, &t->samples[0]);

  t->totals = totals;
  Zap(totals);
  t->phase = 1;

  Explore(t, 0, &t->samples[0], INIDEPTH, 1);

  for( iter = 1; ; ++iter ) {
    Totals *maxtot;
    count valid;

    for( comp = 0; comp < t->ncomp; ++comp ) {
      Totals *tot = &totals[comp];
      tot->avg = tot->spreadsq = 0;
      tot->spread = tot->secondspread = -INFTY;
    }

    for( iregion = 0; iregion < t->nregions; ++iregion ) {
      Region *region = RegionPtr(iregion);
      for( comp = 0; comp < t->ncomp; ++comp ) {
        cResult *r = &region->result[comp];
        Totals *tot = &totals[comp];
        tot->avg += r->avg;
        tot->spreadsq += Sq(r->spread);
        if( r->spread > tot->spread ) {
          tot->secondspread = tot->spread;
          tot->spread = r->spread;
          tot->iregion = iregion;
        }
        else if( r->spread > tot->secondspread )
          tot->secondspread = r->spread;
      }
    }

    maxtot = totals;
    valid = 0;
    for( comp = 0; comp < t->ncomp; ++comp ) {
      Totals *tot = &totals[comp];
      integral[comp] = tot->avg;
      valid += tot->avg == tot->avg;
      if( tot->spreadsq > maxtot->spreadsq ) maxtot = tot;
      tot->spread = sqrt(tot->spreadsq);
      error[comp] = tot->spread*t->samples[0].weight;
    }

    if( VERBOSE ) {
      char s[128 + 64*NCOMP], *p = s;

      p += sprintf(p, "\n"
        "Iteration " COUNT " (pass " COUNT "):  " COUNT " regions\n"
        NUMBER7 " integrand evaluations so far,\n"
        NUMBER7 " in optimizing regions,\n"
        NUMBER7 " in finding cuts",
        iter, pass, t->nregions, t->neval, t->neval_opt, t->neval_cut);

      for( comp = 0; comp < t->ncomp; ++comp )
        p += sprintf(p, "\n[" COUNT "] "
          REAL " +- " REAL,
          comp + 1, integral[comp], error[comp]);

      Print(s);
    }

    if( valid == 0 ) goto abort;	/* all NaNs */

    if( t->neval > t->maxeval ) break;

    nneed = maxtot->spread/MaxErr(maxtot->avg);
    if( nneed < MAXPRIME ) {
      cnumber n = t->neval + t->nregions*(number)ceil(nneed);
      if( n < nmin ) {
        nmin = n;
        pass = 0;
      }
      else if( ++pass > t->maxpass && n >= t->mineval ) break;
    }

    Split(t, maxtot->iregion, DEPTH);
  }

  /* Step 2: do a "full" integration on each region */

/* nneed = t->samples[0].neff + 1; */
  nneed = 2*t->samples[0].neff;
  for( comp = 0; comp < t->ncomp; ++comp ) {
    Totals *tot = &totals[comp];
    creal maxerr = MaxErr(tot->avg);
    tot->nneed = tot->spread/maxerr;
    nneed = Max(nneed, tot->nneed);
    tot->maxerrsq = Sq(maxerr);
    tot->mindevsq = tot->maxerrsq*Sq(t->mindeviation);
  }
  nwant = (number)Min(ceil(nneed), MARKMASK/40.);

  err = SamplesLookup(t, &t->samples[1], t->key2, nwant,
    (t->maxeval - t->neval)/t->nregions + 1, t->samples[0].n + 1);

  /* the number of points needed to reach the desired accuracy */
  fail = Unmark(err)*t->nregions;

  if( Marked(err) ) {
    if( VERBOSE ) Print("\nNot enough samples left for main integration.");
    for( comp = 0; comp < t->ncomp; ++comp )
      prob[comp] = -999;
    weight = t->samples[0].weight;
  }
  else {
    bool can_adjust = (t->key3 == 1 && t->samples[1].sampler != SampleRule &&
      (t->key2 < 0 || t->samples[1].neff < MAXPRIME));
    count df, nlimit;

    SamplesAlloc(t, &t->samples[1]);

    if( VERBOSE ) {
      char s[128];
      sprintf(s, "\nMain integration on " COUNT
        " regions with " NUMBER " samples per region.",
        t->nregions, t->samples[1].neff);
      Print(s);
    }

    ResClear(integral);
    ResClear(error);
    ResClear(prob);

    nlimit = t->maxeval - t->nregions*t->samples[1].n;
    df = 0;

    for( iregion = 0; iregion < t->nregions; ++iregion ) {
      Region *region = RegionPtr(iregion);
      char s[64*NDIM + 256*NCOMP], *p = s;
      int todo;

refine:
      t->phase = 2;
      t->samples[1].sampler(t, &t->samples[1], region->bounds, region->vol);

      if( can_adjust )
        for( comp = 0; comp < t->ncomp; ++comp )
          totals[comp].spreadsq -= Sq(region->result[comp].spread);

      nlimit += t->samples[1].n;
      todo = 0;

      for( comp = 0; comp < t->ncomp; ++comp ) {
        cResult *r = &region->result[comp];
        Totals *tot = &totals[comp];

        t->samples[0].avg[comp] = r->avg;
        t->samples[0].err[comp] = r->err;

        if( t->neval < nlimit ) {
          creal avg2 = t->samples[1].avg[comp];
          creal err2 = t->samples[1].err[comp];
          creal diffsq = Sq(avg2 - r->avg);

#define Var(s) Sq((s.err[comp] == 0) ? r->spread*s.weight : s.err[comp])

          if( err2*tot->nneed > r->spread ||
              diffsq > Max(t->maxchisq*(Var(t->samples[0]) + Var(t->samples[1])),
                           EPS*Sq(avg2)) ) {
            if( t->key3 && diffsq > tot->mindevsq ) {
              if( t->key3 == 1 ) {
                ccount xregion = t->nregions;

                if( VERBOSE > 2 ) Print("\nSplit");

                t->phase = 1;
                Explore(t, iregion, &t->samples[1], POSTDEPTH, 2);

                if( can_adjust ) {
                  number nnew;
                  count ireg, xreg;

                  for( ireg = iregion, xreg = xregion;
                       ireg < t->nregions; ireg = xreg++ ) {
                    cResult *result = RegionPtr(ireg)->result;
                    count c;
                    for( c = 0; c < t->ncomp; ++c )
                      totals[c].spreadsq += Sq(result[c].spread);
                  }

                  nnew = (tot->spreadsq/Sq(MARKMASK) > tot->maxerrsq) ?
                    MARKMASK :
                    (number)ceil(sqrt(tot->spreadsq/tot->maxerrsq));
                  if( nnew > nwant + nwant/64 ) {
                    ccount err = SamplesLookup(t, &t->samples[1], t->key2, nnew,
                      (t->maxeval - t->neval)/t->nregions + 1, t->samples[1].n);
                    fail += Unmark(err)*t->nregions;
                    nwant = nnew;
                    SamplesFree(&t->samples[1]);
                    SamplesAlloc(t, &t->samples[1]);

                    if( t->key2 > 0 && t->samples[1].neff >= MAXPRIME )
                      can_adjust = false;

                    if( VERBOSE > 2 ) {
                      char s[128];
                      sprintf(s, "Sampling remaining " COUNT
                        " regions with " NUMBER " points per region.",
                        t->nregions, t->samples[1].neff);
                      Print(s);
                    }
                  }
                }

                goto refine;
              }
              todo |= 3;
            }
            todo |= 1;
          }
        }
      }

      if( can_adjust ) {
        for( comp = 0; comp < t->ncomp; ++comp )
          totals[comp].maxerrsq -=
            Sq(region->result[comp].spread*t->samples[1].weight);
      }

      switch( todo ) {
      case 1:	/* get spread right */
        Explore(t, iregion, &t->samples[1], 0, 2);
        break;

      case 3:	/* sample region again with more points */
        if( SamplesIniQ(&t->samples[2]) ) {
          SamplesLookup(t, &t->samples[2], t->key3,
            nwant, (number)INT_MAX, (number)0);
          SamplesAlloc(t, &t->samples[2]);
        }
        t->phase = 3;
        t->samples[2].sampler(t, &t->samples[2], region->bounds, region->vol);
        Explore(t, iregion, &t->samples[2], 0, 2);
        ++region->depth;	/* misused for df here */
        ++df;
      }

      ++region->depth;	/* misused for df here */

      if( VERBOSE > 2 ) {
        for( dim = 0; dim < t->ndim; ++dim ) {
          cBounds *b = &region->bounds[dim];
          p += sprintf(p,
            (dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
                         "\n       (" REALF ") - (" REALF ")",
            b->lower, b->upper);
        }
      }

      for( comp = 0; comp < t->ncomp; ++comp ) {
        Result *r = &region->result[comp];

        creal x1 = t->samples[0].avg[comp];
        creal s1 = Var(t->samples[0]);
        creal x2 = t->samples[1].avg[comp];
        creal s2 = Var(t->samples[1]);
        creal r2 = (s1 == 0) ? Sq(t->samples[1].neff*t->samples[0].weight) : s2/s1;

        real norm = 1 + r2;
        real avg = x2 + r2*x1;
        real sigsq = s2;
        real chisq = Sq(x2 - x1);
        real chiden = s1 + s2;

        if( todo == 3 ) {
          creal x3 = t->samples[2].avg[comp];
          creal s3 = Var(t->samples[2]);
          creal r3 = (s2 == 0) ? Sq(t->samples[2].neff*t->samples[1].weight) : s3/s2;

          norm = 1 + r3*norm;
          avg = x3 + r3*avg;
          sigsq = s3;
          chisq = s1*Sq(x3 - x2) + s2*Sq(x3 - x1) + s3*chisq;
          chiden = s1*s2 + s3*chiden;
        }

        avg = LAST ? r->avg : (sigsq *= norm = 1/norm, avg*norm);
        if( chisq > EPS ) chisq /= Max(chiden, NOTZERO);

#define Out(s) s.avg[comp], r->spread*s.weight, s.err[comp]

        if( VERBOSE > 2 ) {
          p += sprintf(p, "\n[" COUNT "] "
            REAL " +- " REAL "(" REAL ")\n    "
            REAL " +- " REAL "(" REAL ")",
            comp + 1, Out(t->samples[0]), Out(t->samples[1]));
          if( todo == 3 ) p += sprintf(p, "\n    "
            REAL " +- " REAL "(" REAL ")",
            Out(t->samples[2]));
          p += sprintf(p, "  \tchisq " REAL, chisq);
        }

        integral[comp] += avg;
        error[comp] += sigsq;
        prob[comp] += chisq;

        r->avg = avg;
        r->spread = sqrt(sigsq);
        r->chisq = chisq;
      }

      if( VERBOSE > 2 ) Print(s);
    }

    for( comp = 0; comp < t->ncomp; ++comp )
      error[comp] = sqrt(error[comp]);

    df += t->nregions;

    if( VERBOSE > 2 ) {
      char s[16 + 128*NCOMP], *p = s;

      p += sprintf(p, "\nTotals:");

      for( comp = 0; comp < t->ncomp; ++comp )
        p += sprintf(p, "\n[" COUNT "] "
          REAL " +- " REAL "  \tchisq " REAL " (" COUNT " df)",
          comp + 1, integral[comp], error[comp], prob[comp], df);

      Print(s);
    }

    for( comp = 0; comp < t->ncomp; ++comp )
      prob[comp] = ChiSquare(prob[comp], df);

    weight = 1;
  }

#ifdef MLVERSION
  if( REGIONS ) {
    MLPutFunction(stdlink, "List", 2);
    MLPutFunction(stdlink, "List", t->nregions);
    for( iregion = 0; iregion < t->nregions; ++iregion ) {
      Region *region = RegionPtr(iregion);
      cBounds *b = region->bounds;
      real lower[NDIM], upper[NDIM];

      for( dim = 0; dim < t->ndim; ++dim ) {
        lower[dim] = b[dim].lower;
        upper[dim] = b[dim].upper;
      }

      MLPutFunction(stdlink, "Cuba`Divonne`region", 4);

      MLPutRealList(stdlink, lower, t->ndim);
      MLPutRealList(stdlink, upper, t->ndim);

      MLPutFunction(stdlink, "List", t->ncomp);
      for( comp = 0; comp < t->ncomp; ++comp ) {
        cResult *r = &region->result[comp];
        real res[] = {r->avg, r->spread*weight, r->chisq};
        MLPutRealList(stdlink, res, Elements(res));
      }

      MLPutInteger(stdlink, region->depth);  /* misused for df */
    }
  }
#endif

abort:
  SamplesFree(&t->samples[2]);
  SamplesFree(&t->samples[1]);
  SamplesFree(&t->samples[0]);
  RuleFree(&t->rule13);
  RuleFree(&t->rule11);
  RuleFree(&t->rule9);
  RuleFree(&t->rule7);

  free(t->voidregion);

  return fail;
}
示例#14
0
static int Integrate(creal epsrel, creal epsabs,
  cint flags, cnumber mineval, cnumber maxeval,
  int key1, int key2, int key3, ccount maxpass, 
  creal maxchisq, creal mindeviation,
  real *integral, real *error, real *prob)
{
  TYPEDEFREGION;

  Region anchor, *region;
  Totals totals[NCOMP];
  real nneed, weight;
  count dim, comp, iter, nregions, pass = 0, err;
  number nwant, nmin = INT_MAX;
  int fail = -1;

  if( VERBOSE > 1 ) {
    char s[512];
    sprintf(s, "Divonne input parameters:\n"
      "  ndim " COUNT "\n  ncomp " COUNT "\n"
      "  epsrel " REAL "\n  epsabs " REAL "\n"
      "  flags %d\n  mineval " NUMBER "\n  maxeval " NUMBER "\n"
      "  key1 %d\n  key2 %d\n  key3 %d\n  maxpass " COUNT "\n"
      "  border " REAL "\n  maxchisq " REAL "\n  mindeviation " REAL "\n"
      "  ngiven " NUMBER "\n  nextra " NUMBER "\n",
      ndim_, ncomp_,
      epsrel, epsabs,
      flags, mineval, maxeval,
      key1, key2, key3, maxpass,
      border_.lower, maxchisq, mindeviation,
      ngiven_, nextra_);
    Print(s);
  }

  anchor.next = NULL;
  for( dim = 0; dim < ndim_; ++dim ) {
    Bounds *b = &anchor.bounds[dim];
    b->lower = 0;
    b->upper = 1;
  }

  RuleIni(&rule7_);
  RuleIni(&rule9_);
  RuleIni(&rule11_);
  RuleIni(&rule13_);
  SamplesIni(&samples_[0]);
  SamplesIni(&samples_[1]);
  SamplesIni(&samples_[2]);

#ifdef MLVERSION
  if( setjmp(abort_) ) goto abort;
#endif

  /* Step 1: partition the integration region */

  if( VERBOSE ) Print("Partitioning phase:");

  if( IsSobol(key1) || IsSobol(key2) || IsSobol(key3) )
    IniRandom(2*maxeval, flags);

  SamplesLookup(&samples_[0], key1,
    (number)47, (number)INT_MAX, (number)0);
  SamplesAlloc(&samples_[0]);

  totals_ = totals;
  Zap(totals);
  phase_ = 1;

  Explore(&anchor, &samples_[0], INIDEPTH, 1);

  for( iter = 1; ; ++iter ) {
    Totals *maxtot;

    for( comp = 0; comp < ncomp_; ++comp ) {
      Totals *tot = &totals[comp];
      tot->avg = tot->spreadsq = 0;
      tot->spread = tot->secondspread = -INFTY;
    }

    nregions = 0;
    for( region = anchor.next; region; region = region->next ) {
      ++nregions;
      for( comp = 0; comp < ncomp_; ++comp ) {
        cResult *r = &region->result[comp];
        Totals *tot = &totals[comp];
        tot->avg += r->avg;
        tot->spreadsq += Sq(r->spread);
        if( r->spread > tot->spread ) {
          tot->secondspread = tot->spread;
          tot->spread = r->spread;
          tot->region = region;
        }
        else if( r->spread > tot->secondspread )
          tot->secondspread = r->spread;
      }
    }

    maxtot = totals;
    for( comp = 0; comp < ncomp_; ++comp ) {
      Totals *tot = &totals[comp];
      integral[comp] = tot->avg;
      if( tot->spreadsq > maxtot->spreadsq ) maxtot = tot;
      tot->spread = sqrt(tot->spreadsq);
      error[comp] = tot->spread*samples_[0].weight;
    }

    if( VERBOSE ) {
      char s[128 + 64*NCOMP], *p = s;

      p += sprintf(p, "\n"
        "Iteration " COUNT " (pass " COUNT "):  " COUNT " regions\n"
        NUMBER7 " integrand evaluations so far,\n"
        NUMBER7 " in optimizing regions,\n"
        NUMBER7 " in finding cuts",
        iter, pass, nregions, neval_, neval_opt_, neval_cut_);

      for( comp = 0; comp < ncomp_; ++comp )
        p += sprintf(p, "\n[" COUNT "] "
          REAL " +- " REAL,
          comp + 1, integral[comp], error[comp]);

      Print(s);
    }

    if( neval_ > maxeval ) break;

    nneed = maxtot->spread/MaxErr(maxtot->avg);
    if( nneed < MAXPRIME ) {
      cnumber n = neval_ + nregions*(number)ceil(nneed);
      if( n < nmin ) {
        nmin = n;
        pass = 0;
      }
      else if( ++pass > maxpass && n >= mineval ) break;
    }

    Split(maxtot->region, DEPTH);
  }

  /* Step 2: do a "full" integration on each region */

/* nneed = samples_[0].neff + 1; */
  nneed = 2*samples_[0].neff;
  for( comp = 0; comp < ncomp_; ++comp ) {
    Totals *tot = &totals[comp];
    creal maxerr = MaxErr(tot->avg);
    tot->nneed = tot->spread/maxerr;
    nneed = Max(nneed, tot->nneed);
    tot->maxerrsq = Sq(maxerr);
    tot->mindevsq = tot->maxerrsq*Sq(mindeviation);
  }
  nwant = (number)Min(ceil(nneed), MARKMASK/40.);

  err = SamplesLookup(&samples_[1], key2, nwant,
    (maxeval - neval_)/nregions + 1, samples_[0].n + 1);

  /* the number of points needed to reach the desired accuracy */
  fail = Unmark(err)*nregions;

  if( Marked(err) ) {
    if( VERBOSE ) Print("\nNot enough samples left for main integration.");
    for( comp = 0; comp < ncomp_; ++comp )
      prob[comp] = -999;
    weight = samples_[0].weight;
    nregions_ = nregions;
  }
  else {
    bool can_adjust = (key3 == 1 && samples_[1].sampler != SampleRule &&
      (key2 < 0 || samples_[1].neff < MAXPRIME));
    count df, nlimit;

    SamplesAlloc(&samples_[1]);

    if( VERBOSE ) {
      char s[128];
      sprintf(s, "\nMain integration on " COUNT
        " regions with " NUMBER " samples per region.",
        nregions, samples_[1].neff);
      Print(s);
    }

    ResClear(integral);
    ResClear(error);
    ResClear(prob);

    nlimit = maxeval - nregions*samples_[1].n;
    df = nregions_ = 0;

    for( region = anchor.next; region; region = region->next ) {
      char s[64*NDIM + 256*NCOMP], *p = s;
      int todo;

refine:
      phase_ = 2;
      samples_[1].sampler(&samples_[1], region->bounds, region->vol);

      if( can_adjust ) {
        --nregions;
        for( comp = 0; comp < ncomp_; ++comp )
          totals[comp].spreadsq -= Sq(region->result[comp].spread);
      }

      nlimit += samples_[1].n;
      todo = 0;

      for( comp = 0; comp < ncomp_; ++comp ) {
        cResult *r = &region->result[comp];
        Totals *tot = &totals[comp];

        samples_[0].avg[comp] = r->avg;
        samples_[0].err[comp] = r->err;

        if( neval_ < nlimit ) {
          creal avg2 = samples_[1].avg[comp];
          creal err2 = samples_[1].err[comp];
          creal diffsq = Sq(avg2 - r->avg);

#define Var(s) Sq((s.err[comp] == 0) ? r->spread*s.weight : s.err[comp])

          if( err2*tot->nneed > r->spread ||
              diffsq > Max(maxchisq*(Var(samples_[0]) + Var(samples_[1])),
                           EPS*Sq(avg2)) ) {
            if( key3 && diffsq > tot->mindevsq ) {
              if( key3 == 1 ) {
                const Region *next = region->next;

                if( VERBOSE > 2 ) Print("\nSplit");

                phase_ = 1;
                Explore(region, &samples_[1], POSTDEPTH, 2);

                if( can_adjust ) {
                  number nnew;
                  Region *child;

                  for( child = region; child != next; child = child->next ) {
                    count c;
                    for( c = 0; c < ncomp_; ++c )
                      totals[c].spreadsq += Sq(child->result[c].spread);
                    ++nregions;
                  }

                  nnew = (tot->spreadsq/Sq(MARKMASK) > tot->maxerrsq) ?
                    MARKMASK :
                    (number)ceil(sqrt(tot->spreadsq/tot->maxerrsq));
                  if( nnew > nwant + nwant/64 ) {
                    ccount err = SamplesLookup(&samples_[1], key2, nnew,
                      (maxeval - neval_)/nregions + 1, samples_[1].n);
                    fail += Unmark(err)*nregions;
                    nwant = nnew;
                    SamplesFree(&samples_[1]);
                    SamplesAlloc(&samples_[1]);

                    if( key2 > 0 && samples_[1].neff >= MAXPRIME )
                      can_adjust = false;

                    if( VERBOSE > 2 ) {
                      char s[128];
                      sprintf(s, "Sampling remaining " COUNT
                        " regions with " NUMBER " points per region.",
                        nregions, samples_[1].neff);
                      Print(s);
                    }
                  }
                }

                goto refine;
              }
              todo |= 3;
            }
            todo |= 1;
          }
        }
      }

      if( can_adjust ) {
        for( comp = 0; comp < ncomp_; ++comp )
          totals[comp].maxerrsq -=
            Sq(region->result[comp].spread*samples_[1].weight);
      }

      switch( todo ) {
      case 1:	/* get spread right */
        Explore(region, &samples_[1], 0, 2);
        break;

      case 3:	/* sample region again with more points */
        if( MEM(&samples_[2]) == NULL ) {
          SamplesLookup(&samples_[2], key3,
            nwant, (number)INT_MAX, (number)0);
          SamplesAlloc(&samples_[2]);
        }
        phase_ = 3;
        samples_[2].sampler(&samples_[2], region->bounds, region->vol);
        Explore(region, &samples_[2], 0, 2);
        ++region->depth;	/* misused for df here */
        ++df;
      }

      ++region->depth;	/* misused for df here */
      ++nregions_;

      if( VERBOSE > 2 ) {
        for( dim = 0; dim < ndim_; ++dim ) {
          cBounds *b = &region->bounds[dim];
          p += sprintf(p,
            (dim == 0) ? "\nRegion (" REALF ") - (" REALF ")" :
                         "\n       (" REALF ") - (" REALF ")",
            b->lower, b->upper);
        }
      }

      for( comp = 0; comp < ncomp_; ++comp ) {
        Result *r = &region->result[comp];

        creal x1 = samples_[0].avg[comp];
        creal s1 = Var(samples_[0]);
        creal x2 = samples_[1].avg[comp];
        creal s2 = Var(samples_[1]);
        creal r2 = (s1 == 0) ? Sq(samples_[1].neff*samples_[0].weight) : s2/s1;

        real norm = 1 + r2;
        real avg = x2 + r2*x1;
        real sigsq = s2;
        real chisq = Sq(x2 - x1);
        real chiden = s1 + s2;

        if( todo == 3 ) {
          creal x3 = samples_[2].avg[comp];
          creal s3 = Var(samples_[2]);
          creal r3 = (s2 == 0) ? Sq(samples_[2].neff*samples_[1].weight) : s3/s2;

          norm = 1 + r3*norm;
          avg = x3 + r3*avg;
          sigsq = s3;
          chisq = s1*Sq(x3 - x2) + s2*Sq(x3 - x1) + s3*chisq;
          chiden = s1*s2 + s3*chiden;
        }

        avg = LAST ? r->avg : (sigsq *= norm = 1/norm, avg*norm);
        if( chisq > EPS ) chisq /= Max(chiden, NOTZERO);

#define Out(s) s.avg[comp], r->spread*s.weight, s.err[comp]

        if( VERBOSE > 2 ) {
          p += sprintf(p, "\n[" COUNT "] "
            REAL " +- " REAL "(" REAL ")\n    "
            REAL " +- " REAL "(" REAL ")",
            comp + 1, Out(samples_[0]), Out(samples_[1]));
          if( todo == 3 ) p += sprintf(p, "\n    "
            REAL " +- " REAL "(" REAL ")",
            Out(samples_[2]));
          p += sprintf(p, "  \tchisq " REAL, chisq);
        }

        integral[comp] += avg;
        error[comp] += sigsq;
        prob[comp] += chisq;

        r->avg = avg;
        r->spread = sqrt(sigsq);
        r->chisq = chisq;
      }

      if( VERBOSE > 2 ) Print(s);
    }

    for( comp = 0; comp < ncomp_; ++comp )
      error[comp] = sqrt(error[comp]);

    df += nregions_;

    if( VERBOSE > 2 ) {
      char s[16 + 128*NCOMP], *p = s;

      p += sprintf(p, "\nTotals:");

      for( comp = 0; comp < ncomp_; ++comp )
        p += sprintf(p, "\n[" COUNT "] "
          REAL " +- " REAL "  \tchisq " REAL " (" COUNT " df)",
          comp + 1, integral[comp], error[comp], prob[comp], df);

      Print(s);
    }

    for( comp = 0; comp < ncomp_; ++comp )
      prob[comp] = ChiSquare(prob[comp], df);

    weight = 1;
  }

#ifdef MLVERSION
  if( REGIONS ) {
    MLPutFunction(stdlink, "List", 2);
    MLPutFunction(stdlink, "List", nregions_);
    for( region = anchor.next; region; region = region->next ) {
      cBounds *b = region->bounds;
      real lower[NDIM], upper[NDIM];

      for( dim = 0; dim < ndim_; ++dim ) {
        lower[dim] = b[dim].lower;
        upper[dim] = b[dim].upper;
      }

      MLPutFunction(stdlink, "Cuba`Divonne`region", 4);

      MLPutRealList(stdlink, lower, ndim_);
      MLPutRealList(stdlink, upper, ndim_);

      MLPutFunction(stdlink, "List", ncomp_);
      for( comp = 0; comp < ncomp_; ++comp ) {
        cResult *r = &region->result[comp];
        real res[] = {r->avg, r->spread*weight, r->chisq};
        MLPutRealList(stdlink, res, Elements(res));
      }

      MLPutInteger(stdlink, region->depth);  /* misused for df */
    }
  }
#endif

#ifdef MLVERSION
abort:
#endif

  SamplesFree(&samples_[2]);
  SamplesFree(&samples_[1]);
  SamplesFree(&samples_[0]);
  RuleFree(&rule13_);
  RuleFree(&rule11_);
  RuleFree(&rule9_);
  RuleFree(&rule7_);

  for( region = anchor.next; region; ) {
    Region *next = region->next;
    free(region);
    region = next;
  }

  return fail;
}
示例#15
0
static void Sample(This *t, Region *region)
{
  csize_t setsize = SetSize;
  creal vol = ldexp(1., -region->div);

  real *x = t->frame, *f = x + t->rule.n*t->ndim;
  Set *first = t->rule.first, *last = t->rule.last, *s;
  Bounds *b, *B = region->bounds + t->ndim;
  Result *result = RegionResult(region), *res, *Res = result + t->ncomp;
  creal *errcoeff = t->rule.errcoeff;
  creal ratio = Sq(IndexSet(first,2)->gen[0]/
                   IndexSet(first,1)->gen[0]);

  ccount offset = 2*t->ndim*t->ncomp;
  count dim, rul, n, maxdim = 0;
  real maxrange = 0;

  for( b = region->bounds, dim = 0; b < B; ++b, ++dim ) {
    creal range = b->upper - b->lower;
    if( range > maxrange ) {
      maxrange = range;
      maxdim = dim;
    }
  }

  for( s = first; s <= last; NextSet(s) )
    if( s->n ) x = ExpandFS(t, region->bounds, s->gen, x);

  DoSample(t, t->rule.n, t->frame, f);

  for( res = result; res < Res; ++res ) {
    real sum[nrules];
    creal *f1 = f;
    creal base = *f1*2*(1 - ratio);
    real maxdiff = 0;
    count bisectdim = maxdim;

    for( dim = 0; dim < t->ndim; ++dim ) {
      creal *fp = f1 + t->ncomp;
      creal *fm = fp + t->ncomp;
      creal fourthdiff = fabs(base +
        ratio*(fp[0] + fm[0]) - (fp[offset] + fm[offset]));
      f1 = fm;
      if( fourthdiff > maxdiff ) {
        maxdiff = fourthdiff;
        bisectdim = dim;
      }
    }
    res->bisectdim = bisectdim;

    f1 = f++;
    Zap(sum);
    for( s = first; s <= last; NextSet(s) )
      for( n = s->n; n; --n ) {
        creal fun = *f1;
        f1 += t->ncomp;
        for( rul = 0; rul < nrules; ++rul )
          sum[rul] += fun*s->weight[rul];
      }

    /* Search for the null rule, in the linear space spanned by two
       successive null rules in our sequence, which gives the greatest
       error estimate among all normalized (1-norm) null rules in this
       space. */

    for( rul = 1; rul < nrules - 1; ++rul ) {
      real maxerr = 0;
      for( s = first; s <= last; NextSet(s) )
        maxerr = Max(maxerr,
          fabs(sum[rul + 1] + s->scale[rul]*sum[rul])*s->norm[rul]);
      sum[rul] = maxerr;
    }

    res->avg = vol*sum[0];
    res->err = vol*(
      (errcoeff[0]*sum[1] <= sum[2] && errcoeff[0]*sum[2] <= sum[3]) ?
        errcoeff[1]*sum[1] :
        errcoeff[2]*Max(Max(sum[1], sum[2]), sum[3]) );
  }

  if( VERBOSE > 2 ) {
    Vector(char, out, 64*NDIM + 128*NCOMP);
    char *oe = out;
    count comp;
    cchar *msg = "\nRegion (" REALF ") - (" REALF ")";

    for( b = region->bounds; b < B; ++b ) {
      oe += sprintf(oe, msg, b->lower, b->upper);
      msg = "\n       (" REALF ") - (" REALF ")";
    }

    for( res = result, comp = 0; res < Res; ++res )
      oe += sprintf(oe, "\n[" COUNT "] "
        REAL " +- " REAL, ++comp, res->avg, res->err);

    Print(out);
  }