From af2fd98144ed46e6cfbe9bac927e274038308657 Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen <4643818-rmlarsen1@users.noreply.gitlab.com> Date: Mon, 18 May 2026 21:36:29 -0700 Subject: [PATCH] SparseCore: honor Eigen::NoChange in SparseMatrix/SparseVector resize (#656) libeigen/eigen!2569 Closes #656 Co-authored-by: Rasmus Munk Larsen --- Eigen/src/Core/util/Constants.h | 6 +++++- Eigen/src/SparseCore/SparseMatrix.h | 12 +++++++++++ Eigen/src/SparseCore/SparseVector.h | 6 ++++++ test/sparse_basic.cpp | 32 +++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index 7908bf3b3..edfad7c55 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -357,7 +357,11 @@ enum NaNPropagationOptions { * and we do not know how to get rid of them (bug 450). */ -enum NoChange_t { NoChange }; +// NoChange is set to -1 (rather than 0) so that calls like resize(NoChange, n) +// that land in a generic resize(Index, Index) overload — missing the NoChange_t +// overload — trip the rows/cols >= 0 assertion instead of silently producing a +// 0-sized dimension. See issue #656. +enum NoChange_t { NoChange = -1 }; enum Sequential_t { Sequential }; enum Default_t { Default }; diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h index b85d1ad0d..8c97a11be 100644 --- a/Eigen/src/SparseCore/SparseMatrix.h +++ b/Eigen/src/SparseCore/SparseMatrix.h @@ -725,6 +725,12 @@ class SparseMatrix : public SparseCompressedBase(density, refMat1, m1); + + SparseMatrixType m2 = m1; + + m1.conservativeResize(NoChange, cols + 2); + refMat1.conservativeResize(NoChange, cols + 2); + refMat1.rightCols(2).setZero(); + VERIFY_IS_APPROX(m1, refMat1); + + m1.conservativeResize(rows + 1, NoChange); + refMat1.conservativeResize(rows + 1, NoChange); + refMat1.bottomRows(1).setZero(); + VERIFY_IS_APPROX(m1, refMat1); + + m2.resize(NoChange, cols + 4); + VERIFY(m2.rows() == rows && m2.cols() == cols + 4); + VERIFY(m2.nonZeros() == 0); + + m2.resize(rows + 2, NoChange); + VERIFY(m2.rows() == rows + 2 && m2.cols() == cols + 4); + + SparseVector v(rows); + v.resize(NoChange, 1); + VERIFY(v.size() == rows); + v.resize(rows + 3, NoChange); + VERIFY(v.size() == rows + 3); + } + // test Identity matrix { DenseMatrix refMat1 = DenseMatrix::Identity(rows, rows);