diff options
author | Gael Guennebaud <g.gael@free.fr> | 2014-07-01 11:50:20 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2014-07-01 11:50:20 +0200 |
commit | 441f97b2df8465cb8d5c601e9f1ed324af71491e (patch) | |
tree | 1e1b6e64f19ab6fa156b8948dbfda7713ec23b3a /Eigen/src/SparseCore/SparseProduct.h | |
parent | 0ad7a644df5c71b9a75c0300210ce17985b88044 (diff) |
Implement evaluators for sparse * sparse products
Diffstat (limited to 'Eigen/src/SparseCore/SparseProduct.h')
-rw-r--r-- | Eigen/src/SparseCore/SparseProduct.h | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/Eigen/src/SparseCore/SparseProduct.h b/Eigen/src/SparseCore/SparseProduct.h index cf7663070..52c452f92 100644 --- a/Eigen/src/SparseCore/SparseProduct.h +++ b/Eigen/src/SparseCore/SparseProduct.h @@ -12,6 +12,8 @@ namespace Eigen { +#ifndef EIGEN_TEST_EVALUATORS + template<typename Lhs, typename Rhs> struct SparseSparseProductReturnType { @@ -183,6 +185,68 @@ SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other return typename SparseSparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); } +#else // EIGEN_TEST_EVALUATORS + + +/** \returns an expression of the product of two sparse matrices. + * By default a conservative product preserving the symbolic non zeros is performed. + * The automatic pruning of the small values can be achieved by calling the pruned() function + * in which case a totally different product algorithm is employed: + * \code + * C = (A*B).pruned(); // supress numerical zeros (exact) + * C = (A*B).pruned(ref); + * C = (A*B).pruned(ref,epsilon); + * \endcode + * where \c ref is a meaningful non zero reference value. + * */ +template<typename Derived> +template<typename OtherDerived> +inline const Product<Derived,OtherDerived> +SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const +{ + return Product<Derived,OtherDerived>(derived(), other.derived()); +} + +namespace internal { + +template<typename Lhs, typename Rhs, int ProductType> +struct generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType> +{ + template<typename Dest> + static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) + { + typedef typename nested_eval<Lhs,Dynamic>::type LhsNested; + typedef typename nested_eval<Rhs,Dynamic>::type RhsNested; + LhsNested lhsNested(lhs); + RhsNested rhsNested(rhs); + internal::conservative_sparse_sparse_product_selector<typename remove_all<LhsNested>::type, + typename remove_all<RhsNested>::type, Dest>::run(lhsNested,rhsNested,dst); + } +}; + +template<typename Lhs, typename Rhs, int ProductTag> +struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, ProductTag, SparseShape, SparseShape, typename Lhs::Scalar, typename Rhs::Scalar> + : public evaluator<typename Product<Lhs, Rhs, DefaultProduct>::PlainObject>::type +{ + typedef Product<Lhs, Rhs, DefaultProduct> XprType; + typedef typename XprType::PlainObject PlainObject; + typedef typename evaluator<PlainObject>::type Base; + + product_evaluator(const XprType& xpr) + : m_result(xpr.rows(), xpr.cols()) + { + ::new (static_cast<Base*>(this)) Base(m_result); + generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductTag>::evalTo(m_result, xpr.lhs(), xpr.rhs()); + } + +protected: + PlainObject m_result; +}; + +} // end namespace internal + +#endif // EIGEN_TEST_EVALUATORS + } // end namespace Eigen #endif // EIGEN_SPARSEPRODUCT_H |