Exemple #1
0
std::pair<double,double> 
find_slice_boundaries_stepping_out(double x0,slice_function& g,double logy, double w,int m)
{
  assert(g.in_range(x0));

  double u = uniform()*w;
  double L = x0 - u;
  double R = x0 + (w-u);

  // Expand the interval until its ends are outside the slice, or until
  // the limit on steps is reached.

  //  std::cerr<<"!!    L0 = "<<L<<"   x0 = "<<x0<<"   R0 = "<<R<<"\n";
  if (m>1) {
    int J = uniform(0,m-1);
    int K = (m-1)-J;

    while (J>0 and (not g.below_lower_bound(L)) and g(L)>logy) {
      L -= w;
      J--;
      //      std::cerr<<" g("<<L<<") = "<<g()<<" > "<<logy<<"\n";
      //      std::cerr<<"<-    L0 = "<<L<<"   x0 = "<<x0<<"   R0 = "<<R<<"\n";
    }

    while (K>0 and (not g.above_upper_bound(R)) and g(R)>logy) {
      R += w;
      K--;
      //      std::cerr<<" g("<<R<<") = "<<g()<<" > "<<logy<<"\n";
      //      std::cerr<<"->    L0 = "<<L<<"   x0 = "<<x0<<"   R0 = "<<R<<"\n";
    }
  }
  else {
    while ((not g.below_lower_bound(L)) and g(L)>logy)
      L -= w;

    while ((not g.above_upper_bound(R)) and g(R)>logy)
      R += w;
  }

  // Shrink interval to lower and upper bounds.

  if (g.below_lower_bound(L)) L = g.lower_bound;
  if (g.above_upper_bound(R)) R = g.upper_bound;

  assert(L < R);

  //  std::cerr<<"[]    L0 = "<<L<<"   x0 = "<<x0<<"   R0 = "<<R<<"\n";

  return std::pair<double,double>(L,R);
}
Exemple #2
0
inline static void dec(double& x, double w, const slice_function& g, bool& hit_lower_bound)
{
  x -= w;
  if (g.below_lower_bound(x)) {
    x = g.lower_bound;
    hit_lower_bound=true;
  }
}
Exemple #3
0
std::pair<double,double> 
find_slice_boundaries_stepping_out(double x0,slice_function& g,double logy, double w,int m)
{
  double u = uniform()*w;
  double L = x0 - u;
  double R = x0 + (w-u);

  // Expand the interval until its ends are outside the slice, or until
  // the limit on steps is reached.

  if (m>1) {
    int J = floor(uniform()*m);
    int K = (m-1)-J;

    while (J>0 and (not g.below_lower_bound(L)) and g(L)>logy) {
      L -= w;
      J--;
    }

    while (K>0 and (not g.above_upper_bound(R)) and g(R)>logy) {
      R += w;
      K--;
    }
  }
  else {
    while ((not g.below_lower_bound(L)) and g(L)>logy)
      L -= w;

    while ((not g.above_upper_bound(R)) and g(R)>logy)
      R += w;
  }

  // Shrink interval to lower and upper bounds.

  if (g.below_lower_bound(L)) L = g.lower_bound;
  if (g.above_upper_bound(R)) R = g.upper_bound;

  return std::pair<double,double>(L,R);
}
Exemple #4
0
// Assumes uni-modal
std::pair<double,double> find_slice_boundaries_search(double& x0,slice_function& g,double logy,
						      double w,int /*m*/)
{
  // the initial point should be within the bounds, if the exist
  assert(not g.below_lower_bound(x0));
  assert(not g.above_upper_bound(x0));

  bool hit_lower_bound=false;
  bool hit_upper_bound=false;

  double gx0 = g(x0);

  double L = x0;
  double R = L;
  inc(R,w,g,hit_upper_bound);
  
  //  if (gx > logy) return find_slice_boundaries_stepping_out(x,g,logy,w,m,lower_bound,lower,upper_bound,upper);

  int state = -1;

  while(1)
  {
    double gL = g(L);
    double gR = g(R);

    if (gx0 < logy and gL > gx0) {
      x0 = L;
      gx0 = gL;
    }

    if (gx0 < logy and gR > gx0) {
      x0 = R;
      gx0 = gR;
    }

    // below bound, and slopes upwards to the right
    if (gR < logy and gL < gR) 
    {
      if (state == 2)
	break;
      else if (state == 1) {
	inc(R,w,g,hit_upper_bound);
	break;
      }

      state = 0;
      hit_lower_bound=false;
      L = R;
      inc(R,w,g,hit_upper_bound);
    }
    // below bound, and slopes upwards to the left
    else if (gL < logy and gR < gL) 
    {
      if (state == 2)
	break;
      if (state == 1)
      {
	dec(L,w,g,hit_lower_bound);
	break;
      }

      state = 1;
      hit_upper_bound=false;
      R = L;
      dec(L,w,g,hit_lower_bound);
    }
    else {
      state = 2;
      bool moved = false;
      if (gL >= logy and not hit_lower_bound) {
	moved = true;
	dec(L,w,g,hit_lower_bound);
      }

      if (gR >= logy and not hit_upper_bound) {
	moved = true;
	inc(R,w,g,hit_upper_bound);
      }

      if (not moved) break;
    }
  }

  return std::pair<double,double>(L,R);
}