Beispiel #1
0
// construct an approximating Gaussian model
// Note the difference to previous versions, the convergence is assessed only
// by checking the changes in mode, not the actual function values. This is
// slightly faster and sufficient as the approximation doesn't need to be accurate.
// Using function values would be safer though, as we could use line search etc
// in case of potential divergence etc...
ugg_ssm ung_ssm::approximate(arma::vec& mode_estimate, const unsigned int max_iter,
  const double conv_tol) {
  
  //Construct y and H for the Gaussian model
  arma::vec approx_y(n, arma::fill::zeros);
  arma::vec approx_H(n, arma::fill::zeros);
  
  // RNG of approximate model is only used in basic IS sampling
  // set seed for new RNG stream based on the original model
  std::uniform_int_distribution<> unif(0, std::numeric_limits<int>::max());
  const unsigned int new_seed = unif(engine);
  ugg_ssm approx_model(approx_y, Z, approx_H, T, R, a1, P1, xreg, beta, D, C, new_seed);
  
  unsigned int i = 0;
  double diff = conv_tol + 1;
  while(i < max_iter && diff > conv_tol) {
    i++;
    //Construct y and H for the Gaussian model
    laplace_iter(mode_estimate, approx_model.y, approx_model.H);
    approx_model.compute_HH();
    // compute new guess of mode
    arma::vec mode_estimate_new(n);
    if (distribution == 0) {
      mode_estimate_new = arma::vectorise(approx_model.fast_smoother().head_cols(n));
    } else {
      arma::mat alpha = approx_model.fast_smoother().head_cols(n);
      for (unsigned int t = 0; t < n; t++) {
        mode_estimate_new(t) = arma::as_scalar(Z.col(Ztv * t).t() * alpha.col(t));
      }
    }
    diff = arma::mean(arma::square(mode_estimate_new - mode_estimate));
    mode_estimate = mode_estimate_new;
  }
  
  return approx_model;
}
Beispiel #2
0
size_t Approximator::test_function(const std::string& name,
                                   const Function& fun) {
    POMAGMA_INFO("Testing " << name << " approximation");

    size_t ob_fail_count = 0;
    size_t upper_fail_count = 0;
    size_t upper_extra_count = 0;
    size_t upper_missing_count = 0;
    size_t lower_fail_count = 0;
    size_t lower_extra_count = 0;
    size_t lower_missing_count = 0;

    const size_t item_dim = m_item_dim;
#pragma omp parallel
    {
        DenseSet temp_set(item_dim);

#pragma omp for schedule(dynamic, 1)
        for (Ob x = 1; x <= item_dim; ++x) {
            Approximation approx_x(x, m_less);
            approx_x.ob = 0;

            for (auto iter = fun.iter_lhs(x); iter.ok(); iter.next()) {
                Ob y = *iter;
                Approximation approx_y(y, m_less);
                approx_y.ob = 0;

                Ob xy = fun.find(x, y);
                Approximation expected(xy, m_less);
                Approximation actual = find(fun, approx_x, approx_y);

                if (actual.ob != expected.ob) {
#pragma omp atomic
                    ob_fail_count += 1;
                }
                if (actual.upper != expected.upper) {
#pragma omp atomic
                    upper_fail_count += 1;
                    temp_set.set_diff(actual.upper, expected.upper);
                    if (size_t count = temp_set.count_items()) {
#pragma omp atomic
                        upper_extra_count += count;
                    }
                    temp_set.set_diff(expected.upper, actual.upper);
                    if (size_t count = temp_set.count_items()) {
#pragma omp atomic
                        upper_missing_count += count;
                    }
                }
                if (actual.lower != expected.lower) {
#pragma omp atomic
                    lower_fail_count += 1;
                    temp_set.set_diff(actual.lower, expected.lower);
                    if (size_t count = temp_set.count_items()) {
#pragma omp atomic
                        lower_extra_count += count;
                    }
                    temp_set.set_diff(expected.lower, actual.lower);
                    if (size_t count = temp_set.count_items()) {
#pragma omp atomic
                        lower_missing_count += count;
                    }
                }
            }
        }
    }

    if (ob_fail_count) {
        POMAGMA_WARN(name << " ob failed " << ob_fail_count << " cases");
    }
    if (upper_missing_count or upper_extra_count) {
        POMAGMA_WARN(name << " upper has " << upper_missing_count
                          << " missing and " << upper_extra_count
                          << " extra obs in " << upper_fail_count << " cases");
    }
    if (lower_missing_count or lower_extra_count) {
        POMAGMA_WARN(name << " lower has " << lower_missing_count
                          << " missing and " << lower_extra_count
                          << " extra obs in " << lower_fail_count << " cases");
    }

    return ob_fail_count + upper_fail_count + lower_fail_count;
}