From 6cd6284f7f99c581ad944a3250d7a37c2f729258 Mon Sep 17 00:00:00 2001 From: Evan Porter Date: Mon, 8 Sep 2025 20:05:46 +0000 Subject: [PATCH] Make the sparse matrix printer pretty --- Eigen/src/SparseCore/SparseMatrixBase.h | 66 ++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/Eigen/src/SparseCore/SparseMatrixBase.h b/Eigen/src/SparseCore/SparseMatrixBase.h index 7ac16f834..fbf1313d5 100644 --- a/Eigen/src/SparseCore/SparseMatrixBase.h +++ b/Eigen/src/SparseCore/SparseMatrixBase.h @@ -224,33 +224,87 @@ class SparseMatrixBase : public EigenBase { public: #ifndef EIGEN_NO_IO friend std::ostream& operator<<(std::ostream& s, const SparseMatrixBase& m) { - typedef typename Derived::Nested Nested; - typedef internal::remove_all_t NestedCleaned; + using Nested = typename Derived::Nested; + using NestedCleaned = typename internal::remove_all::type; + + /// For converting `0's` to the matrices numerical type + using Scalar = typename Derived::Scalar; if (Flags & RowMajorBit) { Nested nm(m.derived()); internal::evaluator thisEval(nm); + + // compute global width + std::size_t width = 0; + { + std::ostringstream ss0; + ss0.copyfmt(s); + ss0 << Scalar(0); + width = ss0.str().size(); + for (Index row = 0; row < nm.outerSize(); ++row) { + for (typename internal::evaluator::InnerIterator it(thisEval, row); it; ++it) { + std::ostringstream ss; + ss.copyfmt(s); + ss << it.value(); + + const std::size_t potential_width = ss.str().size(); + if (potential_width > width) width = potential_width; + } + } + } + for (Index row = 0; row < nm.outerSize(); ++row) { Index col = 0; for (typename internal::evaluator::InnerIterator it(thisEval, row); it; ++it) { - for (; col < it.index(); ++col) s << "0 "; + for (; col < it.index(); ++col) { + s.width(width); + s << Scalar(0) << " "; + } + s.width(width); s << it.value() << " "; ++col; } - for (; col < m.cols(); ++col) s << "0 "; + for (; col < m.cols(); ++col) { + s.width(width); + s << Scalar(0) << " "; + } s << std::endl; } } else { Nested nm(m.derived()); internal::evaluator thisEval(nm); if (m.cols() == 1) { + // compute local width (single col) + std::size_t width = 0; + { + std::ostringstream ss0; + ss0.copyfmt(s); + ss0 << Scalar(0); + width = ss0.str().size(); + for (typename internal::evaluator::InnerIterator it(thisEval, 0); it; ++it) { + std::ostringstream ss; + ss.copyfmt(s); + ss << it.value(); + + const std::size_t potential_width = ss.str().size(); + if (potential_width > width) width = potential_width; + } + } + Index row = 0; for (typename internal::evaluator::InnerIterator it(thisEval, 0); it; ++it) { - for (; row < it.index(); ++row) s << "0" << std::endl; + for (; row < it.index(); ++row) { + s.width(width); + s << Scalar(0) << std::endl; + } + s.width(width); s << it.value() << std::endl; ++row; } - for (; row < m.rows(); ++row) s << "0" << std::endl; + for (; row < m.rows(); ++row) { + s.width(width); + s << Scalar(0) << std::endl; + } } else { SparseMatrix trans = m; s << static_cast >&>(trans);