예제 #1
0
Extern void EXPORT(Divonne)(ccount ndim, ccount ncomp,
  Integrand integrand,
  creal epsrel, creal epsabs,
  cint flags, cnumber mineval, cnumber maxeval,
  cint key1, cint key2, cint key3, ccount maxpass,
  creal border, creal maxchisq, creal mindeviation,
  cnumber ngiven, ccount ldxgiven, real *xgiven,
  cnumber nextra, PeakFinder peakfinder,
  int *pnregions, number *pneval, int *pfail,
  real *integral, real *error, real *prob)
{
  ndim_ = ndim;
  ncomp_ = ncomp;

  if( BadComponent(ncomp) ||
      BadDimension(ndim, flags, key1) ||
      BadDimension(ndim, flags, key2) ||
      ((key3 & -2) && BadDimension(ndim, flags, key3)) ) *pfail = -1;
  else {
    neval_ = neval_opt_ = neval_cut_ = 0;
    integrand_ = integrand;
    peakfinder_ = peakfinder;
    border_.lower = border;
    border_.upper = 1 - border_.lower;
    ngiven_ = ngiven;
    xgiven_ = NULL;
    ldxgiven_ = IMax(ldxgiven, ndim_);
    nextra_ = nextra;

    if( ngiven + nextra ) {
      cnumber nxgiven = ngiven*ldxgiven;
      cnumber nxextra = nextra*ldxgiven;
      cnumber nfgiven = ngiven*ncomp;
      cnumber nfextra = nextra*ncomp;

      Alloc(xgiven_, nxgiven + nxextra + nfgiven + nfextra);
      xextra_ = xgiven_ + nxgiven;
      fgiven_ = xextra_ + nxextra;
      fextra_ = fgiven_ + nfgiven;

      if( nxgiven ) {
        phase_ = 0;
        Copy(xgiven_, xgiven, nxgiven);
        DoSample(ngiven_, ldxgiven_, xgiven_, fgiven_);
      }
    }

    *pfail = Integrate(epsrel, Max(epsabs, NOTZERO),
      flags, mineval, maxeval, key1, key2, key3, maxpass,
      maxchisq, mindeviation,
      integral, error, prob);
    *pnregions = nregions_;
    *pneval = neval_;

    if( xgiven_ ) free(xgiven_);
  }
}
예제 #2
0
void Divonne(ccount ndim, ccount ncomp, Integrand integrand,
             creal epsrel, creal epsabs,
             cint flags, ccount mineval, ccount maxeval,
             cint key1, cint key2, cint key3, ccount maxpass,
             creal border, creal maxchisq, creal mindeviation,
             ccount ngiven, ccount ldxgiven, real *xgiven,
             ccount nextra, PeakFinder peakfinder,
             int *pnregions, int *pneval, int *pfail,
             real *integral, real *error, real *prob)
{
    ndim_ = ndim;
    ncomp_ = ncomp;

    if( ndim < MINDIM || ndim > MAXDIM ) *pfail = -1;
    else {
        neval_ = neval_opt_ = neval_cut_ = 0;
        integrand_ = integrand;
        peakfinder_ = peakfinder;
        border_.lower = border;
        border_.upper = 1 - border_.lower;
        ngiven_ = ngiven;
        xgiven_ = NULL;
        ldxgiven_ = IMax(ldxgiven, ndim_);
        nextra_ = nextra;

        if( ngiven + nextra ) {
            ccount nxgiven = ngiven*ldxgiven;
            ccount nxextra = nextra*ldxgiven;
            ccount nfgiven = ngiven*ncomp;
            ccount nfextra = nextra*ncomp;

            Allocate(xgiven_, nxgiven + nxextra + nfgiven + nfextra);
            xextra_ = xgiven_ + nxgiven;
            fgiven_ = xextra_ + nxextra;
            fextra_ = fgiven_ + nfgiven;

            if( nxgiven ) {
                phase_ = 0;
                Copy(xgiven_, xgiven, nxgiven);
                DoSample(ngiven_, ldxgiven_, xgiven_, fgiven_);
            }
        }

        *pfail = Integrate(epsrel, Max(epsabs, NOTZERO),
                           flags, mineval, maxeval, key1, key2, key3, maxpass,
                           maxchisq, mindeviation,
                           integral, error, prob);
        *pnregions = nregions_;
        *pneval = neval_;

        if( xgiven_ ) free(xgiven_);
    }
}
예제 #3
0
파일: parallel.c 프로젝트: JNicL/MPIProject
static inline void newcore(subroutine foo, const int flags)
{
  int fd[2];
  pid_t pid;
  int core = nlaunched++;

  assert(
    socketpair(AF_LOCAL, SOCK_STREAM, 0, fd) != -1 &&
    (pid = fork()) != -1 );

  if( pid ) {
    MASTER("forked core %d pid %d pipe %d(master) -> %d(worker) seq %llx",
      core, pid, fd[0], fd[1], mem_seq);
    close(fd[1]);
    child[core].fd = fd[0];
    child[core].seq = mem_seq;
    FD_SET(fd[0], &children);
    fdmax = IMax(fd[0], fdmax);
    return;
  }

  close(fd[0]);

  for( ; ; ) {
    RealType res[NCOMP];
    seq_t seq = mem_seq;

    res[0] = res[1] = 0;
    foo(res, &flags);
    WORKER(core, "writing result(%ld)", sizeof res);
    writesock(fd[1], res, sizeof res);

    WORKER(core, "reading mem_hel(%p#%ld)", mem.h, mem.he - mem.h);
    if( !readsock(fd[1], mem.h, mem.he - mem.h) ) exit(0);
    WORKER(core, "seq %llx  new %llx", seq, mem_seq);
    seq ^= mem_seq;
    if( SEQ_ANGLE(seq) ) {
      WORKER(core, "reading mem_angle(%p#%ld+%p#%ld)",
        mem.v, mem.ve - mem.v, mem.a, mem.ae - mem.a);
      readsock(fd[1], mem.v, mem.ve - mem.v);
      readsock(fd[1], mem.a, mem.ae - mem.a);
      restorecache_();
    }
    if( SEQ_S(seq) ) {
      WORKER(core, "reading mem_s(%p#%ld)", mem.s, mem.se - mem.s);
      readsock(fd[1], mem.s, mem.se - mem.s);
      clearcache_();
    }
    seq = mem_seq;
  }
}
예제 #4
0
static inline void AllocGiven(This *t, creal *xgiven)
{
  if( t->ngiven | t->nextra ) {
    cnumber nxgiven = t->ngiven*(t->ldxgiven = IMax(t->ldxgiven, t->ndim));
    cnumber nxextra = t->nextra*t->ldxgiven;
    cnumber nfgiven = t->ngiven*t->ncomp;
    cnumber nfextra = t->nextra*t->ncomp;

    Alloc(t->xgiven, nxgiven + nxextra + nfgiven + nfextra);
    t->xextra = t->xgiven + nxgiven;
    t->fgiven = t->xextra + nxextra;
    t->fextra = t->fgiven + nfgiven;

    if( nxgiven ) {
      t->phase = 0;
      Copy(t->xgiven, xgiven, nxgiven);
      DoSample(t, t->ngiven, t->ldxgiven, t->xgiven, t->fgiven);
    }
  }
}
예제 #5
0
static void Iterate(This *t, count iregion, cint depth, cint isamples,
  Totals *totals)
{
  csize_t regionsize = RegionSize;
  Region *parent, *region;
  typedef struct {
    real avg, err, spread, spreadsq;
  } Corr;
  Vector(Corr, corr, NCOMP);
  Corr *c, *C = corr + t->ncomp;
  Result *res;
  count ireg, mreg = iregion;
  count comp, maxsplit;
  int last, idest, isrc;

  region = RegionPtr(iregion);
  region->depth = depth;
  region->next = -iregion - 1;
  if( isamples < 0 ) Split(t, iregion);
  else {
    region->isamples = isamples;
    ExploreSerial(t, iregion);
  }

  ireg = iregion + RegionPtr(iregion)->next;

  do {
    region = RegionPtr(ireg);
    if( region->depth > 0 ) {
      --region->depth;
FORK_ONLY(more:)
      ireg = Explore(t, ireg);
      if( ireg == -1 ) return;
      region = RegionPtr(ireg);
    }
    if( region->depth < 0 ) mreg = IMax(mreg, ireg);
    ireg += region->next;
  } while( ireg > 0 );
예제 #6
0
static int Integrate(This *t, real *integral, real *error, real *prob)
{
  StateDecl;
  csize_t statesize = sizeof(State) + NCOMP*sizeof(Result);
  Sized(State, state, statesize);
  Array(Var, var, NDIM, 2);
  Vector(char, out, 128*NCOMP + 256);

  Region *anchor = NULL, *region = NULL;
  Result *tot, *Tot = state->totals + t->ncomp;
  Result *res, *resL, *resR;
  Bounds *b, *B;
  cnumber minsamples = IMax(t->nmin, MINSAMPLES);
  count dim, comp;
  int fail;

  if( VERBOSE > 1 ) {
    sprintf(out, "Suave input parameters:\n"
      "  ndim " COUNT "\n  ncomp " COUNT "\n"
      ML_NOT("  nvec " NUMBER "\n")
      "  epsrel " REAL "\n  epsabs " REAL "\n"
      "  flags %d\n  seed %d\n"
      "  mineval " NUMBER "\n  maxeval " NUMBER "\n"
      "  nnew " NUMBER "\n  nmin " NUMBER "\n"
      "  flatness " REAL "\n"
      "  statefile \"%s\"",
      t->ndim, t->ncomp,
      ML_NOT(t->nvec,)
      SHOW(t->epsrel), SHOW(t->epsabs),
      t->flags, t->seed,
      t->mineval, t->maxeval,
      t->nnew, t->nmin,
      SHOW(t->flatness),
      t->statefile);
    Print(out);
  }
예제 #7
0
static int Integrate(This *t, real *integral, real *error, real *prob)
{
  TYPEDEFREGION;
  typedef struct pool {
    struct pool *next;
    Region region[POOLSIZE];
  } Pool;

  count dim, comp, ncur, ipool, npool;
  int fail;
  Totals totals[NCOMP];
  Pool *cur = NULL, *pool;
  Region *region;

  if( VERBOSE > 1 ) {
    char s[256];
    sprintf(s, "Cuhre input parameters:\n"
      "  ndim " COUNT "\n  ncomp " COUNT "\n"
      "  epsrel " REAL "\n  epsabs " REAL "\n"
      "  flags %d\n  mineval " NUMBER "\n  maxeval " NUMBER "\n"
      "  key " COUNT,
      t->ndim, t->ncomp,
      t->epsrel, t->epsabs,
      t->flags, t->mineval, t->maxeval,
      t->key);
    Print(s);
  }

  if( BadComponent(t) ) return -2;
  if( BadDimension(t) ) return -1;

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

  RuleAlloc(t);
  t->mineval = IMax(t->mineval, t->rule.n + 1);
  FrameAlloc(t, ShmRm(t));
  ForkCores(t);

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

  Alloc(cur, 1);
  cur->next = NULL;
  ncur = 1;

  region = cur->region;
  region->div = 0;
  for( dim = 0; dim < t->ndim; ++dim ) {
    Bounds *b = &region->bounds[dim];
    b->lower = 0;
    b->upper = 1;
  }

  Sample(t, region);

  for( comp = 0; comp < t->ncomp; ++comp ) {
    Totals *tot = &totals[comp];
    Result *r = &region->result[comp];
    tot->avg = tot->lastavg = tot->guess = r->avg;
    tot->err = tot->lasterr = r->err;
    tot->weightsum = 1/Max(Sq(r->err), NOTZERO);
    tot->avgsum = tot->weightsum*r->avg;
    tot->chisq = tot->chisqsum = tot->chisum = 0;
  }

  for( t->nregions = 1; ; ++t->nregions ) {
    count maxcomp, bisectdim;
    real maxratio, maxerr;
    Result result[NCOMP];
    Region *regionL, *regionR;
    Bounds *bL, *bR;

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

      p += sprintf(p, "\n"
        "Iteration " COUNT ":  " NUMBER " integrand evaluations so far",
        t->nregions, t->neval);

      for( comp = 0; comp < t->ncomp; ++comp ) {
        cTotals *tot = &totals[comp];
        p += sprintf(p, "\n[" COUNT "] "
          REAL " +- " REAL "  \tchisq " REAL " (" COUNT " df)",
          comp + 1, tot->avg, tot->err, tot->chisq, t->nregions - 1);
      }

      Print(s);
    }

    maxratio = -INFTY;
    maxcomp = 0;
    for( comp = 0; comp < t->ncomp; ++comp ) {
      creal ratio = totals[comp].err/MaxErr(totals[comp].avg);
      if( ratio > maxratio ) {
        maxratio = ratio;
        maxcomp = comp;
      }
    }

    if( maxratio <= 1 && t->neval >= t->mineval ) break;

    if( t->neval >= t->maxeval ) {
      fail = 1;
      break;
    }

    maxerr = -INFTY;
    regionL = cur->region;
    npool = ncur;
    for( pool = cur; pool; npool = POOLSIZE, pool = pool->next )
      for( ipool = 0; ipool < npool; ++ipool ) {
        Region *region = &pool->region[ipool];
        creal err = region->result[maxcomp].err;
        if( err > maxerr ) {
          maxerr = err;
          regionL = region;
        }
      }

    if( ncur == POOLSIZE ) {
      Pool *prev = cur;
      Alloc(cur, 1);
      cur->next = prev;
      ncur = 0;
    }
    regionR = &cur->region[ncur++];

    regionR->div = ++regionL->div;
    FCopy(result, regionL->result);
    XCopy(regionR->bounds, regionL->bounds);

    bisectdim = result[maxcomp].bisectdim;
    bL = &regionL->bounds[bisectdim];
    bR = &regionR->bounds[bisectdim];
    bL->upper = bR->lower = .5*(bL->upper + bL->lower);

    Sample(t, regionL);
    Sample(t, regionR);

    for( comp = 0; comp < t->ncomp; ++comp ) {
      cResult *r = &result[comp];
      Result *rL = &regionL->result[comp];
      Result *rR = &regionR->result[comp];
      Totals *tot = &totals[comp];
      real diff, err, w, avg, sigsq;

      tot->lastavg += diff = rL->avg + rR->avg - r->avg;

      diff = fabs(.25*diff);
      err = rL->err + rR->err;
      if( err > 0 ) {
        creal c = 1 + 2*diff/err;
        rL->err *= c;
        rR->err *= c;
      }
      rL->err += diff;
      rR->err += diff;
      tot->lasterr += rL->err + rR->err - r->err;

      tot->weightsum += w = 1/Max(Sq(tot->lasterr), NOTZERO);
      sigsq = 1/tot->weightsum;
      tot->avgsum += w*tot->lastavg;
      avg = sigsq*tot->avgsum;
      tot->chisum += w *= tot->lastavg - tot->guess;
      tot->chisqsum += w*tot->lastavg;
      tot->chisq = tot->chisqsum - avg*tot->chisum;

      if( LAST ) {
        tot->avg = tot->lastavg;
        tot->err = tot->lasterr;
      }
      else {
        tot->avg = avg;
        tot->err = sqrt(sigsq);
      }
    }
  }

  for( comp = 0; comp < t->ncomp; ++comp ) {
    cTotals *tot = &totals[comp];
    integral[comp] = tot->avg;
    error[comp] = tot->err;
    prob[comp] = ChiSquare(tot->chisq, t->nregions - 1);
  }

#ifdef MLVERSION
  if( REGIONS ) {
    MLPutFunction(stdlink, "List", 2);
    MLPutFunction(stdlink, "List", t->nregions);

    npool = ncur;
    for( pool = cur; pool; npool = POOLSIZE, pool = pool->next )
      for( ipool = 0; ipool < npool; ++ipool ) {
        Region const *region = &pool->region[ipool];
        real lower[NDIM], upper[NDIM];

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

        MLPutFunction(stdlink, "Cuba`Cuhre`region", 3);
        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->err};
          MLPutRealList(stdlink, res, Elements(res));
        }
      }
  }
