Skip to content

Commit cd8b2e0

Browse files
authored
Merge pull request #3071 from nhuurre/zero-dim-metric
Fix size-zero mass matrix
2 parents 21cef93 + 522a34f commit cd8b2e0

File tree

5 files changed

+23
-3
lines changed

5 files changed

+23
-3
lines changed

src/stan/mcmc/hmc/base_hmc.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ class base_hmc : public base_mcmc {
9393
void init_stepsize(callbacks::logger& logger) {
9494
ps_point z_init(this->z_);
9595

96+
// step size is meaningless in zero-dimensional space
97+
if (this->z_.q.size() == 0) {
98+
this->nom_epsilon_ = std::numeric_limits<double>::quiet_NaN();
99+
return;
100+
}
101+
96102
// Skip initialization for extreme step sizes
97103
if (this->nom_epsilon_ == 0 || this->nom_epsilon_ > 1e7
98104
|| std::isnan(this->nom_epsilon_))

src/stan/mcmc/hmc/hamiltonians/dense_e_point.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class dense_e_point : public ps_point {
4343
*/
4444
inline void write_metric(stan::callbacks::writer& writer) {
4545
writer("Elements of inverse mass matrix:");
46+
if (inv_e_metric_.rows() == 0)
47+
writer("");
4648
for (int i = 0; i < inv_e_metric_.rows(); ++i) {
4749
std::stringstream inv_e_metric_ss;
4850
inv_e_metric_ss << inv_e_metric_(i, 0);

src/stan/mcmc/hmc/hamiltonians/diag_e_point.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class diag_e_point : public ps_point {
4444
inline void write_metric(stan::callbacks::writer& writer) {
4545
writer("Diagonal elements of inverse mass matrix:");
4646
std::stringstream inv_e_metric_ss;
47-
inv_e_metric_ss << inv_e_metric_(0);
47+
if (inv_e_metric_.size() > 0)
48+
inv_e_metric_ss << inv_e_metric_(0);
4849
for (int i = 1; i < inv_e_metric_.size(); ++i)
4950
inv_e_metric_ss << ", " << inv_e_metric_(i);
5051
writer(inv_e_metric_ss.str());

src/stan/services/util/validate_dense_inv_metric.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ namespace util {
1818
inline void validate_dense_inv_metric(const Eigen::MatrixXd& inv_metric,
1919
callbacks::logger& logger) {
2020
try {
21-
stan::math::check_pos_definite("check_pos_definite", "inv_metric",
22-
inv_metric);
21+
if (inv_metric.size() > 0)
22+
stan::math::check_pos_definite("check_pos_definite", "inv_metric",
23+
inv_metric);
2324
} catch (const std::domain_error& e) {
2425
logger.error("Inverse Euclidean metric not positive definite.");
2526
throw std::domain_error("Initialization failure");

src/test/unit/services/util/inv_metric_test.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@ TEST(inv_metric, read_dense_OK) {
120120
ASSERT_NEAR(0.8274, inv_inv_metric(8), 0.000001);
121121
}
122122

123+
TEST(inv_metric, read_dense_sz0) {
124+
stan::callbacks::logger logger;
125+
stan::io::dump dmp = stan::services::util::create_unit_e_dense_inv_metric(0);
126+
Eigen::MatrixXd inv_inv_metric
127+
= stan::services::util::read_dense_inv_metric(dmp, 0, logger);
128+
EXPECT_EQ(0, inv_inv_metric.size());
129+
EXPECT_EQ(0, inv_inv_metric.rows());
130+
EXPECT_EQ(0, inv_inv_metric.cols());
131+
}
132+
123133
TEST(inv_metric, read_dense_bad1) {
124134
stan::callbacks::logger logger;
125135
std::string txt

0 commit comments

Comments
 (0)