Re: [eigen] Specializing max_coeff_visitor for some number types

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Hello,

here is a simpler alternative, where I only replace abs() by a score function, so the change looks really minor.

I tested the following in CGAL and it worked just as well as the previous version:

+    template<typename> struct scalar_score_coeff_op;
+    template<bool b> struct scalar_score_coeff_op<CGAL::Interval_nt<b> > {
+      typedef double result_type;
+      double operator()(CGAL::Interval_nt<b> const&x)const{ return abs(x).inf(); }
+    };
+    template<typename> struct functor_traits;
+    template<bool b> struct functor_traits<scalar_score_coeff_op<CGAL::Interval_nt<b> > >
+    {
+      enum {
+       Cost = 5,
+       PacketAccess = false
+      };
+    };

Could something like this patch get in?

--
Marc Glisse
diff -r 987d6680a845 Eigen/src/Core/functors/UnaryFunctors.h
--- a/Eigen/src/Core/functors/UnaryFunctors.h	Mon Apr 28 16:16:29 2014 +0200
+++ b/Eigen/src/Core/functors/UnaryFunctors.h	Mon Apr 28 21:03:18 2014 +0200
@@ -56,6 +56,15 @@
 };
 
 /** \internal
+  * \brief Template functor to compute the score of a scalar, to chose a pivot
+  *
+  * \sa class CwiseUnaryOp
+  */
+template<typename Scalar> struct scalar_score_coeff_op : scalar_abs_op<Scalar> {};
+template<typename Scalar>
+struct functor_traits<scalar_score_coeff_op<Scalar> > : functor_traits<scalar_abs_op<Scalar> > {};
+
+/** \internal
   * \brief Template functor to compute the squared absolute value of a scalar
   *
   * \sa class CwiseUnaryOp, Cwise::abs2
diff -r 987d6680a845 Eigen/src/LU/FullPivLU.h
--- a/Eigen/src/LU/FullPivLU.h	Mon Apr 28 16:16:29 2014 +0200
+++ b/Eigen/src/LU/FullPivLU.h	Mon Apr 28 21:03:18 2014 +0200
@@ -442,14 +442,15 @@
 
     // biggest coefficient in the remaining bottom-right corner (starting at row k, col k)
     Index row_of_biggest_in_corner, col_of_biggest_in_corner;
-    RealScalar biggest_in_corner;
+    typedef typename internal::scalar_score_coeff_op<Scalar>::result_type Score;
+    Score biggest_in_corner;
     biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k)
-                        .cwiseAbs()
+                        .cwiseScoreCoeff()
                         .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
     row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
     col_of_biggest_in_corner += k; // need to add k to them.
 
-    if(biggest_in_corner==RealScalar(0))
+    if(biggest_in_corner==Score(0))
     {
       // before exiting, make sure to initialize the still uninitialized transpositions
       // in a sane state without destroying what we already have.
@@ -462,7 +463,9 @@
       break;
     }
 
-    if(biggest_in_corner > m_maxpivot) m_maxpivot = biggest_in_corner;
+    using std::abs;
+    RealScalar abs_pivot = abs(m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner));
+    if(abs_pivot > m_maxpivot) m_maxpivot = abs_pivot;
 
     // Now that we've found the pivot, we need to apply the row/col swaps to
     // bring it to the location (k,k).
diff -r 987d6680a845 Eigen/src/LU/PartialPivLU.h
--- a/Eigen/src/LU/PartialPivLU.h	Mon Apr 28 16:16:29 2014 +0200
+++ b/Eigen/src/LU/PartialPivLU.h	Mon Apr 28 21:03:18 2014 +0200
@@ -238,6 +238,7 @@
     */
   static Index unblocked_lu(MatrixType& lu, PivIndex* row_transpositions, PivIndex& nb_transpositions)
   {
+    typedef typename scalar_score_coeff_op<Scalar>::result_type Score;
     const Index rows = lu.rows();
     const Index cols = lu.cols();
     const Index size = (std::min)(rows,cols);
@@ -249,13 +250,13 @@
       Index rcols = cols-k-1;
         
       Index row_of_biggest_in_col;
-      RealScalar biggest_in_corner
-        = lu.col(k).tail(rows-k).cwiseAbs().maxCoeff(&row_of_biggest_in_col);
+      Score biggest_in_corner
+        = lu.col(k).tail(rows-k).cwiseScoreCoeff().maxCoeff(&row_of_biggest_in_col);
       row_of_biggest_in_col += k;
 
       row_transpositions[k] = PivIndex(row_of_biggest_in_col);
 
-      if(biggest_in_corner != RealScalar(0))
+      if(biggest_in_corner != Score(0))
       {
         if(k != row_of_biggest_in_col)
         {
diff -r 987d6680a845 Eigen/src/plugins/MatrixCwiseUnaryOps.h
--- a/Eigen/src/plugins/MatrixCwiseUnaryOps.h	Mon Apr 28 16:16:29 2014 +0200
+++ b/Eigen/src/plugins/MatrixCwiseUnaryOps.h	Mon Apr 28 21:03:18 2014 +0200
@@ -70,3 +70,11 @@
   return CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >,const Derived>
           (derived(), std::bind1st(std::equal_to<Scalar>(), s));
 }
+
+/** \returns an expression of the coefficient-wise score (for pivot) of \c *this
+  *
+  * \sa cwiseAbs()
+  */
+EIGEN_DEVICE_FUNC
+EIGEN_STRONG_INLINE const CwiseUnaryOp<internal::scalar_score_coeff_op<Scalar>, const Derived>
+cwiseScoreCoeff() const { return derived(); }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/