Test: Track stored zeros in sparse triplet references

libeigen/eigen!3028

Closes #3150

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index 087604b..2c1c549 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -549,6 +549,9 @@
       triplets.push_back(TripletType(r, c, v));
       refMat_sum(r, c) += v;
     }
+    triplets.emplace_back(0, 0, Scalar(0));
+    triplets.emplace_back(0, 0, Scalar(2));
+    refMat_sum(0, 0) += Scalar(2);
 
     std::vector<TripletType> moreTriplets;
     moreTriplets.reserve(ntriplets);
@@ -561,6 +564,9 @@
       moreTriplets.push_back(TripletType(r, c, v));
       refMat_sum_more(r, c) += v;
     }
+    moreTriplets.emplace_back(0, 0, Scalar(0));
+    moreTriplets.emplace_back(0, 0, Scalar(3));
+    refMat_sum_more(0, 0) += Scalar(3);
 
     // setFromTriplets sorts internally by (outer, inner), so non-commutative
     // reductions (std::multiplies, "last wins") depend on sorted order.
@@ -574,14 +580,17 @@
 
     DenseMatrix refMat_prod = DenseMatrix::Zero(rows, cols);
     DenseMatrix refMat_last = DenseMatrix::Zero(rows, cols);
+    // A stored zero still participates in duplicate reductions.
+    Matrix<bool, Dynamic, Dynamic> visited = Matrix<bool, Dynamic, Dynamic>::Constant(rows, cols, false);
     {
       auto sorted = triplets;
       std::stable_sort(sorted.begin(), sorted.end(), triplet_comp());
       for (const auto& t : sorted) {
-        if (std::abs(refMat_prod(t.row(), t.col())) == 0)
+        if (!visited(t.row(), t.col()))
           refMat_prod(t.row(), t.col()) = t.value();
         else
           refMat_prod(t.row(), t.col()) *= t.value();
+        visited(t.row(), t.col()) = true;
         refMat_last(t.row(), t.col()) = t.value();
       }
     }
@@ -592,10 +601,11 @@
       auto sorted = moreTriplets;
       std::stable_sort(sorted.begin(), sorted.end(), triplet_comp());
       for (const auto& t : sorted) {
-        if (std::abs(refMat_prod_more(t.row(), t.col())) == 0)
+        if (!visited(t.row(), t.col()))
           refMat_prod_more(t.row(), t.col()) = t.value();
         else
           refMat_prod_more(t.row(), t.col()) *= t.value();
+        visited(t.row(), t.col()) = true;
         refMat_last_more(t.row(), t.col()) = t.value();
       }
     }