aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Core/AssignEvaluator.h6
-rw-r--r--Eigen/src/Core/CoreEvaluators.h66
-rw-r--r--Eigen/src/Core/Product.h28
-rw-r--r--Eigen/src/Core/ProductEvaluators.h40
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h5
5 files changed, 109 insertions, 36 deletions
diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h
index 99ae3f89d..2f18cbc95 100644
--- a/Eigen/src/Core/AssignEvaluator.h
+++ b/Eigen/src/Core/AssignEvaluator.h
@@ -646,7 +646,7 @@ struct SparseShape {};
// Based on the respective shapes of the destination and source,
// the class AssignmentKind determine the kind of assignment mechanism.
// AssignmentKind must define a Kind typedef.
-template<int DstShape, int SrcShape> struct AssignmentKind;
+template<typename DstShape, typename SrcShape> struct AssignmentKind;
// AssignmentKind<.,.>::Kind can be one of the following:
struct Dense2Dense {};
@@ -655,9 +655,11 @@ template<int DstShape, int SrcShape> struct AssignmentKind;
struct Sparse2Dense {};
struct Sparse2Sparse {};
+template<> struct AssignmentKind<Dense,Dense> { typedef Dense2Dense Kind; };
+
// This is the main assignment class
template< typename DstXprType, typename SrcXprType, typename Functor,
- typename Kind = Dense2Dense,//AssignmentKind< evaluator<A>::Shape , evaluator<B>::Shape >::Kind,
+ typename Kind = typename AssignmentKind< typename evaluator_traits<DstXprType>::Shape , typename evaluator_traits<SrcXprType>::Shape >::Kind,
typename Scalar = typename DstXprType::Scalar>
struct Assignment;
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h
index c63ff8acd..9460e675f 100644
--- a/Eigen/src/Core/CoreEvaluators.h
+++ b/Eigen/src/Core/CoreEvaluators.h
@@ -14,20 +14,70 @@
#define EIGEN_COREEVALUATORS_H
namespace Eigen {
-
+
namespace internal {
-template<typename T> struct evaluator;
+struct IndexBased {};
+struct IteratorBased {};
+
+// This class returns the evaluator kind from the expression storage kind.
+// Default assumes index based accessors
+template<typename StorageKind>
+struct storage_kind_to_evaluator_kind {
+ typedef IndexBased Kind;
+};
+
+// TODO to be moved to SparseCore:
+/*
+template<>
+struct storage_kind_to_evaluator_kind<Sparse> {
+ typedef IteratorBased Kind
+};
+*/
+
+// This class returns the evaluator shape from the expression storage kind.
+// It can be Dense, Sparse, Triangular, Diagonal, SelfAdjoint, Band, etc.
+template<typename StorageKind> struct storage_kind_to_shape;
+
+
+template<>
+struct storage_kind_to_shape<Dense> {
+ typedef Dense Shape;
+};
+
+// TODO to be moved to SparseCore:
+/*
+template<>
+struct storage_kind_to_shape<Sparse> {
+ typedef Sparse Shape;
+};
+*/
+
+template<typename T> struct evaluator_traits;
+
+template< typename T,
+ typename Kind = typename evaluator_traits<T>::Kind,
+ typename Scalar = typename T::Scalar> struct evaluator;
+
+template< typename T,
+ typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
+ typename RhsKind = typename evaluator_traits<typename T::Rhs>::Kind,
+ typename LhsScalar = typename T::Lhs::Scalar,
+ typename RhsScalar = typename T::Rhs::Scalar> struct binary_evaluator;
// evaluator_traits<T> contains traits for evaluator<T>
- template<typename T>
+template<typename T>
struct evaluator_traits_base
{
// TODO check whether these two indirections are really needed.
// Basically, if nobody overwrite type and nestedType, then, they can be dropped
- typedef evaluator<T> type;
- typedef evaluator<T> nestedType;
+// typedef evaluator<T> type;
+// typedef evaluator<T> nestedType;
+
+ // by default, get evalautor kind and shape from storage
+ typedef typename storage_kind_to_evaluator_kind<typename T::StorageKind>::Kind Kind;
+ typedef typename storage_kind_to_shape<typename T::StorageKind>::Shape Shape;
// 1 if assignment A = B assumes aliasing when B is of type T and thus B needs to be evaluated into a
// temporary; 0 if not.
@@ -58,8 +108,10 @@ struct evaluator<const T>
template<typename ExpressionType>
struct evaluator_base
{
- typedef typename evaluator_traits<ExpressionType>::type type;
- typedef typename evaluator_traits<ExpressionType>::nestedType nestedType;
+// typedef typename evaluator_traits<ExpressionType>::type type;
+// typedef typename evaluator_traits<ExpressionType>::nestedType nestedType;
+ typedef evaluator<ExpressionType> type;
+ typedef evaluator<ExpressionType> nestedType;
typedef typename ExpressionType::Index Index;
// TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices.
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index 52586e5c0..970d257a5 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -12,7 +12,7 @@
namespace Eigen {
-template<typename Lhs, typename Rhs, int Option, int ProductTag, typename StorageKind> class ProductImpl;
+template<typename Lhs, typename Rhs, int Option, typename StorageKind> class ProductImpl;
/** \class Product
* \ingroup Core_Module
@@ -26,14 +26,13 @@ template<typename Lhs, typename Rhs, int Option, int ProductTag, typename Storag
*
* The other template parameters are:
* \tparam Option can be DefaultProduct or LazyProduct
- * \tparam ProductTag can be InnerProduct, OuterProduct, GemvProduct, GemmProduct. It is used to ease expression manipulations.
*
*/
// Use ProductReturnType to get correct traits, in particular vectorization flags
namespace internal {
-template<typename Lhs, typename Rhs, int Option, int ProductTag>
-struct traits<Product<Lhs, Rhs, Option, ProductTag> >
+template<typename Lhs, typename Rhs, int Option>
+struct traits<Product<Lhs, Rhs, Option> >
: traits<typename ProductReturnType<Lhs, Rhs>::Type>
{
// We want A+B*C to be of type Product<Matrix, Sum> and not Product<Matrix, Matrix>
@@ -45,18 +44,23 @@ struct traits<Product<Lhs, Rhs, Option, ProductTag> >
} // end namespace internal
-template<typename Lhs, typename Rhs, int Option, int ProductTag>
-class Product : public ProductImpl<Lhs,Rhs,Option,ProductTag,
- typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
- typename internal::traits<Rhs>::StorageKind>::ret>
+template<typename _Lhs, typename _Rhs, int Option>
+class Product : public ProductImpl<_Lhs,_Rhs,Option,
+ typename internal::promote_storage_type<typename internal::traits<_Lhs>::StorageKind,
+ typename internal::traits<_Rhs>::StorageKind>::ret>
{
public:
+ typedef _Lhs Lhs;
+ typedef _Rhs Rhs;
+
typedef typename ProductImpl<
- Lhs, Rhs, Option, ProductTag,
+ Lhs, Rhs, Option,
typename internal::promote_storage_type<typename Lhs::StorageKind,
typename Rhs::StorageKind>::ret>::Base Base;
EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
+
+
typedef typename Lhs::Nested LhsNested;
typedef typename Rhs::Nested RhsNested;
@@ -82,13 +86,13 @@ class Product : public ProductImpl<Lhs,Rhs,Option,ProductTag,
RhsNested m_rhs;
};
-template<typename Lhs, typename Rhs, int Option, int ProductTag>
-class ProductImpl<Lhs,Rhs,Option,ProductTag,Dense> : public internal::dense_xpr_base<Product<Lhs,Rhs,Option,ProductTag> >::type
+template<typename Lhs, typename Rhs, int Option>
+class ProductImpl<Lhs,Rhs,Option,Dense> : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
{
typedef Product<Lhs, Rhs> Derived;
public:
- typedef typename internal::dense_xpr_base<Product<Lhs, Rhs, Option, ProductTag> >::type Base;
+ typedef typename internal::dense_xpr_base<Product<Lhs, Rhs, Option> >::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
};
diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h
index 9f5f6eb0c..e3a893651 100644
--- a/Eigen/src/Core/ProductEvaluators.h
+++ b/Eigen/src/Core/ProductEvaluators.h
@@ -16,7 +16,28 @@
namespace Eigen {
namespace internal {
+
+// Like more general binary expressions, products need they own evaluator:
+template< typename T,
+ int ProductTag = internal::product_tag<typename T::Lhs,typename T::Rhs>::ret,
+ typename LhsShape = typename evaluator_traits<typename T::Lhs>::Shape,
+ typename RhsShape = typename evaluator_traits<typename T::Rhs>::Shape,
+ typename LhsScalar = typename T::Lhs::Scalar,
+ typename RhsScalar = typename T::Rhs::Scalar
+ > struct product_evaluator;
+
+template<typename Lhs, typename Rhs, int Options>
+struct evaluator<Product<Lhs, Rhs, Options> >
+ : public product_evaluator<Product<Lhs, Rhs, Options> >
+{
+ typedef Product<Lhs, Rhs, Options> XprType;
+ typedef product_evaluator<XprType> Base;
+ typedef evaluator type;
+ typedef evaluator nestedType;
+
+ evaluator(const XprType& xpr) : Base(xpr) {}
+};
// Helper class to perform a dense product with the destination at hand.
// Depending on the sizes of the factors, there are different evaluation strategies
@@ -27,17 +48,14 @@ struct dense_product_impl;
// The evaluator for default dense products creates a temporary and call dense_product_impl
template<typename Lhs, typename Rhs, int ProductTag>
-struct evaluator<Product<Lhs, Rhs, DefaultProduct, ProductTag> >
- : public evaluator<typename Product<Lhs, Rhs, DefaultProduct, ProductTag>::PlainObject>::type
+struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, ProductTag, Dense, Dense, typename Lhs::Scalar, typename Rhs::Scalar>
+ : public evaluator<typename Product<Lhs, Rhs, DefaultProduct>::PlainObject>::type
{
- typedef Product<Lhs, Rhs, DefaultProduct, ProductTag> XprType;
+ typedef Product<Lhs, Rhs, DefaultProduct> XprType;
typedef typename XprType::PlainObject PlainObject;
typedef typename evaluator<PlainObject>::type Base;
-
- typedef evaluator type;
- typedef evaluator nestedType;
- evaluator(const XprType& xpr)
+ product_evaluator(const XprType& xpr)
: m_result(xpr.rows(), xpr.cols())
{
::new (static_cast<Base*>(this)) Base(m_result);
@@ -199,13 +217,13 @@ template<int StorageOrder, int UnrollingIndex, typename Lhs, typename Rhs, typen
struct etor_product_packet_impl;
template<typename Lhs, typename Rhs, int ProductTag>
-struct evaluator<Product<Lhs, Rhs, LazyProduct, ProductTag> >
- : evaluator_base<Product<Lhs, Rhs, LazyProduct, ProductTag> >
+struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, Dense, Dense, typename Lhs::Scalar, typename Rhs::Scalar >
+ : evaluator_base<Product<Lhs, Rhs, LazyProduct> >
{
- typedef Product<Lhs, Rhs, LazyProduct, ProductTag> XprType;
+ typedef Product<Lhs, Rhs, LazyProduct> XprType;
typedef CoeffBasedProduct<Lhs, Rhs, 0> CoeffBasedProductType;
- evaluator(const XprType& xpr)
+ product_evaluator(const XprType& xpr)
: m_lhsImpl(xpr.lhs()),
m_rhsImpl(xpr.rhs()),
m_innerDim(xpr.lhs().cols())
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index 459422524..776eac587 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -94,10 +94,7 @@ namespace internal {
template<typename Lhs, typename Rhs> struct product_tag;
}
-template<typename Lhs, typename Rhs,
- int Option = DefaultProduct,
- int ProductTag = internal::product_tag<Lhs,Rhs>::ret
- > class Product;
+template<typename Lhs, typename Rhs, int Option = DefaultProduct> class Product;
template<typename Lhs, typename Rhs, int Mode> class GeneralProduct; // TODO deprecated
template<typename Lhs, typename Rhs, int NestingFlags> class CoeffBasedProduct; // TODO deprecated