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(); }