aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2013-12-03 17:17:53 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2013-12-03 17:17:53 +0100
commit6c5e915e9a6c79550e7e2db2b53648f163a1411d (patch)
treeaab5c0a07616fcd028d2839f402edcadc0e53d81 /Eigen/src/Core
parentf0b82c3ab972a1eafd6aa4f08f4eaffa0d6f1e55 (diff)
Enable use of evaluators for noalias and lazyProduct, add conversion to scalar for inner products
Diffstat (limited to 'Eigen/src/Core')
-rw-r--r--Eigen/src/Core/CoreEvaluators.h4
-rw-r--r--Eigen/src/Core/GeneralProduct.h33
-rw-r--r--Eigen/src/Core/MatrixBase.h4
-rw-r--r--Eigen/src/Core/NoAlias.h29
-rw-r--r--Eigen/src/Core/Product.h6
-rw-r--r--Eigen/src/Core/ProductEvaluators.h32
-rw-r--r--Eigen/src/Core/products/CoeffBasedProduct.h6
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h6
-rw-r--r--Eigen/src/Core/util/StaticAssert.h3
9 files changed, 101 insertions, 22 deletions
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h
index 961b56e55..faf5aedb5 100644
--- a/Eigen/src/Core/CoreEvaluators.h
+++ b/Eigen/src/Core/CoreEvaluators.h
@@ -53,11 +53,7 @@ struct storage_kind_to_shape<Sparse> {
};
*/
-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,
diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h
index c9ab63782..675f6ee8d 100644
--- a/Eigen/src/Core/GeneralProduct.h
+++ b/Eigen/src/Core/GeneralProduct.h
@@ -623,7 +623,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
return Product<Derived, OtherDerived>(derived(), other.derived());
}
-#else
+#else // EIGEN_TEST_EVALUATORS
template<typename Derived>
template<typename OtherDerived>
inline const typename ProductReturnType<Derived, OtherDerived>::Type
@@ -653,9 +653,10 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
#endif
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
}
-#endif
+#endif // EIGEN_TEST_EVALUATORS
+
+#endif // __CUDACC__
-#endif
/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
*
* The returned product will behave like any other expressions: the coefficients of the product will be
@@ -667,6 +668,31 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
*
* \sa operator*(const MatrixBase&)
*/
+#ifdef EIGEN_TEST_EVALUATORS
+template<typename Derived>
+template<typename OtherDerived>
+const Product<Derived,OtherDerived,LazyProduct>
+MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
+{
+ enum {
+ ProductIsValid = Derived::ColsAtCompileTime==Dynamic
+ || OtherDerived::RowsAtCompileTime==Dynamic
+ || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
+ AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
+ SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
+ };
+ // note to the lost user:
+ // * for a dot product use: v1.dot(v2)
+ // * for a coeff-wise product use: v1.cwiseProduct(v2)
+ EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
+ INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
+ EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
+ INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
+ EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
+
+ return Product<Derived,OtherDerived,LazyProduct>(derived(), other.derived());
+}
+#else // EIGEN_TEST_EVALUATORS
template<typename Derived>
template<typename OtherDerived>
const typename LazyProductReturnType<Derived,OtherDerived>::Type
@@ -690,6 +716,7 @@ MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
}
+#endif // EIGEN_TEST_EVALUATORS
} // end namespace Eigen
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 61798317e..37e7408a4 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -199,7 +199,11 @@ template<typename Derived> class MatrixBase
template<typename OtherDerived>
EIGEN_DEVICE_FUNC
+#ifdef EIGEN_TEST_EVALUATORS
+ const Product<Derived,OtherDerived,LazyProduct>
+#else
const typename LazyProductReturnType<Derived,OtherDerived>::Type
+#endif
lazyProduct(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h
index 65117a806..6ac525336 100644
--- a/Eigen/src/Core/NoAlias.h
+++ b/Eigen/src/Core/NoAlias.h
@@ -34,6 +34,33 @@ class NoAlias
typedef typename ExpressionType::Scalar Scalar;
NoAlias(ExpressionType& expression) : m_expression(expression) {}
+
+#ifdef EIGEN_TEST_EVALUATORS
+ template<typename OtherDerived>
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
+ {
+ call_assignment(*this, other.derived(), internal::assign_op<Scalar>());
+ return m_expression;
+ }
+
+ template<typename OtherDerived>
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
+ {
+ call_assignment(*this, other.derived(), internal::add_assign_op<Scalar>());
+ return m_expression;
+ }
+
+ template<typename OtherDerived>
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
+ {
+ call_assignment(*this, other.derived(), internal::sub_assign_op<Scalar>());
+ return m_expression;
+ }
+
+#else
/** Behaves like MatrixBase::lazyAssign(other)
* \sa MatrixBase::lazyAssign() */
@@ -93,6 +120,8 @@ class NoAlias
{ return m_expression = func; }
#endif
+#endif
+
EIGEN_DEVICE_FUNC
ExpressionType& expression() const
{
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index 3b8fd7d9a..b37fd2ff7 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -79,6 +79,12 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
const LhsNestedCleaned& lhs() const { return m_lhs; }
const RhsNestedCleaned& rhs() const { return m_rhs; }
+
+ /** Convertion to scalar for inner-products */
+ operator const Scalar() const {
+ EIGEN_STATIC_ASSERT(SizeAtCompileTime==1, IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY);
+ return typename internal::evaluator<Product>::type(*this).coeff(0,0);
+ }
protected:
diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h
index d0dba1644..5dd480cad 100644
--- a/Eigen/src/Core/ProductEvaluators.h
+++ b/Eigen/src/Core/ProductEvaluators.h
@@ -209,12 +209,12 @@ struct dense_product_impl<Lhs,Rhs,GemmProduct> : dense_product_impl_base<Lhs,Rhs
{
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
- template<typename Dest>
- static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
- {
- // TODO bypass GeneralProduct class
- GeneralProduct<Lhs, Rhs, GemmProduct>(lhs,rhs).scaleAndAddTo(dst, alpha);
- }
+// template<typename Dest>
+// static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
+// {
+// // TODO bypass GeneralProduct class
+// GeneralProduct<Lhs, Rhs, GemmProduct>(lhs,rhs).scaleAndAddTo(dst, alpha);
+// }
};
template<typename Lhs, typename Rhs>
@@ -225,22 +225,28 @@ struct dense_product_impl<Lhs,Rhs,CoeffBasedProductMode>
template<typename Dst>
static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{
- // TODO: use the following instead of calling call_assignment
+ // TODO: use the following instead of calling call_assignment, same for the other methods
// dst = lazyprod(lhs,rhs);
call_assignment(dst, lazyprod(lhs,rhs), internal::assign_op<Scalar>());
}
template<typename Dst>
static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
- { dst += lazyprod(lhs,rhs); }
+ {
+ // dst += lazyprod(lhs,rhs);
+ call_assignment(dst, lazyprod(lhs,rhs), internal::add_assign_op<Scalar>());
+ }
template<typename Dst>
static inline void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
- { dst -= lazyprod(lhs,rhs); }
+ {
+ // dst -= lazyprod(lhs,rhs);
+ call_assignment(dst, lazyprod(lhs,rhs), internal::sub_assign_op<Scalar>());
+ }
- template<typename Dst>
- static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
- { dst += alpha * lazyprod(lhs,rhs); }
+// template<typename Dst>
+// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
+// { dst += alpha * lazyprod(lhs,rhs); }
};
template<typename Lhs, typename Rhs>
@@ -286,7 +292,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape,
CoeffReadCost = traits<CoeffBasedProductType>::CoeffReadCost,
Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
CanVectorizeInner = traits<CoeffBasedProductType>::CanVectorizeInner,
- Flags = CoeffBasedProductType::Flags
+ Flags = traits<CoeffBasedProductType>::Flags
};
typedef typename evaluator<Lhs>::type LhsEtorType;
diff --git a/Eigen/src/Core/products/CoeffBasedProduct.h b/Eigen/src/Core/products/CoeffBasedProduct.h
index 637513132..c987a30b0 100644
--- a/Eigen/src/Core/products/CoeffBasedProduct.h
+++ b/Eigen/src/Core/products/CoeffBasedProduct.h
@@ -14,7 +14,7 @@
namespace Eigen {
namespace internal {
-
+
/*********************************************************************************
* Coefficient based product implementation.
* It is designed for the following use cases:
@@ -110,6 +110,8 @@ struct traits<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> >
} // end namespace internal
+#ifndef EIGEN_TEST_EVALUATORS
+
template<typename LhsNested, typename RhsNested, int NestingFlags>
class CoeffBasedProduct
: internal::no_assignment_operator,
@@ -447,6 +449,8 @@ struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
} // end namespace internal
+#endif // EIGEN_TEST_EVALUATORS
+
} // end namespace Eigen
#endif // EIGEN_COEFFBASED_PRODUCT_H
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index 776eac587..3bc151229 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -36,6 +36,12 @@ template<typename Derived> struct accessors_level
};
};
+template<typename T> struct evaluator_traits;
+
+template< typename T,
+ typename Kind = typename evaluator_traits<T>::Kind,
+ typename Scalar = typename T::Scalar> struct evaluator;
+
} // end namespace internal
template<typename T> struct NumTraits;
diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h
index 8872c5b64..b9b1ee02a 100644
--- a/Eigen/src/Core/util/StaticAssert.h
+++ b/Eigen/src/Core/util/StaticAssert.h
@@ -90,7 +90,8 @@
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
- OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
+ OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG,
+ IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY
};
};