aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Core/GeneralProduct.h53
-rw-r--r--Eigen/src/Core/Product.h2
-rw-r--r--Eigen/src/Core/ProductEvaluators.h72
-rw-r--r--Eigen/src/Core/SelfAdjointView.h2
4 files changed, 98 insertions, 31 deletions
diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h
index 675f6ee8d..f823ff251 100644
--- a/Eigen/src/Core/GeneralProduct.h
+++ b/Eigen/src/Core/GeneralProduct.h
@@ -82,7 +82,8 @@ private:
public:
enum {
- value = selector::ret
+ value = selector::ret,
+ ret = selector::ret
};
#ifdef EIGEN_DEBUG_PRODUCT
static void debug()
@@ -98,31 +99,31 @@ public:
#endif
};
-template<typename Lhs, typename Rhs> struct product_tag
-{
-private:
-
- typedef typename remove_all<Lhs>::type _Lhs;
- typedef typename remove_all<Rhs>::type _Rhs;
- enum {
- Rows = _Lhs::RowsAtCompileTime,
- Cols = _Rhs::ColsAtCompileTime,
- Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, _Rhs::RowsAtCompileTime)
- };
-
- enum {
- rows_select = Rows==1 ? int(Rows) : int(Large),
- cols_select = Cols==1 ? int(Cols) : int(Large),
- depth_select = Depth==1 ? int(Depth) : int(Large)
- };
- typedef product_type_selector<rows_select, cols_select, depth_select> selector;
-
-public:
- enum {
- ret = selector::ret
- };
-
-};
+// template<typename Lhs, typename Rhs> struct product_tag
+// {
+// private:
+//
+// typedef typename remove_all<Lhs>::type _Lhs;
+// typedef typename remove_all<Rhs>::type _Rhs;
+// enum {
+// Rows = _Lhs::RowsAtCompileTime,
+// Cols = _Rhs::ColsAtCompileTime,
+// Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, _Rhs::RowsAtCompileTime)
+// };
+//
+// enum {
+// rows_select = Rows==1 ? int(Rows) : int(Large),
+// cols_select = Cols==1 ? int(Cols) : int(Large),
+// depth_select = Depth==1 ? int(Depth) : int(Large)
+// };
+// typedef product_type_selector<rows_select, cols_select, depth_select> selector;
+//
+// public:
+// enum {
+// ret = selector::ret
+// };
+//
+// };
/* The following allows to select the kind of product at compile time
* based on the three dimensions of the product.
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index 79d09fbb6..d64fbae35 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -88,7 +88,7 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
namespace internal {
-template<typename Lhs, typename Rhs, int Option, int ProductTab = internal::product_tag<Lhs,Rhs>::ret>
+template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret>
class dense_product_base
: public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
{};
diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h
index f0eb57d67..46048882b 100644
--- a/Eigen/src/Core/ProductEvaluators.h
+++ b/Eigen/src/Core/ProductEvaluators.h
@@ -19,7 +19,7 @@ namespace internal {
// Like more general binary expressions, products need their own evaluator:
template< typename T,
- int ProductTag = internal::product_tag<typename T::Lhs,typename T::Rhs>::ret,
+ int ProductTag = internal::product_type<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,
@@ -38,7 +38,43 @@ struct evaluator<Product<Lhs, Rhs, Options> >
evaluator(const XprType& xpr) : Base(xpr) {}
};
+
+// Catch scalar * ( A * B ) and transform it to (A*scalar) * B
+// TODO we should apply that rule if that's really helpful
+template<typename Lhs, typename Rhs, typename Scalar>
+struct evaluator<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const Product<Lhs, Rhs, DefaultProduct> > >
+ : public evaluator<Product<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,const Lhs>, Rhs, DefaultProduct> >
+{
+ typedef CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const Product<Lhs, Rhs, DefaultProduct> > XprType;
+ typedef evaluator<Product<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,const Lhs>, Rhs, DefaultProduct> > Base;
+
+ typedef evaluator type;
+ typedef evaluator nestedType;
+
+ evaluator(const XprType& xpr)
+ : Base(xpr.functor().m_other * xpr.nestedExpression().lhs() * xpr.nestedExpression().rhs())
+ {}
+};
+
+
+template<typename Lhs, typename Rhs, int DiagIndex>
+struct evaluator<Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> >
+ : public evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> >
+{
+ typedef Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> XprType;
+ typedef evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> > Base;
+ typedef evaluator type;
+ typedef evaluator nestedType;
+//
+ evaluator(const XprType& xpr)
+ : Base(Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex>(
+ Product<Lhs, Rhs, LazyProduct>(xpr.nestedExpression().lhs(), xpr.nestedExpression().rhs()),
+ xpr.index() ))
+ {}
+};
+
+
// Helper class to perform a matrix product with the destination at hand.
// Depending on the sizes of the factors, there are different evaluation strategies
// as controlled by internal::product_type.
@@ -108,6 +144,23 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_ass
}
};
+
+// Dense ?= scalar * Product
+// TODO we should apply that rule if that's really helpful
+// for instance, this is not good for inner products
+template< typename DstXprType, typename Lhs, typename Rhs, typename AssignFunc, typename Scalar, typename ScalarBis>
+struct Assignment<DstXprType, CwiseUnaryOp<internal::scalar_multiple_op<ScalarBis>,
+ const Product<Lhs,Rhs,DefaultProduct> >, AssignFunc, Dense2Dense, Scalar>
+{
+ typedef CwiseUnaryOp<internal::scalar_multiple_op<ScalarBis>,
+ const Product<Lhs,Rhs,DefaultProduct> > SrcXprType;
+ static void run(DstXprType &dst, const SrcXprType &src, const AssignFunc& func)
+ {
+ call_assignment(dst.noalias(), (src.functor().m_other * src.nestedExpression().lhs()) * src.nestedExpression().rhs(), func);
+ }
+};
+
+
template<typename Lhs, typename Rhs>
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
{
@@ -255,9 +308,9 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode>
};
// This specialization enforces the use of a coefficient-based evaluation strategy
-template<typename Lhs, typename Rhs>
-struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,LazyCoeffBasedProductMode>
- : generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> {};
+// template<typename Lhs, typename Rhs>
+// struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,LazyCoeffBasedProductMode>
+// : generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> {};
// Case 2: Evaluate coeff by coeff
//
@@ -347,6 +400,17 @@ protected:
Index m_innerDim;
};
+template<typename Lhs, typename Rhs>
+struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, LazyCoeffBasedProductMode, DenseShape, DenseShape, typename Lhs::Scalar, typename Rhs::Scalar >
+ : product_evaluator<Product<Lhs, Rhs, LazyProduct>, CoeffBasedProductMode, DenseShape, DenseShape, typename Lhs::Scalar, typename Rhs::Scalar >
+{
+ typedef Product<Lhs, Rhs, DefaultProduct> XprType;
+ typedef Product<Lhs, Rhs, LazyProduct> BaseProduct;
+ typedef product_evaluator<BaseProduct, CoeffBasedProductMode, DenseShape, DenseShape, typename Lhs::Scalar, typename Rhs::Scalar > Base;
+ product_evaluator(const XprType& xpr)
+ : Base(BaseProduct(xpr.lhs(),xpr.rhs()))
+ {}
+};
/***************************************************************************
* Normal product .coeff() implementation (with meta-unrolling)
diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h
index 079b987f8..a5c6d5ceb 100644
--- a/Eigen/src/Core/SelfAdjointView.h
+++ b/Eigen/src/Core/SelfAdjointView.h
@@ -336,6 +336,7 @@ struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, Dyn
}
};
+#ifdef EIGEN_ENABLE_EVALUATORS
// TODO currently a selfadjoint expression has the form SelfAdjointView<.,.>
// in the future selfadjoint-ness should be defined by the expression traits
// such that Transpose<SelfAdjointView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
@@ -347,6 +348,7 @@ struct evaluator_traits<SelfAdjointView<MatrixType,Mode> >
static const int AssumeAliasing = 0;
};
+#endif // EIGEN_ENABLE_EVALUATORS
} // end namespace internal