#endif

abort:
  while( (pool = cur) ) {
    cur = cur->next;
    free(pool);
  }

  WaitCores(t);
  FrameFree(t);
  RuleFree(t);

  return fail;
}
예제 #8
0
파일: Fork.c 프로젝트: NumCosmo/NumCosmo
Extern void SUFFIX(cubafork)(Spin **pspin)
{
  char out[128];
  int cores, core;
  fdpid *pfp;
  Spin *spin;

  VerboseInit();

  EnvInit(cubaworkers_.paccel, "CUBAACCELMAX", 1000);
  EnvInit(cubaworkers_.pcores, "CUBACORESMAX", 10000);
  EnvInit(cubaworkers_.naccel, "CUBAACCEL", 0);
  EnvInit(cubaworkers_.ncores, "CUBACORES", -sysconf(_SC_NPROCESSORS_ONLN));

#ifdef HAVE_GETLOADAVG
  if( cubaworkers_.ncores < 0 ) {
    static int load = uninitialized;
    if( load == uninitialized ) {
      double loadavg;
      getloadavg(&loadavg, 1);
      load = floor(loadavg);
    }
    cubaworkers_.ncores = IMax(-cubaworkers_.ncores - load, 0);
  }
#else
  cubaworkers_.ncores = abs(cubaworkers_.ncores);
#endif

  cores = cubaworkers_.naccel + cubaworkers_.ncores;
  if( cores < MINCORES ) {
    *pspin = NULL;
    return;
  }

  if( cubaverb_ ) {
    sprintf(out, "using %d cores %d accelerators via "
#ifdef HAVE_SHMGET
      "shared memory",
#else
      "pipes",
#endif
      cubaworkers_.ncores, cubaworkers_.naccel);
    Print(out);
  }

  fflush(NULL);		/* make sure all buffers are flushed,
			   or else buffered content will be written
			   out multiply, at each child's exit(0) */

  MemAlloc(spin, sizeof *spin + cores*sizeof *spin->fp);
  spin->spec = cubaworkers_;
  pfp = spin->fp;
  for( core = -spin->spec.naccel; core < spin->spec.ncores; ++core ) {
    int fd[2];
    pid_t pid;
    assert(
      socketpair(AF_LOCAL, SOCK_STREAM, 0, fd) != -1 &&
      (pid = fork()) != -1 );
    if( pid == 0 ) {
      close(fd[0]);
      free(spin);
      Child(fd[1], core);
      exit(0);
    }
    MASTER("forked pid %d pipe %d(master) -> %d(worker)",
      pid, fd[0], fd[1]);
    close(fd[1]);
    pfp->fd = fd[0];
    pfp->pid = pid;
    ++pfp;
  }

  *pspin = spin;
}
예제 #9
0
static int Integrate(This *t, real *integral, real *error, real *prob)
{
  TYPEDEFREGION;

  count dim, comp, df;
  int fail;
  Result totals[NCOMP];
  Region *anchor = NULL, *region = NULL;

  if( VERBOSE > 1 ) {
    char s[256];
    sprintf(s, "Suave 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"
      "  nnew " NUMBER "\n  flatness " REAL,
      t->ndim, t->ncomp,
      t->epsrel, t->epsabs,
      t->flags, t->seed,
      t->mineval, t->maxeval,
      t->nnew, t->flatness);
    Print(s);
  }

  if( BadComponent(t) ) return -2;
  if( BadDimension(t) ) return -1;

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

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

  RegionAlloc(t, anchor, t->nnew, t->nnew);
  anchor->next = NULL;
  anchor->div = 0;

  for( dim = 0; dim < t->ndim; ++dim ) {
    Bounds *b = &anchor->bounds[dim];
    b->lower = 0;
    b->upper = 1;
    b->mid = .5;

    if( dim == 0 ) {
      count bin;
      /* define the initial distribution of bins */
      for( bin = 0; bin < NBINS; ++bin )
        b->grid[bin] = (bin + 1)/(real)NBINS;
    }
    else Copy(b->grid, anchor->bounds[0].grid, NBINS);
  }

  Sample(t, t->nnew, anchor, anchor->w,
    anchor->w + t->nnew,
    anchor->w + t->nnew + t->ndim*t->nnew);
  df = anchor->df;
  ResCopy(totals, anchor->result);

  for( t->nregions = 1; ; ++t->nregions ) {
    Var var[NDIM][2], *vLR;
    real maxratio, maxerr, minfluct, bias, mid;
    Region *regionL, *regionR, *reg, **parent, **par;
    Bounds *bounds, *boundsL, *boundsR;
    count maxcomp, bisectdim;
    number n, nL, nR, nnewL, nnewR;
    real *w, *wL, *wR, *x, *xL, *xR, *f, *fL, *fR, *wlast, *flast;

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

      p += sprintf(p, "\n"
        "Iteration " COUNT ":  " NUMBER " integrand evaluations so far",
        t->nregions, t->neval);

      for( comp = 0; comp < t->ncomp; ++comp ) {
        cResult *tot = &totals[comp];
        p += sprintf(p, "\n[" COUNT "] " 
          REAL " +- " REAL "  \tchisq " REAL " (" COUNT " df)",
          comp + 1, tot->avg, tot->err, tot->chisq, df);
      }

      Print(s);
    }

    maxratio = -INFTY;
    maxcomp = 0;
    for( comp = 0; comp < t->ncomp; ++comp ) {
      creal ratio = totals[comp].err/MaxErr(totals[comp].avg);
      if( ratio > maxratio ) {
        maxratio = ratio;
        maxcomp = comp;
      }
    }

    if( maxratio <= 1 && t->neval >= t->mineval ) {
      fail = 0;
      break;
    }

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

    maxerr = -INFTY;
    parent = &anchor;
    region = anchor;
    for( par = &anchor; (reg = *par); par = &reg->next ) {
      creal err = reg->result[maxcomp].err;
      if( err > maxerr ) {
        maxerr = err;
        parent = par;
        region = reg;
      }
    }

    Fluct(t, var[0],
      region->bounds, region->w, region->n, maxcomp,
      region->result[maxcomp].avg, Max(maxerr, t->epsabs));

    bias = (t->epsrel < 1e-50) ? 2 :
      Max(pow(2., -(real)region->div/t->ndim)/t->epsrel, 2.);
    minfluct = INFTY;
    bisectdim = 0;
    for( dim = 0; dim < t->ndim; ++dim ) {
      cBounds *b = &region->bounds[dim];
      creal fluct = (var[dim][0].fluct + var[dim][1].fluct)*
        (bias - b->upper + b->lower);
      if( fluct < minfluct ) {
        minfluct = fluct;
        bisectdim = dim;
      }
    }

    vLR = var[bisectdim];
    minfluct = vLR[0].fluct + vLR[1].fluct;
    nnewL = IMax(
      (minfluct == 0) ? t->nnew/2 : (count)(vLR[0].fluct/minfluct*t->nnew),
      MINSAMPLES );
    nL = vLR[0].n + nnewL;
    nnewR = IMax(t->nnew - nnewL, MINSAMPLES);
    nR = vLR[1].n + nnewR;

    RegionAlloc(t, regionL, nL, nnewL);
    RegionAlloc(t, regionR, nR, nnewR);

    *parent = regionL;
    regionL->next = regionR;
    regionR->next = region->next;
    regionL->div = regionR->div = region->div + 1;

    bounds = &region->bounds[bisectdim];
    mid = bounds->mid;
    n = region->n;
    w = wlast = region->w;  x = w + n;     f = flast = x + n*t->ndim;
    wL = regionL->w;        xL = wL + nL;  fL = xL + nL*t->ndim;
    wR = regionR->w;        xR = wR + nR;  fR = xR + nR*t->ndim;

    while( n-- ) {
      cbool final = (*w < 0);
      if( x[bisectdim] < mid ) {
        if( final && wR > regionR->w ) *(wR - 1) = -fabs(*(wR - 1));
        *wL++ = *w++;
        VecCopy(xL, x);
        xL += t->ndim;
        ResCopy(fL, f);
        fL += t->ncomp;
      }
      else {
        if( final && wL > regionL->w ) *(wL - 1) = -fabs(*(wL - 1));
        *wR++ = *w++;
        VecCopy(xR, x);
        xR += t->ndim;
        ResCopy(fR, f);
        fR += t->ncomp;
      }
      x += t->ndim;
      f += t->ncomp;
      if( n && final ) wlast = w, flast = f;
    }

    Reweight(t, region->bounds, wlast, flast, f, totals);
    VecCopy(regionL->bounds, region->bounds);
    VecCopy(regionR->bounds, region->bounds);

    boundsL = &regionL->bounds[bisectdim];
    boundsR = &regionR->bounds[bisectdim];
    boundsL->mid = .5*(boundsL->lower + (boundsL->upper = mid));
    boundsR->mid = .5*((boundsR->lower = mid) + boundsR->upper);

    StretchGrid(bounds->grid, boundsL->grid, boundsR->grid);

    Sample(t, nnewL, regionL, wL, xL, fL);
    Sample(t, nnewR, regionR, wR, xR, fR);

    df += regionL->df + regionR->df - region->df;

    for( comp = 0; comp < t->ncomp; ++comp ) {
      cResult *r = &region->result[comp];
      Result *rL = &regionL->result[comp];
      Result *rR = &regionR->result[comp];
      Result *tot = &totals[comp];
      real diff, sigsq;

      tot->avg += diff = rL->avg + rR->avg - r->avg;

      diff = Sq(.25*diff);
      sigsq = rL->sigsq + rR->sigsq;
      if( sigsq > 0 ) {
        creal c = Sq(1 + sqrt(diff/sigsq));
        rL->sigsq *= c;
        rR->sigsq *= c;
      }
      rL->err = sqrt(rL->sigsq += diff);
      rR->err = sqrt(rR->sigsq += diff);

      tot->sigsq += rL->sigsq + rR->sigsq - r->sigsq;
      tot->err = sqrt(tot->sigsq);

      tot->chisq += rL->chisq + rR->chisq - r->chisq;
    }

    free(region);
    region = NULL;
  }
