Make the sparse matrix printer pretty

This commit is contained in:
Evan Porter 2025-09-08 20:05:46 +00:00 committed by GitLab
parent e5f3fa2d61
commit 6cd6284f7f
No known key found for this signature in database

View File

@ -224,33 +224,87 @@ class SparseMatrixBase : public EigenBase<Derived> {
public: public:
#ifndef EIGEN_NO_IO #ifndef EIGEN_NO_IO
friend std::ostream& operator<<(std::ostream& s, const SparseMatrixBase& m) { friend std::ostream& operator<<(std::ostream& s, const SparseMatrixBase& m) {
typedef typename Derived::Nested Nested; using Nested = typename Derived::Nested;
typedef internal::remove_all_t<Nested> NestedCleaned; using NestedCleaned = typename internal::remove_all<Nested>::type;
/// For converting `0's` to the matrices numerical type
using Scalar = typename Derived::Scalar;
if (Flags & RowMajorBit) { if (Flags & RowMajorBit) {
Nested nm(m.derived()); Nested nm(m.derived());
internal::evaluator<NestedCleaned> thisEval(nm); internal::evaluator<NestedCleaned> 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<NestedCleaned>::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) { for (Index row = 0; row < nm.outerSize(); ++row) {
Index col = 0; Index col = 0;
for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, row); it; ++it) { for (typename internal::evaluator<NestedCleaned>::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() << " "; s << it.value() << " ";
++col; ++col;
} }
for (; col < m.cols(); ++col) s << "0 "; for (; col < m.cols(); ++col) {
s.width(width);
s << Scalar(0) << " ";
}
s << std::endl; s << std::endl;
} }
} else { } else {
Nested nm(m.derived()); Nested nm(m.derived());
internal::evaluator<NestedCleaned> thisEval(nm); internal::evaluator<NestedCleaned> thisEval(nm);
if (m.cols() == 1) { 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<NestedCleaned>::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; Index row = 0;
for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, 0); it; ++it) { for (typename internal::evaluator<NestedCleaned>::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; s << it.value() << std::endl;
++row; ++row;
} }
for (; row < m.rows(); ++row) s << "0" << std::endl; for (; row < m.rows(); ++row) {
s.width(width);
s << Scalar(0) << std::endl;
}
} else { } else {
SparseMatrix<Scalar, RowMajorBit, StorageIndex> trans = m; SparseMatrix<Scalar, RowMajorBit, StorageIndex> trans = m;
s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, StorageIndex> >&>(trans); s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, StorageIndex> >&>(trans);