aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2015-10-27 11:01:37 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2015-10-27 11:01:37 +0100
commit73f692d16b544d619c2234259f4086cc93c577df (patch)
tree0ecdaa5ef6b936671cd784736eac320510268e7f
parente6f8c5c325fca53b53436b6bd8d66749444216bb (diff)
Fix ambiguous instantiation
-rw-r--r--Eigen/src/SparseCore/SparseProduct.h75
-rw-r--r--test/sparse_basic.cpp2
-rw-r--r--test/sparse_product.cpp4
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
@@ -40,6 +40,34 @@ struct generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType>
template<typename Dest>
static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
{
+ evalTo(dst, lhs, rhs, typename evaluator_traits<Dest>::Shape());
+ }
+
+ // dense += sparse * sparse
+ template<typename Dest,typename ActualLhs>
+ static void addTo(Dest& dst, const ActualLhs& lhs, const Rhs& rhs, int* = typename enable_if<is_same<typename evaluator_traits<Dest>::Shape,DenseShape>::value,int*>::type(0) )
+ {
+ typedef typename nested_eval<ActualLhs,Dynamic>::type LhsNested;
+ typedef typename nested_eval<Rhs,Dynamic>::type RhsNested;
+ LhsNested lhsNested(lhs);
+ RhsNested rhsNested(rhs);
+ internal::sparse_sparse_to_dense_product_selector<typename remove_all<LhsNested>::type,
+ typename remove_all<RhsNested>::type, Dest>::run(lhsNested,rhsNested,dst);
+ }
+
+ // dense -= sparse * sparse
+ template<typename Dest>
+ static void subTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, int* = typename enable_if<is_same<typename evaluator_traits<Dest>::Shape,DenseShape>::value,int*>::type(0) )
+ {
+ addTo(dst, -lhs, rhs);
+ }
+
+protected:
+
+ // sparse = sparse * sparse
+ template<typename Dest>
+ static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, SparseShape)
+ {
typedef typename nested_eval<Lhs,Dynamic>::type LhsNested;
typedef typename nested_eval<Rhs,Dynamic>::type RhsNested;
LhsNested lhsNested(lhs);
@@ -47,6 +75,14 @@ struct generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType>
internal::conservative_sparse_sparse_product_selector<typename remove_all<LhsNested>::type,
typename remove_all<RhsNested>::type, Dest>::run(lhsNested,rhsNested,dst);
}
+
+ // dense = sparse * sparse
+ template<typename Dest>
+ 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<Lhs, Rhs, SparseTriangularShape, SparseShape, Produc
: public generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType>
{};
-// Dense = sparse * sparse
-template< typename DstXprType, typename Lhs, typename Rhs, int Options/*, typename Scalar*/>
-struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::assign_op<typename DstXprType::Scalar>, 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<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::assign_op<typename DstXprType::Scalar>, Sparse2Dense>
{
- typedef Product<Lhs,Rhs,Options> SrcXprType;
+ typedef Product<Lhs,Rhs,AliasFreeProduct> SrcXprType;
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar> &)
{
- dst.setZero();
- dst += src;
+ generic_product_impl<Lhs, Rhs>::evalTo(dst,src.lhs(),src.rhs());
}
};
-// Dense += sparse * sparse
-template< typename DstXprType, typename Lhs, typename Rhs, int Options>
-struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::add_assign_op<typename DstXprType::Scalar>, 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<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::add_assign_op<typename DstXprType::Scalar>, Sparse2Dense>
{
- typedef Product<Lhs,Rhs,Options> SrcXprType;
+ typedef Product<Lhs,Rhs,AliasFreeProduct> SrcXprType;
static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar> &)
{
- typedef typename nested_eval<Lhs,Dynamic>::type LhsNested;
- typedef typename nested_eval<Rhs,Dynamic>::type RhsNested;
- LhsNested lhsNested(src.lhs());
- RhsNested rhsNested(src.rhs());
- internal::sparse_sparse_to_dense_product_selector<typename remove_all<LhsNested>::type,
- typename remove_all<RhsNested>::type, DstXprType>::run(lhsNested,rhsNested,dst);
+ generic_product_impl<Lhs, Rhs>::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<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::sub_assign_op<typename DstXprType::Scalar>, Sparse2Dense>
+{
+ typedef Product<Lhs,Rhs,AliasFreeProduct> SrcXprType;
+ static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar> &)
+ {
+ generic_product_impl<Lhs, Rhs>::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<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
{
Index i = internal::random<Index>(0,rows-1);
Index j = internal::random<Index>(0,rows-1);
- Index v = internal::random<Scalar>();
+ Scalar v = internal::random<Scalar>();
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<typename SparseMatrixType> 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