示例#1
0
size_t sample_discrete(const double* cumsum, const size_t m, int level, Rand& rng)
{
  size_t a = 0;
  size_t b = m - 1;
  size_t c;

  double z = cumsum[b];
  double r = rng.rand_01() * z;

  // bisection search
  while (level > 0){
    c = (a + b) / 2;
    if (r < cumsum[c]){
      b = c;
    } else {
      a = c + 1;
    }
    --level;
  }

  // linear search
  for (size_t i = a; i <= b; ++i){
    if (r < cumsum[i]){
      return i;
    }
  }

  throw std::logic_error("sample_discrete reached end");
}
示例#2
0
int sample_discrete_naive(const double *cumsum, const int m, Rand &rng){
  double z = cumsum[m - 1];
  double r = rng.rand_01() * z;

  for (int i = 0; i < m; ++i){
    if (r < cumsum[i]){
      return i;
    }
  }

  throw std::logic_error("sample_discrete_naive reached end, exiting");
}
示例#3
0
int sample_discrete_naive_ft(const double *cumsum, const int from, const int to, Rand &rng){
  double d = ((from > 0) ? cumsum[from-1] : 0.0);
  double z = cumsum[to] - d;
  double r = rng.rand_01() * z + d;

  for (int i = from; i <= to; ++i){
    if (r < cumsum[i]){
      return i;
    }
  }

  throw std::logic_error("sample_discrete_naive_ft reached end, exiting");
}
示例#4
0
double Prior::sample_alpha(Model* model, const VectorView& y, Rand& rng)
{
  // then use full conditional of alpha to update it
  size_t nterms = (model->beta).length() - m_e;

  double a = alpha_;

  do { // disallow exact zero value
    if (nterms > 0){
      // propose switching sign of alpha and eta (sign of eta has no effect as long
      // as we actually sample beta; note that eta has symmetric zero mean
      // distribution); this is metropolis move with deterministic
      // proposal; no effect is mu_alpha is zero (might as well skip...)
      if ((a <= 0.0) || log(rng.rand_01()) <= -2.0 * mu_alpha * a){
        a = -a;
      }

      Vector xb(n);
      Vector eb(n);

      xb.set_to_product((model->x).columnblock(m_e, nterms),
          (model->beta).block(m_e, nterms), false);
      eb.set_to_product((model->x).columnblock(0, m_e),
          (model->beta).block(0, m_e), false);
      eb -= y; // note: this is E * b - y, hence there is minus below in mu formul.

      double alpha_sigma2 = a * model->sigma2;
      double var = 1.0 / (1.0 + VectorView::dotproduct(xb, xb) / (a * alpha_sigma2));
      double mu = var * (mu_alpha - VectorView::dotproduct(eb, xb) / alpha_sigma2);

      a = sqrt(var) * rng.rand_normal() + mu;
    } else {
      // sample from prior
      a = rng.rand_normal() + mu_alpha;
    }
  } while (a == 0 || a * a == 0);
  model->mu_beta_computed = false;

  return a;
}