예제 #10
0
static int Integrate(creal epsrel, creal epsabs,
  cint flags, number mineval, cnumber maxeval, ccount key,
  real *integral, real *error, real *prob)
{
  TYPEDEFREGION;

  count dim, comp;
  int fail = 1;
  Rule rule;
  Totals totals[NCOMP];
  Region *anchor = NULL, *region = NULL;

  if( VERBOSE > 1 ) {
    char s[256];
    sprintf(s, "Cuhre input parameters:\n"
      "  ndim " COUNT "\n  ncomp " COUNT "\n"
      "  epsrel " REAL "\n  epsabs " REAL "\n"
      "  flags %d\n  mineval " NUMBER "\n  maxeval " NUMBER "\n"
      "  key " COUNT,
      ndim_, ncomp_,
      epsrel, epsabs,
      flags, mineval, maxeval,
      key);
    Print(s);
  }

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

  if( key == 13 && ndim_ == 2 ) Rule13Alloc(&rule);
  else if( key == 11 && ndim_ == 3 ) Rule11Alloc(&rule);
  else if( key == 9 ) Rule9Alloc(&rule);
  else if( key == 7 ) Rule7Alloc(&rule);
  else {
    if( ndim_ == 2 ) Rule13Alloc(&rule);
    else if( ndim_ == 3 ) Rule11Alloc(&rule);
    else Rule9Alloc(&rule);
  }

  Alloc(rule.x, rule.n*(ndim_ + ncomp_));
  rule.f = rule.x + rule.n*ndim_;

  mineval = IMax(mineval, rule.n + 1);

  Alloc(anchor, 1);
  anchor->next = NULL;
  anchor->div = 0;

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

  Sample(&rule, anchor, flags);

  for( comp = 0; comp < ncomp_; ++comp ) {
    Totals *tot = &totals[comp];
    Result *r = &anchor->result[comp];
    tot->avg = tot->lastavg = tot->guess = r->avg;
    tot->err = tot->lasterr = r->err;
    tot->weightsum = 1/Max(Sq(r->err), NOTZERO);
    tot->avgsum = tot->weightsum*r->avg;
    tot->chisq = tot->chisqsum = tot->chisum = 0;
  }

  for( nregions_ = 1; ; ++nregions_ ) {
    count maxcomp, bisectdim;
    real maxratio, maxerr;
    Region *regionL, *regionR, *reg, **parent, **par;
    Bounds *bL, *bR;

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

      p += sprintf(p, "\n"
        "Iteration " COUNT ":  " NUMBER " integrand evaluations so far",
        nregions_, neval_);

      for( comp = 0; comp < ncomp_; ++comp ) {
        cTotals *tot = &totals[comp];
        p += sprintf(p, "\n[" COUNT "] "
          REAL " +- " REAL "  \tchisq " REAL " (" COUNT " df)",
          comp + 1, tot->avg, tot->err, tot->chisq, nregions_ - 1);
      }

      Print(s);
    }

    maxratio = -INFTY;
    maxcomp = 0;
    for( comp = 0; comp < ncomp_; ++comp ) {
      creal ratio = totals[comp].err/MaxErr(totals[comp].avg);
      if( ratio > maxratio ) {
        maxratio = ratio;
        maxcomp = comp;
      }
    }

    if( maxratio <= 1 && neval_ >= mineval ) {
      fail = 0;
      break;
    }

    if( neval_ >= maxeval ) break;

    maxerr = -INFTY;
    parent = &anchor;
    region = anchor;
    for( par = &anchor; (reg = *par); par = &reg->next ) {
      creal err = reg->result[maxcomp].err;
      if( err > maxerr ) {
        maxerr = err;
        parent = par;
        region = reg;
      }
    }

    Alloc(regionL, 1);
    Alloc(regionR, 1);

    *parent = regionL;
    regionL->next = regionR;
    regionR->next = region->next;
    regionL->div = regionR->div = region->div + 1;

    VecCopy(regionL->bounds, region->bounds);
    VecCopy(regionR->bounds, region->bounds);

    bisectdim = region->result[maxcomp].bisectdim;
    bL = &regionL->bounds[bisectdim];
    bR = &regionR->bounds[bisectdim];
    bL->upper = bR->lower = .5*(bL->upper + bL->lower);

    Sample(&rule, regionL, flags);
    Sample(&rule, regionR, flags);

    for( comp = 0; comp < ncomp_; ++comp ) {
      cResult *r = &region->result[comp];
      Result *rL = &regionL->result[comp];
      Result *rR = &regionR->result[comp];
      Totals *tot = &totals[comp];
      real diff, err, w, avg, sigsq;

      tot->lastavg += diff = rL->avg + rR->avg - r->avg;

      diff = fabs(.25*diff);
      err = rL->err + rR->err;
      if( err > 0 ) {
        creal c = 1 + 2*diff/err;
        rL->err *= c;
        rR->err *= c;
      }
      rL->err += diff;
      rR->err += diff;
      tot->lasterr += rL->err + rR->err - r->err;

      tot->weightsum += w = 1/Max(Sq(tot->lasterr), NOTZERO);
      sigsq = 1/tot->weightsum;
      tot->avgsum += w*tot->lastavg;
      avg = sigsq*tot->avgsum;
      tot->chisum += w *= tot->lastavg - tot->guess;
      tot->chisqsum += w*tot->lastavg;
      tot->chisq = tot->chisqsum - avg*tot->chisum;

      if( LAST ) {
        tot->avg = tot->lastavg;
        tot->err = tot->lasterr;
      }
      else {
        tot->avg = avg;
        tot->err = sqrt(sigsq);
      }
    }

    free(region);
    region = NULL;
  }

  for( comp = 0; comp < ncomp_; ++comp ) {
    cTotals *tot = &totals[comp];
    integral[comp] = tot->avg;
    error[comp] = tot->err;
    prob[comp] = ChiSquare(tot->chisq, nregions_ - 1);
  }

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

      for( dim = 0; dim < ndim_; ++dim ) {
        cBounds *b = &region->bounds[dim];
        lower[dim] = b->lower;
        upper[dim] = b->upper;
      }

      MLPutFunction(stdlink, "Cuba`Cuhre`region", 3);
      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->err};
        MLPutRealList(stdlink, res, Elements(res));
      }
    }
  }
