예제 #1
0
TEST(McmcNuts, instantiaton_test) {
  rng_t base_rng(4839294);

  std::stringstream output;
  stan::callbacks::stream_writer writer(output);
  std::stringstream error_stream;
  stan::callbacks::stream_writer error_writer(error_stream);

  std::fstream empty_stream("", std::fstream::in);
  stan::io::dump data_var_context(empty_stream);
  gauss3D_model_namespace::gauss3D_model model(data_var_context);

  stan::mcmc::unit_e_nuts<gauss3D_model_namespace::gauss3D_model, rng_t>
    unit_e_sampler(model, base_rng);
  
  stan::mcmc::diag_e_nuts<gauss3D_model_namespace::gauss3D_model, rng_t>
    diag_e_sampler(model, base_rng);
  
  stan::mcmc::dense_e_nuts<gauss3D_model_namespace::gauss3D_model, rng_t>
    dense_e_sampler(model, base_rng);
  
  stan::mcmc::adapt_unit_e_nuts<gauss3D_model_namespace::gauss3D_model, rng_t>
    adapt_unit_e_sampler(model, base_rng);
  
  stan::mcmc::adapt_diag_e_nuts<gauss3D_model_namespace::gauss3D_model, rng_t>
    adapt_diag_e_sampler(model, base_rng);
  
  stan::mcmc::adapt_dense_e_nuts<gauss3D_model_namespace::gauss3D_model, rng_t>
    adapt_dense_e_sampler(model, base_rng);
}
예제 #2
0
TEST(McmcNutsBaseNuts, transition) {

  rng_t base_rng(0);

  int model_size = 1;
  double init_momentum = 1.5;

  stan::mcmc::ps_point z_init(model_size);
  z_init.q(0) = 0;
  z_init.p(0) = init_momentum;

  stan::mcmc::mock_model model(model_size);
  stan::mcmc::mock_nuts sampler(model, base_rng);

  sampler.set_nominal_stepsize(1);
  sampler.set_stepsize_jitter(0);
  sampler.sample_stepsize();
  sampler.z() = z_init;

  std::stringstream output_stream;
  stan::interface_callbacks::writer::stream_writer writer(output_stream);
  std::stringstream error_stream;
  stan::interface_callbacks::writer::stream_writer error_writer(error_stream);

  stan::mcmc::sample init_sample(z_init.q, 0, 0);

  stan::mcmc::sample s = sampler.transition(init_sample, writer, error_writer);

  EXPECT_EQ(31.5, s.cont_params()(0));
  EXPECT_EQ(0, s.log_prob());
  EXPECT_EQ(1, s.accept_stat());
  EXPECT_EQ("", output_stream.str());
  EXPECT_EQ("", error_stream.str());
}
예제 #3
0
TEST(McmcNutsBaseNuts, build_tree) {

  rng_t base_rng(0);

  int model_size = 1;
  double init_momentum = 1.5;

  stan::mcmc::ps_point z_init(model_size);
  z_init.q(0) = 0;
  z_init.p(0) = init_momentum;

  stan::mcmc::ps_point z_propose(model_size);

  Eigen::VectorXd rho = z_init.p;
  double log_sum_weight = -std::numeric_limits<double>::infinity();

  double H0 = -0.1;
  int n_leapfrog = 0;
  double sum_metro_prob = 0;

  stan::mcmc::mock_model model(model_size);
  stan::mcmc::mock_nuts sampler(model, base_rng);

  sampler.set_nominal_stepsize(1);
  sampler.set_stepsize_jitter(0);
  sampler.sample_stepsize();
  sampler.z() = z_init;

  std::stringstream output;
  stan::interface_callbacks::writer::stream_writer writer(output);
  std::stringstream error_stream;
  stan::interface_callbacks::writer::stream_writer error_writer(error_stream);


  bool valid_subtree = sampler.build_tree(3, rho, z_propose,
                                          H0, 1, n_leapfrog, log_sum_weight,
                                          sum_metro_prob, writer, error_writer);

  EXPECT_TRUE(valid_subtree);

  EXPECT_EQ(init_momentum * (n_leapfrog + 1), rho(0));

  EXPECT_EQ(8 * init_momentum, sampler.z().q(0));
  EXPECT_EQ(init_momentum, sampler.z().p(0));

  EXPECT_EQ(8, n_leapfrog);
  EXPECT_FLOAT_EQ(H0 + std::log(n_leapfrog), log_sum_weight);
  EXPECT_FLOAT_EQ(std::exp(H0) * n_leapfrog, sum_metro_prob);

  EXPECT_EQ("", output.str());
  EXPECT_EQ("", error_stream.str());
}
예제 #4
0
TEST(McmcHmcIntegratorsImplLeapfrog, unit_e_energy_conservation) {
  rng_t base_rng(0);

  std::fstream data_stream(std::string("").c_str(), std::fstream::in);
  stan::io::dump data_var_context(data_stream);
  data_stream.close();

  std::stringstream model_output;
  std::stringstream metric_output;
  stan::interface_callbacks::writer::stream_writer writer(metric_output);
  std::stringstream error_stream;
  stan::interface_callbacks::writer::stream_writer error_writer(error_stream);

  gauss_model_namespace::gauss_model model(data_var_context, &model_output);

  stan::mcmc::impl_leapfrog<
    stan::mcmc::unit_e_metric<gauss_model_namespace::gauss_model, rng_t> >
    integrator;

  stan::mcmc::unit_e_metric<gauss_model_namespace::gauss_model, rng_t> metric(model);

  stan::mcmc::unit_e_point z(1);
  z.q(0) = 1;
  z.p(0) = 1;

  metric.init(z, writer, error_writer);
  double H0 = metric.H(z);
  double aveDeltaH = 0;

  double epsilon = 1e-3;
  double tau = 6.28318530717959;
  size_t L = tau / epsilon;

  for (size_t n = 0; n < L; ++n) {
    integrator.evolve(z, metric, epsilon, writer, error_writer);

    double deltaH = metric.H(z) - H0;
    aveDeltaH += (deltaH - aveDeltaH) / double(n + 1);
  }

  // Average error in Hamiltonian should be O(epsilon^{2})
  // in general, smaller for the gauss_model in this case due to cancellations
  EXPECT_NEAR(aveDeltaH, 0, epsilon * epsilon);

  EXPECT_EQ("", model_output.str());
  EXPECT_EQ("", metric_output.str());
}
예제 #5
0
TEST(McmcUnitENuts, transition_test) {
  rng_t base_rng(4839294);

  stan::mcmc::unit_e_point z_init(3);
  z_init.q(0) = 1;
  z_init.q(1) = -1;
  z_init.q(2) = 1;
  z_init.p(0) = -1;
  z_init.p(1) = 1;
  z_init.p(2) = -1;

  std::stringstream output_stream;
  stan::interface_callbacks::writer::stream_writer writer(output_stream);
  std::stringstream error_stream;
  stan::interface_callbacks::writer::stream_writer error_writer(error_stream);

  std::fstream empty_stream("", std::fstream::in);
  stan::io::dump data_var_context(empty_stream);
  gauss3D_model_namespace::gauss3D_model model(data_var_context);

  stan::mcmc::unit_e_nuts<gauss3D_model_namespace::gauss3D_model, rng_t>
    sampler(model, base_rng);

  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.set_nominal_stepsize(0.1);
  sampler.set_stepsize_jitter(0);
  sampler.sample_stepsize();

  stan::mcmc::sample init_sample(z_init.q, 0, 0);

  stan::mcmc::sample s = sampler.transition(init_sample, writer, error_writer);

  EXPECT_EQ(4, sampler.depth_);
  EXPECT_EQ((2 << 3) - 1, sampler.n_leapfrog_);
  EXPECT_FALSE(sampler.divergent_);

  EXPECT_FLOAT_EQ(1.8718261, s.cont_params()(0));
  EXPECT_FLOAT_EQ(-0.74208695, s.cont_params()(1));
  EXPECT_FLOAT_EQ( 1.5202962, s.cont_params()(2));
  EXPECT_FLOAT_EQ(-3.1828632, s.log_prob());
  EXPECT_FLOAT_EQ(0.99629009, s.accept_stat());
  EXPECT_EQ("", output_stream.str());
  EXPECT_EQ("", error_stream.str());
}
예제 #6
0
TEST(McmcUnitENuts, tree_boundary_test) {
  rng_t base_rng(4839294);

  stan::mcmc::unit_e_point z_init(3);
  z_init.q(0) = 1;
  z_init.q(1) = -1;
  z_init.q(2) = 1;
  z_init.p(0) = -1;
  z_init.p(1) = 1;
  z_init.p(2) = -1;

  std::stringstream output;
  stan::interface_callbacks::writer::stream_writer writer(output);
  std::stringstream error_stream;
  stan::interface_callbacks::writer::stream_writer error_writer(error_stream);

  std::fstream empty_stream("", std::fstream::in);
  stan::io::dump data_var_context(empty_stream);

  typedef gauss3D_model_namespace::gauss3D_model model_t;
  model_t model(data_var_context);

  // Compute expected tree boundaries
  typedef stan::mcmc::unit_e_metric<model_t, rng_t> metric_t;
  metric_t metric(model);

  stan::mcmc::expl_leapfrog<metric_t> unit_e_integrator;
  double epsilon = 0.1;

  stan::mcmc::unit_e_point z_test = z_init;
  metric.init(z_test, writer, error_writer);

  unit_e_integrator.evolve(z_test, metric, epsilon, writer, error_writer);
  Eigen::VectorXd p_sharp_forward_1 = metric.dtau_dp(z_test);

  unit_e_integrator.evolve(z_test, metric, epsilon, writer, error_writer);
  Eigen::VectorXd p_sharp_forward_2 = metric.dtau_dp(z_test);

  unit_e_integrator.evolve(z_test, metric, epsilon, writer, error_writer);
  unit_e_integrator.evolve(z_test, metric, epsilon, writer, error_writer);
  Eigen::VectorXd p_sharp_forward_3 = metric.dtau_dp(z_test);

  unit_e_integrator.evolve(z_test, metric, epsilon, writer, error_writer);
  unit_e_integrator.evolve(z_test, metric, epsilon, writer, error_writer);
  unit_e_integrator.evolve(z_test, metric, epsilon, writer, error_writer);
  unit_e_integrator.evolve(z_test, metric, epsilon, writer, error_writer);
  Eigen::VectorXd p_sharp_forward_4 = metric.dtau_dp(z_test);

  z_test = z_init;
  metric.init(z_test, writer, error_writer);

  unit_e_integrator.evolve(z_test, metric, -epsilon, writer, error_writer);
  Eigen::VectorXd p_sharp_backward_1 = metric.dtau_dp(z_test);

  unit_e_integrator.evolve(z_test, metric, -epsilon, writer, error_writer);
  Eigen::VectorXd p_sharp_backward_2 = metric.dtau_dp(z_test);

  unit_e_integrator.evolve(z_test, metric, -epsilon, writer, error_writer);
  unit_e_integrator.evolve(z_test, metric, -epsilon, writer, error_writer);
  Eigen::VectorXd p_sharp_backward_3 = metric.dtau_dp(z_test);

  unit_e_integrator.evolve(z_test, metric, -epsilon, writer, error_writer);
  unit_e_integrator.evolve(z_test, metric, -epsilon, writer, error_writer);
  unit_e_integrator.evolve(z_test, metric, -epsilon, writer, error_writer);
  unit_e_integrator.evolve(z_test, metric, -epsilon, writer, error_writer);
  Eigen::VectorXd p_sharp_backward_4 = metric.dtau_dp(z_test);

  // Check expected tree boundaries to those dynamically geneated by NUTS
  stan::mcmc::unit_e_nuts<model_t, rng_t> sampler(model, base_rng);

  sampler.set_nominal_stepsize(epsilon);
  sampler.set_stepsize_jitter(0);
  sampler.sample_stepsize();

  stan::mcmc::ps_point z_propose = z_init;

  Eigen::VectorXd p_sharp_left = Eigen::VectorXd::Zero(z_init.p.size());
  Eigen::VectorXd p_sharp_right = Eigen::VectorXd::Zero(z_init.p.size());
  Eigen::VectorXd rho = z_init.p;
  double log_sum_weight = -std::numeric_limits<double>::infinity();

  double H0 = -0.1;
  int n_leapfrog = 0;
  double sum_metro_prob = 0;

  // Depth 0 forward
  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.build_tree(0, z_propose,
                     p_sharp_left, p_sharp_right, rho,
                     H0, 1, n_leapfrog, log_sum_weight,
                     sum_metro_prob,
                     writer, error_writer);

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_forward_1(n), p_sharp_left(n));

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_forward_1(n), p_sharp_right(n));

  // Depth 1 forward
  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.build_tree(1, z_propose,
                     p_sharp_left, p_sharp_right, rho,
                     H0, 1, n_leapfrog, log_sum_weight,
                     sum_metro_prob,
                     writer, error_writer);

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_forward_1(n), p_sharp_left(n));

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_forward_2(n), p_sharp_right(n));

  // Depth 2 forward
  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.build_tree(2, z_propose,
                     p_sharp_left, p_sharp_right, rho,
                     H0, 1, n_leapfrog, log_sum_weight,
                     sum_metro_prob,
                     writer, error_writer);

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_forward_1(n), p_sharp_left(n));

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_forward_3(n), p_sharp_right(n));

  // Depth 3 forward
  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.build_tree(3, z_propose,
                     p_sharp_left, p_sharp_right, rho,
                     H0, 1, n_leapfrog, log_sum_weight,
                     sum_metro_prob,
                     writer, error_writer);

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_forward_1(n), p_sharp_left(n));

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_forward_4(n), p_sharp_right(n));

  // Depth 0 backward
  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.build_tree(0, z_propose,
                     p_sharp_left, p_sharp_right, rho,
                     H0, -1, n_leapfrog, log_sum_weight,
                     sum_metro_prob,
                     writer, error_writer);

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_backward_1(n), p_sharp_left(n));

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_backward_1(n), p_sharp_right(n));

  // Depth 1 backward
  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.build_tree(1, z_propose,
                     p_sharp_left, p_sharp_right, rho,
                     H0, -1, n_leapfrog, log_sum_weight,
                     sum_metro_prob,
                     writer, error_writer);

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_backward_1(n), p_sharp_left(n));

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_backward_2(n), p_sharp_right(n));

  // Depth 2 backward
  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.build_tree(2, z_propose,
                     p_sharp_left, p_sharp_right, rho,
                     H0, -1, n_leapfrog, log_sum_weight,
                     sum_metro_prob,
                     writer, error_writer);

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_backward_1(n), p_sharp_left(n));

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_backward_3(n), p_sharp_right(n));

  // Depth 3 backward
  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.build_tree(3, z_propose,
                     p_sharp_left, p_sharp_right, rho,
                     H0, -1, n_leapfrog, log_sum_weight,
                     sum_metro_prob,
                     writer, error_writer);

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_backward_1(n), p_sharp_left(n));

  for (int n = 0; n < rho.size(); ++n)
    EXPECT_FLOAT_EQ(p_sharp_backward_4(n), p_sharp_right(n));
}
예제 #7
0
TEST(McmcUnitENuts, build_tree_test) {
  rng_t base_rng(4839294);

  stan::mcmc::unit_e_point z_init(3);
  z_init.q(0) = 1;
  z_init.q(1) = -1;
  z_init.q(2) = 1;
  z_init.p(0) = -1;
  z_init.p(1) = 1;
  z_init.p(2) = -1;

  std::stringstream output;
  stan::interface_callbacks::writer::stream_writer writer(output);
  std::stringstream error_stream;
  stan::interface_callbacks::writer::stream_writer error_writer(error_stream);

  std::fstream empty_stream("", std::fstream::in);
  stan::io::dump data_var_context(empty_stream);
  gauss3D_model_namespace::gauss3D_model model(data_var_context);

  stan::mcmc::unit_e_nuts<gauss3D_model_namespace::gauss3D_model, rng_t>
    sampler(model, base_rng);

  sampler.z() = z_init;
  sampler.init_hamiltonian(writer, error_writer);
  sampler.set_nominal_stepsize(0.1);
  sampler.set_stepsize_jitter(0);
  sampler.sample_stepsize();

  stan::mcmc::ps_point z_propose = z_init;

  Eigen::VectorXd p_sharp_left = Eigen::VectorXd::Zero(z_init.p.size());
  Eigen::VectorXd p_sharp_right = Eigen::VectorXd::Zero(z_init.p.size());
  Eigen::VectorXd rho = z_init.p;
  double log_sum_weight = -std::numeric_limits<double>::infinity();

  double H0 = -0.1;
  int n_leapfrog = 0;
  double sum_metro_prob = 0;

  bool valid_subtree = sampler.build_tree(3, z_propose,
                                          p_sharp_left, p_sharp_right, rho,
                                          H0, 1, n_leapfrog, log_sum_weight,
                                          sum_metro_prob,
                                          writer, error_writer);

  EXPECT_EQ(0.1, sampler.get_nominal_stepsize());

  EXPECT_TRUE(valid_subtree);

  EXPECT_FLOAT_EQ(-11.401228, rho(0));
  EXPECT_FLOAT_EQ(11.401228, rho(1));
  EXPECT_FLOAT_EQ(-11.401228, rho(2));

  EXPECT_FLOAT_EQ(-0.022019938, sampler.z().q(0));
  EXPECT_FLOAT_EQ(0.022019938, sampler.z().q(1));
  EXPECT_FLOAT_EQ(-0.022019938, sampler.z().q(2));

  EXPECT_FLOAT_EQ(-1.4131583, sampler.z().p(0));
  EXPECT_FLOAT_EQ(1.4131583, sampler.z().p(1));
  EXPECT_FLOAT_EQ(-1.4131583, sampler.z().p(2));

  EXPECT_EQ(8, n_leapfrog);
  EXPECT_FLOAT_EQ(std::log(0.36134657), log_sum_weight);
  EXPECT_FLOAT_EQ(0.36134657, sum_metro_prob);

  EXPECT_EQ("", output.str());
  EXPECT_EQ("", error_stream.str());
}
예제 #8
0
TEST(McmcHmcIntegratorsImplLeapfrog, unit_e_symplecticness) {
  rng_t base_rng(0);

  std::fstream data_stream(std::string("").c_str(), std::fstream::in);
  stan::io::dump data_var_context(data_stream);
  data_stream.close();

  std::stringstream model_output;
  std::stringstream metric_output;
  stan::interface_callbacks::writer::stream_writer writer(metric_output);
  std::stringstream error_stream;
  stan::interface_callbacks::writer::stream_writer error_writer(error_stream);

  gauss_model_namespace::gauss_model model(data_var_context, &model_output);

  stan::mcmc::impl_leapfrog<
    stan::mcmc::unit_e_metric<gauss_model_namespace::gauss_model, rng_t> >
    integrator;

  stan::mcmc::unit_e_metric<gauss_model_namespace::gauss_model, rng_t> metric(model);

  // Create a circle of points
  const int n_points = 1000;

  double pi = 3.141592653589793;
  double r = 1.5;
  double q0 = 1;
  double p0 = 0;

  std::vector<stan::mcmc::unit_e_point> z;

  for (int i = 0; i < n_points; ++i) {
    z.push_back(stan::mcmc::unit_e_point(1));

    double theta = 2 * pi * (double)i / (double)n_points;
    z.back().q(0) = r * cos(theta) + q0;
    z.back().p(0)    = r * sin(theta) + p0;
  }

  // Evolve circle
  double epsilon = 1e-3;
  size_t L = pi / epsilon;

  for (int i = 0; i < n_points; ++i)
    metric.init(z.at(i), writer, error_writer);

  for (size_t n = 0; n < L; ++n)
    for (int i = 0; i < n_points; ++i)
      integrator.evolve(z.at(i), metric, epsilon, writer, error_writer);

  // Compute area of evolved shape using divergence theorem in 2D
  double area = 0;

  for (int i = 0; i < n_points; ++i) {

    double x1 = z[i].q(0);
    double y1 = z[i].p(0);
    double x2 = z[(i + 1) % n_points].q(0);
    double y2 = z[(i + 1) % n_points].p(0);

    double x_bary = 0.5 * (x1 + x2);
    double y_bary = 0.5 * (y1 + y2);

    double x_delta = x2 - x1;
    double y_delta = y2 - y1;

    double a = sqrt( x_delta * x_delta + y_delta * y_delta);

    double x_norm = 1;
    double y_norm = - x_delta / y_delta;
    double norm = sqrt( x_norm * x_norm + y_norm * y_norm );

    a *= (x_bary * x_norm + y_bary * y_norm) / norm;
    a = a < 0 ? -a : a;

    area += a;

  }

  area *= 0.5;

  // Symplectic integrators preserve volume (area in 2D)
  EXPECT_NEAR(area, pi * r * r, 1e-2);


  EXPECT_EQ("", model_output.str());
  EXPECT_EQ("", metric_output.str());
}