Skip to content

Commit 4c3441b

Browse files
authored
Merge pull request #2877 from torsti/feature/issue-2876-csr-index
Fix csr_to_dense_matrix first row indexing check bug
2 parents edfc5b8 + 90a5bfe commit 4c3441b

2 files changed

Lines changed: 24 additions & 7 deletions

File tree

stan/math/prim/fun/csr_to_dense_matrix.hpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,17 @@ csr_to_dense_matrix(int m, int n, const T& w, const std::vector<int>& v,
5050
Matrix<value_type_t<T>, Dynamic, Dynamic> result(m, n);
5151
result.setZero();
5252
for (int row = 0; row < m; ++row) {
53-
int row_end_in_w = (u[row] - stan::error_index::value) + csr_u_to_z(u, row);
54-
check_range("csr_to_dense_matrix", "w", w.size(), row_end_in_w);
55-
for (int nze = u[row] - stan::error_index::value; nze < row_end_in_w;
56-
++nze) {
57-
// row is row index, v[nze] is column index. w[nze] is entry value.
58-
check_range("csr_to_dense_matrix", "j", n, v[nze]);
59-
result(row, v[nze] - stan::error_index::value) = w_ref.coeff(nze);
53+
int row_nnz = csr_u_to_z(u, row);
54+
55+
if (row_nnz > 0) {
56+
int row_end_in_w = (u[row] - stan::error_index::value) + row_nnz;
57+
check_range("csr_to_dense_matrix", "w", w.size(), row_end_in_w);
58+
for (int nze = u[row] - stan::error_index::value; nze < row_end_in_w;
59+
++nze) {
60+
// row is row index, v[nze] is column index. w[nze] is entry value.
61+
check_range("csr_to_dense_matrix", "j", n, v[nze]);
62+
result(row, v[nze] - stan::error_index::value) = w_ref.coeff(nze);
63+
}
6064
}
6165
}
6266
return result;

test/unit/math/prim/fun/csr_to_dense_matrix_test.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,16 @@ TEST(SparseStuff, csr_to_dense_matrix_v_short) {
115115
EXPECT_THROW(stan::math::csr_to_dense_matrix(2, 3, X_w, X_v, X_u),
116116
std::invalid_argument);
117117
}
118+
119+
// Test that valid sparse matrix with empty first row does not throw (CSR).
120+
TEST(SparseStuff, csr_to_dense_matrix_empty_row) {
121+
stan::math::matrix_d m(3, 2);
122+
Eigen::SparseMatrix<double, Eigen::RowMajor> a;
123+
m << 0.0, 0.0, 1.0, 0.0, 0.0, 0.0;
124+
a = m.sparseView();
125+
126+
stan::math::vector_d X_w = stan::math::csr_extract_w(a);
127+
std::vector<int> X_v = stan::math::csr_extract_v(a);
128+
std::vector<int> X_u = stan::math::csr_extract_u(a);
129+
EXPECT_NO_THROW(stan::math::csr_to_dense_matrix(3, 2, X_w, X_v, X_u));
130+
}

0 commit comments

Comments
 (0)