#endif

#ifdef MLVERSION
abort:
#endif

  if( region ) free(region);

  while( (region = anchor) ) {
    anchor = anchor->next;
    free(region);
  }

  free(rule.x);
  RuleFree(&rule);

  return fail;
}
예제 #11
0
파일: sync.cpp 프로젝트: CRPropa/CRPropa3
void InitializeSynchrotron(const double B_0, const dCVector* pEnergy, 
			   const dCVector* pEnergyWidth,
			   dCVector* synchrotronLoss, DiffRate* syncRate,
			   string aDirTables)
/* this function calculates the synchrotron loss rate for the electron
    and the synchrotron radiation spectrum for photons
    The radom direction of the magnetic field requires me to do an
    average over the pitch angle, and it results in an extra factor of
    2/3, and slightly modifies the functional form of F(x) from the
    purely perpendicular case   */
/* The above comment is from the stand alone version. Compared to this version the constants seem to be fixed to correct for a perpendicular field as input. JK, 2011*/
{
    const int SYNC_TABLE_SIZE = 161;
    int i;
    double offset;    /* parameter to compute bounds correctly */
    dCVector syncTable;
    double x0;

    double ECrit;
    double EMin;
    double EMax;
    int jMin;
    int jMax;
    int j;
    double xx;
    double function;
    int iTable;
    double eLower;
    double eUpper;
    int num_main_bins;

    num_main_bins = pEnergy->dimension;

    if ((num_main_bins != pEnergyWidth->dimension) || 
	(num_main_bins != syncRate->mainDimension) ||
	(num_main_bins != synchrotronLoss->dimension))
    {
	Error("InitializeSynchrotron: inconsistent dimensions", PROGRAM_ERROR);
    }

    New_dCVector(&syncTable, SYNC_TABLE_SIZE);

    /* read in table */

    LoadSyncTable(&syncTable, aDirTables);

    /* calculate the rates */
    offset = BINS_PER_DECADE*(log10(ELECTRON_MASS) - MAX_ENERGY_EXP) +
        num_main_bins + 0.5;
    x0 = B_0*5.86667629e-4*DISTANCE_UNIT;
    /* x0: eB/m_e in inverse pc */

    for (i = 0; i < num_main_bins; i++)
    {
        /* electron loss rate */
        (synchrotronLoss->vector)[i] = -B_0*B_0*(pEnergy->vector)[i]*
	    (pEnergy->vector)[i]*2.*4.86037e4*VOLUME_UNIT;
        
        /* calculate the radiation spectrum */
        ECrit = 3./2.*B_0/4.414034e13*(pEnergy->vector)[i]*
	    (pEnergy->vector)[i];
        /* ECrit: critical energy in electron mass */

        EMin = 2./3./((pEnergy->vector)[i]*(pEnergy->vector)[i]*
            (pEnergy->vector)[i])*ECrit;
        EMax = 5.*ECrit;
        /* EMin/EMax: useful range for x (in electron mass) */

        /* set up the range for photons -> determine bounds */
	jMin = IMax((int)(BINS_PER_DECADE*log10(EMin) + offset), 0);
	jMax = IMin((int)(BINS_PER_DECADE*log10(EMax) + offset),
	    num_main_bins - 1);
        if (jMax >= 0)  /* normal case */
        {
            (syncRate->bound)[i][0] = jMin;
            (syncRate->bound)[i][1] = jMax;

            for (j = (syncRate->bound)[i][0]; 
		 j <= (syncRate->bound)[i][1]; j++)
            {
                xx = (pEnergy->vector)[j]/ECrit;

                if (log10(xx) < -7.)
                {
                    function = pow(xx, 1./3.)*2.1809736;
		    /* use an approximation for x below 10^-7 */
                }
                else
                {
		  /* compute F(x) at given photon energy by linear
		     extrapolation in logarithm */
                    iTable = (int)(log10(xx)*20. + 140);
                    eLower = (double)(iTable - 140)/20.;
                    eUpper = (double)(iTable - 139)/20.;
		    /* numbers 140, 139, and 20 are properties of table */
                    function = exp(log(syncTable.vector[iTable]) + (log10(xx) -
                        eLower)/(eUpper - eLower)*
                        (log(syncTable.vector[iTable+1]) - 
			 log(syncTable.vector[iTable])));
                }
                (syncRate->diffRate)[i][j] = 2.756644477e-1/137.036*x0*
		    function/(pEnergy->vector)[j]*(pEnergyWidth->vector)[j];
                /* 2.7566...: sqtr(3)/(2pi), 1/137: e^2, x0: eB/m_e */
            }
        }
    }

    Delete_dCVector(&syncTable) ;

}
예제 #12
0
파일: fold.cpp 프로젝트: CRPropa/CRPropa3
void FoldDiffRate(const dCVector* pBgPhotonDensity,
		  const RawDiffRate* pRawDiffRate,
		  DiffRate* pDiffRate, const int scatSwitch, ...)
{
    int i;
    int j;
    int k;
    int offset = 0;
    int jLower;
    int jUpper;
    int num_main_bins;
    int num_bg_bins;

    num_main_bins = pRawDiffRate->mainDimension;
    num_bg_bins = pRawDiffRate->bgDimension;

    if ((pBgPhotonDensity->dimension != num_bg_bins) ||
	(num_main_bins != pDiffRate->mainDimension))
    {
        Error("FoldDiffRate: inconsistent dimensions", PROGRAM_ERROR);
    }

    if (scatSwitch != 0)
    /* scattering type: adjustment of total rate(s) needed */
    {
	va_list pArg;
//	TotalRate* totalRateArray[scatSwitch];
	TotalRate* totalRateArray[3];

	va_start(pArg, scatSwitch);
	for (i = 0; i < scatSwitch; i++)
	    totalRateArray[i] = va_arg(pArg, TotalRate*);
	/* Let totalRateArray[i] point to the totalRate* we will modify; we do
	   not need to update the arguments later
	   (i.e. va_arg(...) = totalRateArray[i];) because the actual values
	   they point to have been properly updated */

	for (i = 0; i < num_main_bins; i++)
	{
	    jLower = num_main_bins - 1;
	    jUpper = 0;
	    for (j = 0; j < num_bg_bins; j++)
	    {
		if (pRawDiffRate->bound[i][j][0] != -1)
		/* above threshold */
		{
		    offset += -(pRawDiffRate->bound)[i][j][0];
		    jLower = IMin(jLower, (pRawDiffRate->bound)[i][j][0]);
		    jUpper = IMax(jUpper, (pRawDiffRate->bound)[i][j][1]);
		    for (k = (pRawDiffRate->bound)[i][j][0]; 
			 k <= (pRawDiffRate->bound)[i][j][1]; k++)
		    {
#ifdef DEBUG
			CheckIndex(0, i+1, k, "FoldDiffRate");
			CheckIndex(0, pRawDiffRate->numberOfElements, k+offset,
				   "FoldDiffRate");
#endif
			(pDiffRate->diffRate)[i][k] += 
			    (pBgPhotonDensity->vector)[j]*
			    (pRawDiffRate->diffRate)[k+offset];
		    }
		    /* these lines take care of the appropriate subtractions 
		       made in the main implicit formula */
		    if ((pRawDiffRate->bound)[i][j][1] == i)
		    /*  if (((pRawDiffRate->bound)[i][j][0] <= i) && 
			    ((pRawDiffRate->bound)[i][j][1] >= i))    */
		    {
			int l;

			for (l = 0; l < scatSwitch; l++)
			{
			    (totalRateArray[l]->totalRate)[i] += 
			        -(pRawDiffRate->diffRate)[i+offset]*
			        (pBgPhotonDensity->vector)[j];
			}
			(pDiffRate->diffRate)[i][i] += 
			    -(pRawDiffRate->diffRate)[i+offset]*
			    (pBgPhotonDensity->vector)[j];
		    }
		    offset += (pRawDiffRate->bound)[i][j][1] + 1;
		    /* reset the offset index */
		}
	    }
	    (pDiffRate->bound)[i][0] = IMin((pDiffRate->bound)[i][0], jLower);
	    (pDiffRate->bound)[i][1] = IMax((pDiffRate->bound)[i][1], jUpper);
        }
	va_end(pArg);
    }