From 73f692d16b544d619c2234259f4086cc93c577df Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Tue, 27 Oct 2015 11:01:37 +0100 Subject: [PATCH] Fix ambiguous instantiation --- Eigen/src/SparseCore/SparseProduct.h | 75 +++++++++++++++++++++------- test/sparse_basic.cpp | 2 +- test/sparse_product.cpp | 4 ++ 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/Eigen/src/SparseCore/SparseProduct.h b/Eigen/src/SparseCore/SparseProduct.h index 26680b7a7..ea2c3a8a3 100644 --- a/Eigen/src/SparseCore/SparseProduct.h +++ b/Eigen/src/SparseCore/SparseProduct.h @@ -39,6 +39,34 @@ struct generic_product_impl { template static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) + { + evalTo(dst, lhs, rhs, typename evaluator_traits::Shape()); + } + + // dense += sparse * sparse + template + static void addTo(Dest& dst, const ActualLhs& lhs, const Rhs& rhs, int* = typename enable_if::Shape,DenseShape>::value,int*>::type(0) ) + { + typedef typename nested_eval::type LhsNested; + typedef typename nested_eval::type RhsNested; + LhsNested lhsNested(lhs); + RhsNested rhsNested(rhs); + internal::sparse_sparse_to_dense_product_selector::type, + typename remove_all::type, Dest>::run(lhsNested,rhsNested,dst); + } + + // dense -= sparse * sparse + template + static void subTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, int* = typename enable_if::Shape,DenseShape>::value,int*>::type(0) ) + { + addTo(dst, -lhs, rhs); + } + +protected: + + // sparse = sparse * sparse + template + static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, SparseShape) { typedef typename nested_eval::type LhsNested; typedef typename nested_eval::type RhsNested; @@ -47,6 +75,14 @@ struct generic_product_impl internal::conservative_sparse_sparse_product_selector::type, typename remove_all::type, Dest>::run(lhsNested,rhsNested,dst); } + + // dense = sparse * sparse + template + static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, DenseShape) + { + dst.setZero(); + addTo(dst, lhs, rhs); + } }; // sparse * sparse-triangular @@ -61,33 +97,36 @@ struct generic_product_impl {}; -// Dense = sparse * sparse -template< typename DstXprType, typename Lhs, typename Rhs, int Options/*, typename Scalar*/> -struct Assignment, internal::assign_op, Sparse2Dense/*, - typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct),Scalar>::type*/> +// dense = sparse-product (can be sparse*sparse, sparse*perm, etc.) +template< typename DstXprType, typename Lhs, typename Rhs> +struct Assignment, internal::assign_op, Sparse2Dense> { - typedef Product SrcXprType; + typedef Product SrcXprType; static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op &) { - dst.setZero(); - dst += src; + generic_product_impl::evalTo(dst,src.lhs(),src.rhs()); } }; -// Dense += sparse * sparse -template< typename DstXprType, typename Lhs, typename Rhs, int Options> -struct Assignment, internal::add_assign_op, Sparse2Dense/*, - typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct),Scalar>::type*/> +// dense += sparse-product (can be sparse*sparse, sparse*perm, etc.) +template< typename DstXprType, typename Lhs, typename Rhs> +struct Assignment, internal::add_assign_op, Sparse2Dense> { - typedef Product SrcXprType; + typedef Product SrcXprType; static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op &) { - typedef typename nested_eval::type LhsNested; - typedef typename nested_eval::type RhsNested; - LhsNested lhsNested(src.lhs()); - RhsNested rhsNested(src.rhs()); - internal::sparse_sparse_to_dense_product_selector::type, - typename remove_all::type, DstXprType>::run(lhsNested,rhsNested,dst); + generic_product_impl::addTo(dst,src.lhs(),src.rhs()); + } +}; + +// dense -= sparse-product (can be sparse*sparse, sparse*perm, etc.) +template< typename DstXprType, typename Lhs, typename Rhs> +struct Assignment, internal::sub_assign_op, Sparse2Dense> +{ + typedef Product SrcXprType; + static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op &) + { + generic_product_impl::subTo(dst,src.lhs(),src.rhs()); } }; diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp index e8ebd7000..d8e42e984 100644 --- a/test/sparse_basic.cpp +++ b/test/sparse_basic.cpp @@ -438,7 +438,7 @@ template void sparse_basic(const SparseMatrixType& re { Index i = internal::random(0,rows-1); Index j = internal::random(0,rows-1); - Index v = internal::random(); + Scalar v = internal::random(); m1.coeffRef(i,j) = v; refMat1.coeffRef(i,j) = v; VERIFY_IS_APPROX(m1, refMat1); diff --git a/test/sparse_product.cpp b/test/sparse_product.cpp index 8c83f08d7..7ec5270e8 100644 --- a/test/sparse_product.cpp +++ b/test/sparse_product.cpp @@ -79,12 +79,16 @@ template void sparse_product() // dense ?= sparse * sparse VERIFY_IS_APPROX(dm4 =m2*m3, refMat4 =refMat2*refMat3); VERIFY_IS_APPROX(dm4+=m2*m3, refMat4+=refMat2*refMat3); + VERIFY_IS_APPROX(dm4-=m2*m3, refMat4-=refMat2*refMat3); VERIFY_IS_APPROX(dm4 =m2t.transpose()*m3, refMat4 =refMat2t.transpose()*refMat3); VERIFY_IS_APPROX(dm4+=m2t.transpose()*m3, refMat4+=refMat2t.transpose()*refMat3); + VERIFY_IS_APPROX(dm4-=m2t.transpose()*m3, refMat4-=refMat2t.transpose()*refMat3); VERIFY_IS_APPROX(dm4 =m2t.transpose()*m3t.transpose(), refMat4 =refMat2t.transpose()*refMat3t.transpose()); VERIFY_IS_APPROX(dm4+=m2t.transpose()*m3t.transpose(), refMat4+=refMat2t.transpose()*refMat3t.transpose()); + VERIFY_IS_APPROX(dm4-=m2t.transpose()*m3t.transpose(), refMat4-=refMat2t.transpose()*refMat3t.transpose()); VERIFY_IS_APPROX(dm4 =m2*m3t.transpose(), refMat4 =refMat2*refMat3t.transpose()); VERIFY_IS_APPROX(dm4+=m2*m3t.transpose(), refMat4+=refMat2*refMat3t.transpose()); + VERIFY_IS_APPROX(dm4-=m2*m3t.transpose(), refMat4-=refMat2*refMat3t.transpose()); VERIFY_IS_APPROX(dm4 = m2*m3*s1, refMat4 = refMat2*refMat3*s1); // test aliasing