TEST(BaseHamiltonian, update) { 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, metric_output; funnel_model_namespace::funnel_model model(data_var_context, &model_output); stan::mcmc::mock_hamiltonian<funnel_model_namespace::funnel_model, rng_t> metric(model, &metric_output); stan::mcmc::ps_point z(11); z.q.setOnes(); metric.update(z); EXPECT_FLOAT_EQ(10.73223197, z.V); EXPECT_FLOAT_EQ(8.757758279, z.g(0)); for (int i = 1; i < z.q.size(); ++i) EXPECT_FLOAT_EQ(0.1353352832, z.g(i)); EXPECT_EQ("", model_output.str()); EXPECT_EQ("", metric_output.str()); }
TEST(advi_test, hier_logistic_cp_constraint_meanfield) { // Create mock data_var_context std::fstream data_stream("src/test/test-models/good/variational/hier_logistic.data.R", std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); std::stringstream output; output.clear(); // Instantiate model Model_cp my_model(data_var_context); // RNG rng_t base_rng(0); // Dummy input Eigen::VectorXd cont_params = Eigen::VectorXd::Zero(my_model.num_params_r()); // ADVI stan::variational::advi<Model_cp, stan::variational::normal_meanfield, rng_t> test_advi(my_model, cont_params, base_rng, 10, 100, 100, 1); stan::interface_callbacks::writer::noop_writer writer; test_advi.run(0.01, false, 50, 1, 2e4, writer, writer, writer); }
TEST(ModelUtil, grad_tr_mat_times_hessian) { int dim = 5; Eigen::VectorXd x(dim); Eigen::MatrixXd X = Eigen::MatrixXd::Identity(dim, dim); Eigen::VectorXd grad_tr_X_hess_f(dim); std::fstream data_stream(std::string("").c_str(), std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); valid_model_namespace::valid_model valid_model(data_var_context, &std::cout); EXPECT_NO_THROW(stan::model::grad_tr_mat_times_hessian(valid_model, x, X, grad_tr_X_hess_f)); EXPECT_FLOAT_EQ(dim, x.size()); EXPECT_FLOAT_EQ(dim, X.rows()); EXPECT_FLOAT_EQ(dim, X.cols()); EXPECT_FLOAT_EQ(dim, grad_tr_X_hess_f.size()); // Incorporate once operands and partials has been generalized //domain_fail_namespace::domain_fail domain_fail_model(data_var_context, &std::cout); //EXPECT_THROW(stan::model::grad_tr_mat_times_hessian(domain_fail_model, x, X, grad_tr_X_hess_f), // std::domain_error); }
void SetUp() { err_msg1 = "Informational Message: The maximum number of iterations is reached!"; err_msg2 = "Informational Message: The ELBO at a previous iteration is larger than the ELBO upon convergence!"; // Create mock data_var_context static const std::string DATA = ""; std::stringstream data_stream(DATA); stan::io::dump data_var_context(data_stream); // data_stream.close(); model_ = new stan_model(data_var_context, &model_stream_); cont_params_ = Eigen::VectorXd::Zero(model_->num_params_r()); base_rng_.seed(3021828106u); model_stream_.str(""); message_stream_.str(""); parameter_stream_.str(""); diagnostic_stream_.str(""); advi_meanfield_ = new stan::variational::advi<stan_model, stan::variational::normal_meanfield, rng_t> (*model_, cont_params_, base_rng_, 1, 100, 1, 1); advi_fullrank_ = new stan::variational::advi<stan_model, stan::variational::normal_fullrank, rng_t> (*model_, cont_params_, base_rng_, 1, 100, 1, 1); }
void SetUp() { // Create mock data_var_context std::fstream data_stream("src/test/test-models/good/variational/hier_logistic.data.R", std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); model_ = new stan_model(data_var_context, 0, &model_stream_); model_null_stream_ = new stan_model(data_var_context, 0, NULL); base_rng_.seed(0); cont_params_ = Eigen::VectorXd::Zero(model_->num_params_r()); model_stream_.str(""); message_stream_.str(""); parameter_stream_.str(""); diagnostic_stream_.str(""); advi_ = new stan::variational::advi<stan_model, stan::variational::normal_meanfield, rng_t> (*model_, cont_params_, base_rng_, 10, 100, 100, 1); advi_fullrank_ = new stan::variational::advi<stan_model, stan::variational::normal_fullrank, rng_t> (*model_, cont_params_, base_rng_, 10, 100, 100, 1); }
TEST(ModelUtil, hessian_times_vector) { int dim = 5; Eigen::VectorXd x(dim); Eigen::VectorXd v(dim); double f; Eigen::VectorXd hess_f_dot_v(dim); std::fstream data_stream(std::string("").c_str(), std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); valid_model_namespace::valid_model valid_model(data_var_context, &std::cout); EXPECT_NO_THROW(stan::model::hessian_times_vector(valid_model, x, v, f, hess_f_dot_v)); EXPECT_FLOAT_EQ(dim, x.size()); EXPECT_FLOAT_EQ(dim, v.size()); EXPECT_FLOAT_EQ(dim, hess_f_dot_v.size()); // Incorporate once operands and partials has been generalized //domain_fail_namespace::domain_fail domain_fail_model(data_var_context, &std::cout); //EXPECT_THROW(stan::model::hessian_times_vector(domain_fail_model, x, v, f, hess_f_dot_v), // std::domain_error); }
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); }
void SetUp() { static const std::string DATA = "mu <- 0.0\ny <- 0\n"; std::stringstream data_stream(DATA); // setup hamiltonian stan::io::dump data_var_context(data_stream); model = new command_model_namespace::command_model(data_var_context); }
TEST(StanIoMcmcWriter, write_diagnostic_names) { // Model std::fstream data_stream("", std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); std::stringstream output; io_example_model_namespace::io_example_model model(data_var_context, &output); // Sample Eigen::VectorXd real(2); real(0) = 1.43; real(1) = 2.71; double log_prob = 3.14; double accept_stat = 0.84; stan::mcmc::sample sample(real, log_prob, accept_stat); // Sampler typedef boost::ecuyer1988 rng_t; rng_t base_rng(0); stan::mcmc::adapt_diag_e_nuts<io_example_model_namespace::io_example_model, rng_t> sampler(model, base_rng, 0, 0); sampler.seed(real); // Writer std::stringstream sample_stream; std::stringstream diagnostic_stream; std::stringstream message_stream; stan::interface::recorder::csv sample_recorder(&sample_stream, "# "); stan::interface::recorder::csv diagnostic_recorder(&diagnostic_stream, "# "); stan::interface::recorder::messages message_recorder(&message_stream, "# "); stan::io::mcmc_writer<io_example_model_namespace::io_example_model, stan::interface::recorder::csv, stan::interface::recorder::csv, stan::interface::recorder::messages> writer(sample_recorder, diagnostic_recorder, message_recorder); writer.write_diagnostic_names(sample, &sampler, model); std::string line; std::getline(diagnostic_stream, line); // FIXME: make this work, too EXPECT_EQ("lp__,accept_stat__,stepsize__,treedepth__,n_leapfrog__,n_divergent__,mu1,mu2,p_mu1,p_mu2,g_mu1,g_mu2", line); EXPECT_EQ("", message_stream.str()); EXPECT_EQ("", output.str()); }
void SetUp() { static const std::string DATA("mu <- 0.0\ny <- 0\n"); std::stringstream data_stream(DATA); // setup hamiltonian stan::io::dump data_var_context(data_stream); model = new command_model_namespace::command_model(data_var_context); debug.str(""); info.str(""); warn.str(""); error.str(""); fatal.str(""); }
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 debug, info, warn, error, fatal; stan::callbacks::stream_logger logger(debug, info, warn, error, fatal); 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, logger); 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, logger); 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("", debug.str()); EXPECT_EQ("", info.str()); EXPECT_EQ("", warn.str()); EXPECT_EQ("", error.str()); EXPECT_EQ("", fatal.str()); }
TEST(ModelUtil, streams) { stan::test::capture_std_streams(); std::fstream data_stream(std::string("").c_str(), std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); stan_model model(data_var_context, static_cast<std::stringstream*>(0)); std::vector<double> params_r(1); std::vector<int> params_i(0); std::vector<double> gradient; std::stringstream out; try { stan::model::log_prob_propto<true, stan_model>(model, params_r, params_i, 0); stan::model::log_prob_propto<false, stan_model>(model, params_r, params_i, 0); out.str(""); stan::model::log_prob_propto<true, stan_model>(model, params_r, params_i, &out); stan::model::log_prob_propto<false, stan_model>(model, params_r, params_i, &out); EXPECT_EQ("", out.str()); } catch (...) { FAIL() << "log_prob_propto"; } try { Eigen::VectorXd p(1); stan::model::log_prob_propto<true, stan_model>(model, p, 0); stan::model::log_prob_propto<false, stan_model>(model, p, 0); out.str(""); stan::model::log_prob_propto<true, stan_model>(model, p, &out); stan::model::log_prob_propto<false, stan_model>(model, p, &out); EXPECT_EQ("", out.str()); } catch (...) { FAIL() << "log_prob_propto"; } stan::test::reset_std_streams(); EXPECT_EQ("", stan::test::cout_ss.str()); EXPECT_EQ("", stan::test::cerr_ss.str()); }
TEST(BaseHamiltonian, streams) { stan::test::capture_std_streams(); std::fstream data_stream(std::string("").c_str(), std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); EXPECT_NO_THROW(funnel_model_namespace::funnel_model model(data_var_context, 0)); std::stringstream output; EXPECT_NO_THROW(funnel_model_namespace::funnel_model model(data_var_context, &output)); EXPECT_EQ("", output.str()); stan::test::reset_std_streams(); EXPECT_EQ("", stan::test::cout_ss.str()); EXPECT_EQ("", stan::test::cerr_ss.str()); }
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()); }
TEST(McmcHmcIntegratorsExplLeapfrog, 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(); gauss_namespace::gauss model(data_var_context, &std::cout); stan::mcmc::expl_leapfrog< stan::mcmc::unit_e_metric<gauss_namespace::gauss, rng_t>, stan::mcmc::unit_e_point> integrator; stan::mcmc::unit_e_metric<gauss_namespace::gauss, rng_t> metric(model, &std::cout); stan::mcmc::unit_e_point z(1); z.q(0) = 1; z.p(0) = 1; metric.update(z); 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); 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 gaussian case due to cancellations EXPECT_NEAR(aveDeltaH, 0, epsilon * epsilon); }
TEST(ModelUtil, streams) { stan::test::capture_std_streams(); std::fstream data_stream(std::string("").c_str(), std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); stan_model model(data_var_context, static_cast<std::stringstream*>(0)); std::vector<double> params_r(1); std::vector<int> params_i(0); std::vector<double> gradient; stan::callbacks::interrupt interrupt; std::stringstream out; try { stan::callbacks::stream_writer writer(out); stan::test::unit::instrumented_logger logger; out.str(""); stan::model::test_gradients<true, true, stan_model>(model, params_r, params_i, 1e-6, 1e-6, interrupt, logger, writer); EXPECT_EQ("\n Log probability=0\n\n param idx value model finite diff error\n 0 0 0 0 0\n", out.str()); out.str(""); stan::model::test_gradients<true, false, stan_model>(model, params_r, params_i, 1e-6, 1e-6, interrupt, logger, writer); EXPECT_EQ("\n Log probability=0\n\n param idx value model finite diff error\n 0 0 0 0 0\n", out.str()); out.str(""); stan::model::test_gradients<false, true, stan_model>(model, params_r, params_i, 1e-6, 1e-6, interrupt, logger, writer); EXPECT_EQ("\n Log probability=0\n\n param idx value model finite diff error\n 0 0 0 0 0\n", out.str()); out.str(""); stan::model::test_gradients<false, false, stan_model>(model, params_r, params_i, 1e-6, 1e-6, interrupt, logger, writer); EXPECT_EQ("\n Log probability=0\n\n param idx value model finite diff error\n 0 0 0 0 0\n", out.str()); } catch (...) { FAIL() << "test_gradients"; } stan::test::reset_std_streams(); EXPECT_EQ("", stan::test::cout_ss.str()); EXPECT_EQ("", stan::test::cerr_ss.str()); }
void SetUp() { static const std::string DATA = ""; std::stringstream data_stream(DATA); stan::io::dump data_var_context(data_stream); model_ = new stan_model(data_var_context, &model_stream_); cont_params_ = Eigen::VectorXd::Zero(model_->num_params_r()); base_rng_.seed(927802408); model_stream_.str(""); message_stream_.str(""); advi_meanfield_ = new stan::variational::advi<stan_model, stan::variational::normal_meanfield, rng_t> (*model_, cont_params_, base_rng_, 1, 1, 100, 1); advi_fullrank_ = new stan::variational::advi<stan_model, stan::variational::normal_fullrank, rng_t> (*model_, cont_params_, base_rng_, 1, 1, 100, 1); }
TEST(ModelUtil, gradient) { int dim = 5; Eigen::VectorXd x(dim); double f; Eigen::VectorXd g(dim); std::fstream data_stream(std::string("").c_str(), std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); valid_model_namespace::valid_model valid_model(data_var_context, &std::cout); EXPECT_NO_THROW(stan::model::gradient(valid_model, x, f, g)); EXPECT_FLOAT_EQ(dim, x.size()); EXPECT_FLOAT_EQ(dim, g.size()); // Incorporate once operands and partials has been generalized //domain_fail_namespace::domain_fail domain_fail_model(data_var_context, &std::cout); //EXPECT_THROW(stan::model::gradient(domain_fail_model, x, f, g), std::domain_error); }
void SetUp() { std::fstream data_stream("src/test/test-models/good/variational/gradient_warn.data.R", std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); model_ = new stan_model(data_var_context, &model_stream_); cont_params_ = Eigen::VectorXd::Zero(model_->num_params_r()); base_rng_.seed(3021828106u); model_stream_.str(""); message_stream_.str(""); parameter_stream_.str(""); diagnostic_stream_.str(""); advi_meanfield_ = new stan::variational::advi<stan_model, stan::variational::normal_meanfield, rng_t> (*model_, cont_params_, base_rng_, 1, 100, 100, 1); advi_fullrank_ = new stan::variational::advi<stan_model, stan::variational::normal_fullrank, rng_t> (*model_, cont_params_, base_rng_, 1, 100, 100, 1); }
TEST(McmcDenseEMetric, gradients) { rng_t base_rng(0); Eigen::VectorXd q = Eigen::VectorXd::Ones(11); stan::mcmc::dense_e_point z(q.size()); z.q = q; z.p.setOnes(); 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 debug, info, warn, error, fatal; stan::callbacks::stream_logger logger(debug, info, warn, error, fatal); funnel_model_namespace::funnel_model model(data_var_context, &model_output); stan::mcmc::dense_e_metric<funnel_model_namespace::funnel_model, rng_t> metric(model); double epsilon = 1e-6; metric.init(z, logger); Eigen::VectorXd g1 = metric.dtau_dq(z, logger); for (int i = 0; i < z.q.size(); ++i) { double delta = 0; z.q(i) += epsilon; metric.update_potential(z, logger); delta += metric.tau(z); z.q(i) -= 2 * epsilon; metric.update_potential(z, logger); delta -= metric.tau(z); z.q(i) += epsilon; metric.update_potential(z, logger); delta /= 2 * epsilon; EXPECT_NEAR(delta, g1(i), epsilon); } Eigen::VectorXd g2 = metric.dtau_dp(z); for (int i = 0; i < z.q.size(); ++i) { double delta = 0; z.p(i) += epsilon; delta += metric.tau(z); z.p(i) -= 2 * epsilon; delta -= metric.tau(z); z.p(i) += epsilon; delta /= 2 * epsilon; EXPECT_NEAR(delta, g2(i), epsilon); } Eigen::VectorXd g3 = metric.dphi_dq(z, logger); for (int i = 0; i < z.q.size(); ++i) { double delta = 0; z.q(i) += epsilon; metric.update_potential(z, logger); delta += metric.phi(z); z.q(i) -= 2 * epsilon; metric.update_potential(z, logger); delta -= metric.phi(z); z.q(i) += epsilon; metric.update_potential(z, logger); delta /= 2 * epsilon; EXPECT_NEAR(delta, g3(i), epsilon); } EXPECT_EQ("", model_output.str()); EXPECT_EQ("", debug.str()); EXPECT_EQ("", info.str()); EXPECT_EQ("", warn.str()); EXPECT_EQ("", error.str()); EXPECT_EQ("", fatal.str()); }
TEST(McmcDiagEMetric, gradients) { rng_t base_rng(0); Eigen::VectorXd q = Eigen::VectorXd::Ones(11); stan::mcmc::diag_e_point z(q.size()); z.q = q; z.p.setOnes(); 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, metric_output; funnel_model_namespace::funnel_model model(data_var_context, &model_output); stan::mcmc::diag_e_metric<funnel_model_namespace::funnel_model, rng_t> metric(model, &metric_output); double epsilon = 1e-6; metric.update(z); Eigen::VectorXd g1 = metric.dtau_dq(z); for (int i = 0; i < z.q.size(); ++i) { double delta = 0; z.q(i) += epsilon; metric.update(z); delta += metric.tau(z); z.q(i) -= 2 * epsilon; metric.update(z); delta -= metric.tau(z); z.q(i) += epsilon; metric.update(z); delta /= 2 * epsilon; EXPECT_NEAR(delta, g1(i), epsilon); } Eigen::VectorXd g2 = metric.dtau_dp(z); for (int i = 0; i < z.q.size(); ++i) { double delta = 0; z.p(i) += epsilon; delta += metric.tau(z); z.p(i) -= 2 * epsilon; delta -= metric.tau(z); z.p(i) += epsilon; delta /= 2 * epsilon; EXPECT_NEAR(delta, g2(i), epsilon); } Eigen::VectorXd g3 = metric.dphi_dq(z); for (int i = 0; i < z.q.size(); ++i) { double delta = 0; z.q(i) += epsilon; metric.update(z); delta += metric.phi(z); z.q(i) -= 2 * epsilon; metric.update(z); delta -= metric.phi(z); z.q(i) += epsilon; metric.update(z); delta /= 2 * epsilon; EXPECT_NEAR(delta, g3(i), epsilon); } EXPECT_EQ("", model_output.str()); EXPECT_EQ("", metric_output.str()); }
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)); }
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()); }
TEST(StanIoMcmcWriter, write_adapt_finish) { // Model std::fstream data_stream("", std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); std::stringstream output; io_example_model_namespace::io_example_model model(data_var_context, &output); // Sample Eigen::VectorXd real(2); real(0) = 1.43; real(1) = 2.71; double log_prob = 3.14; double accept_stat = 0.84; stan::mcmc::sample sample(real, log_prob, accept_stat); // Sampler typedef boost::ecuyer1988 rng_t; rng_t base_rng(0); stan::mcmc::adapt_diag_e_nuts<io_example_model_namespace::io_example_model, rng_t> sampler(model, base_rng, 0, 0); sampler.seed(real); // Writer std::stringstream sample_stream; std::stringstream diagnostic_stream; std::stringstream message_stream; stan::interface::recorder::csv sample_recorder(&sample_stream, "# "); stan::interface::recorder::csv diagnostic_recorder(&diagnostic_stream, "# "); stan::interface::recorder::messages message_recorder(&message_stream, "# "); stan::io::mcmc_writer<io_example_model_namespace::io_example_model, stan::interface::recorder::csv, stan::interface::recorder::csv, stan::interface::recorder::messages> writer(sample_recorder, diagnostic_recorder, message_recorder); writer.write_adapt_finish(&sampler); std::stringstream expected_stream; expected_stream << "# Adaptation terminated" << std::endl; expected_stream << "# Step size = " << sampler.get_current_stepsize() << std::endl; expected_stream << "# Diagonal elements of inverse mass matrix:" << std::endl; expected_stream << "# " << sampler.z().mInv(0) << ", " << sampler.z().mInv(1) << std::endl; std::string line; std::string expected_line; // Line 1 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); // Line 2 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); // Line 3 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); // Line 4 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); EXPECT_EQ("", message_stream.str()); EXPECT_EQ("", output.str()); }
TEST(StanIoMcmcWriter, write_timing) { // Model std::fstream data_stream("", std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); std::stringstream output; io_example_model_namespace::io_example_model model(data_var_context, &output); // Sample Eigen::VectorXd real(2); real(0) = 1.43; real(1) = 2.71; double log_prob = 3.14; double accept_stat = 0.84; stan::mcmc::sample sample(real, log_prob, accept_stat); // Sampler typedef boost::ecuyer1988 rng_t; rng_t base_rng(0); stan::mcmc::adapt_diag_e_nuts<io_example_model_namespace::io_example_model, rng_t> sampler(model, base_rng, 0, 0); sampler.seed(real); // Writer std::stringstream sample_stream; std::stringstream diagnostic_stream; std::stringstream message_stream; stan::interface::recorder::csv sample_recorder(&sample_stream, "# "); stan::interface::recorder::csv diagnostic_recorder(&diagnostic_stream, "# "); stan::interface::recorder::messages message_recorder(&message_stream, "# "); stan::io::mcmc_writer<io_example_model_namespace::io_example_model, stan::interface::recorder::csv, stan::interface::recorder::csv, stan::interface::recorder::messages> writer(sample_recorder, diagnostic_recorder, message_recorder); double warm = 0.193933; double sampling = 0.483830; writer.write_timing(warm, sampling, sample_recorder); std::stringstream expected_stream; expected_stream << std::endl; expected_stream << "# Elapsed Time: " << warm << " seconds (Warm-up)" << std::endl; expected_stream << "# " << sampling << " seconds (Sampling)" << std::endl; expected_stream << "# " << warm + sampling << " seconds (Total)" << std::endl; expected_stream << std::endl; std::string line; std::string expected_line; // Line 1 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); // Line 2 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); // Line 3 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); // Line 4 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); // Line 5 std::getline(expected_stream, expected_line); std::getline(sample_stream, line); EXPECT_EQ(expected_line, line); std::getline(diagnostic_stream, line); EXPECT_EQ(expected_line, line); EXPECT_EQ("", message_stream.str()); EXPECT_EQ("", output.str()); }
TEST(McmcHmcIntegratorsExplLeapfrog, 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(); gauss_namespace::gauss model(data_var_context, &std::cout); stan::mcmc::expl_leapfrog< stan::mcmc::unit_e_metric<gauss_namespace::gauss, rng_t>, stan::mcmc::unit_e_point> integrator; stan::mcmc::unit_e_metric<gauss_namespace::gauss, rng_t> metric(model, &std::cout); // 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)); for (size_t n = 0; n < L; ++n) for (int i = 0; i < n_points; ++i) integrator.evolve(z.at(i), metric, epsilon); // 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); }
TEST(StanIoMcmcWriter, write_sample_params) { // Model std::fstream data_stream("", std::fstream::in); stan::io::dump data_var_context(data_stream); data_stream.close(); std::stringstream output; io_example_model_namespace::io_example_model model(data_var_context, &output); // Sample Eigen::VectorXd real(2); real(0) = 1.43; real(1) = 2.71; double log_prob = 3.14; double accept_stat = 0.84; stan::mcmc::sample sample(real, log_prob, accept_stat); // Sampler typedef boost::ecuyer1988 rng_t; rng_t base_rng(0); stan::mcmc::adapt_diag_e_nuts<io_example_model_namespace::io_example_model, rng_t> sampler(model, base_rng, 0, 0); sampler.seed(real); // Writer std::stringstream sample_stream; std::stringstream diagnostic_stream; std::stringstream message_stream; stan::interface::recorder::csv sample_recorder(&sample_stream, "# "); stan::interface::recorder::csv diagnostic_recorder(&diagnostic_stream, "# "); stan::interface::recorder::messages message_recorder(&message_stream, "# "); stan::io::mcmc_writer<io_example_model_namespace::io_example_model, stan::interface::recorder::csv, stan::interface::recorder::csv, stan::interface::recorder::messages> writer(sample_recorder, diagnostic_recorder, message_recorder); writer.write_sample_params<rng_t>(base_rng, sample, sampler, model); std::string line; std::getline(sample_stream, line); std::stringstream expected_stream; expected_stream << log_prob << ","; expected_stream << accept_stat << ","; expected_stream << sampler.get_current_stepsize() << ","; expected_stream << 0 << ","; expected_stream << 0 << ","; expected_stream << 0 << ","; expected_stream << real(0) << ","; expected_stream << real(1); std::string expected_line; std::getline(expected_stream, expected_line); EXPECT_EQ(expected_line, line); EXPECT_EQ("", message_stream.str()); EXPECT_EQ("", output.str()); }