aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-09-04 11:22:32 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-09-04 11:22:32 +0200
commitb0aa2520f120f256c00357948149b64661e54783 (patch)
treea81cb32fdd9d9fd2104d5d06ada5192e5a59edb5 /Eigen
parent6902ef0824221391d159d153285f3d2142fdcd5b (diff)
* add real scalar * complex matrix, real matrix * complex scalar,
and complex scalar * real matrix overloads * allows the inner and outer product specialisations to mix real and complex
Diffstat (limited to 'Eigen')
-rw-r--r--Eigen/src/Core/CwiseUnaryOp.h14
-rw-r--r--Eigen/src/Core/MatrixBase.h13
-rw-r--r--Eigen/src/Core/Product.h28
-rw-r--r--Eigen/src/Core/ProductBase.h4
-rw-r--r--Eigen/src/Core/util/XprHelper.h4
5 files changed, 43 insertions, 20 deletions
diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h
index 6e4c0d4ec..03011800c 100644
--- a/Eigen/src/Core/CwiseUnaryOp.h
+++ b/Eigen/src/Core/CwiseUnaryOp.h
@@ -232,7 +232,7 @@ Cwise<ExpressionType>::log() const
}
-/** \relates MatrixBase */
+/** \returns an expression of \c *this scaled by the scalar factor \a scalar */
template<typename Derived>
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ScalarMultipleReturnType
MatrixBase<Derived>::operator*(const Scalar& scalar) const
@@ -241,7 +241,17 @@ MatrixBase<Derived>::operator*(const Scalar& scalar) const
(derived(), ei_scalar_multiple_op<Scalar>(scalar));
}
-/** \relates MatrixBase */
+/** Overloaded for efficient real matrix times complex scalar value */
+template<typename Derived>
+EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_multiple2_op<typename ei_traits<Derived>::Scalar,
+ std::complex<typename ei_traits<Derived>::Scalar> >, Derived>
+MatrixBase<Derived>::operator*(const std::complex<Scalar>& scalar) const
+{
+ return CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived>
+ (*static_cast<const Derived*>(this), ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >(scalar));
+}
+
+/** \returns an expression of \c *this divided by the scalar value \a scalar */
template<typename Derived>
EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
MatrixBase<Derived>::operator/(const Scalar& scalar) const
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index fececdd5f..ad5fde562 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -35,7 +35,7 @@
*
* Notice that this class is trivial, it is only used to disambiguate overloaded functions.
*/
-template<typename Derived> struct AnyMatrixBase
+template<typename Derived> struct AnyMatrixBase
: public ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar,
typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>
{
@@ -93,7 +93,7 @@ template<typename Derived> struct AnyMatrixBase
*/
template<typename Derived> class MatrixBase
#ifndef EIGEN_PARSED_BY_DOXYGEN
- : public AnyMatrixBase<Derived>
+ : public AnyMatrixBase<Derived>
#endif // not EIGEN_PARSED_BY_DOXYGEN
{
public:
@@ -419,10 +419,17 @@ template<typename Derived> class MatrixBase
const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
operator/(const Scalar& scalar) const;
- inline friend const CwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
+ const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived>
+ operator*(const std::complex<Scalar>& scalar) const;
+
+ inline friend const ScalarMultipleReturnType
operator*(const Scalar& scalar, const MatrixBase& matrix)
{ return matrix*scalar; }
+ inline friend const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived>
+ operator*(const std::complex<Scalar>& scalar, const MatrixBase& matrix)
+ { return matrix*scalar; }
+
template<typename OtherDerived>
const typename ProductReturnType<Derived,OtherDerived>::Type
operator*(const MatrixBase<OtherDerived> &other) const;
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index dfdbca839..e7227d4f6 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -84,18 +84,18 @@ public:
* based on the three dimensions of the product.
* This is a compile time mapping from {1,Small,Large}^3 -> {product types} */
// FIXME I'm not sure the current mapping is the ideal one.
-template<int Rows, int Cols> struct ei_product_type_selector<Rows,Cols,1> { enum { ret = OuterProduct }; };
-template<int Depth> struct ei_product_type_selector<1,1,Depth> { enum { ret = InnerProduct }; };
-template<> struct ei_product_type_selector<1,1,1> { enum { ret = InnerProduct }; };
-template<> struct ei_product_type_selector<Small,1,Small> { enum { ret = UnrolledProduct }; };
-template<> struct ei_product_type_selector<1,Small,Small> { enum { ret = UnrolledProduct }; };
+template<int Rows, int Cols> struct ei_product_type_selector<Rows, Cols, 1> { enum { ret = OuterProduct }; };
+template<int Depth> struct ei_product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; };
+template<> struct ei_product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; };
+template<> struct ei_product_type_selector<Small,1, Small> { enum { ret = UnrolledProduct }; };
+template<> struct ei_product_type_selector<1, Small,Small> { enum { ret = UnrolledProduct }; };
template<> struct ei_product_type_selector<Small,Small,Small> { enum { ret = UnrolledProduct }; };
-template<> struct ei_product_type_selector<1,Large,Small> { enum { ret = GemvProduct }; };
-template<> struct ei_product_type_selector<1,Large,Large> { enum { ret = GemvProduct }; };
-template<> struct ei_product_type_selector<1,Small,Large> { enum { ret = GemvProduct }; };
-template<> struct ei_product_type_selector<Large,1,Small> { enum { ret = GemvProduct }; };
-template<> struct ei_product_type_selector<Large,1,Large> { enum { ret = GemvProduct }; };
-template<> struct ei_product_type_selector<Small,1,Large> { enum { ret = GemvProduct }; };
+template<> struct ei_product_type_selector<1, Large,Small> { enum { ret = GemvProduct }; };
+template<> struct ei_product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; };
+template<> struct ei_product_type_selector<1, Small,Large> { enum { ret = GemvProduct }; };
+template<> struct ei_product_type_selector<Large,1, Small> { enum { ret = GemvProduct }; };
+template<> struct ei_product_type_selector<Large,1, Large> { enum { ret = GemvProduct }; };
+template<> struct ei_product_type_selector<Small,1, Large> { enum { ret = GemvProduct }; };
template<> struct ei_product_type_selector<Small,Small,Large> { enum { ret = GemmProduct }; };
template<> struct ei_product_type_selector<Large,Small,Large> { enum { ret = GemmProduct }; };
template<> struct ei_product_type_selector<Small,Large,Large> { enum { ret = GemmProduct }; };
@@ -164,7 +164,7 @@ class GeneralProduct<Lhs, Rhs, InnerProduct>
GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{
- EIGEN_STATIC_ASSERT((ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret),
+ EIGEN_STATIC_ASSERT((ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
}
@@ -203,7 +203,7 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{
- EIGEN_STATIC_ASSERT((ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret),
+ EIGEN_STATIC_ASSERT((ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
}
@@ -217,6 +217,7 @@ template<> struct ei_outer_product_selector<ColMajor> {
template<typename ProductType, typename Dest>
EIGEN_DONT_INLINE static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) {
// FIXME make sure lhs is sequentially stored
+ // FIXME not very good if rhs is real and lhs complex while alpha is real too
const int cols = dest.cols();
for (int j=0; j<cols; ++j)
dest.col(j) += (alpha * prod.rhs().coeff(j)) * prod.lhs();
@@ -227,6 +228,7 @@ template<> struct ei_outer_product_selector<RowMajor> {
template<typename ProductType, typename Dest>
EIGEN_DONT_INLINE static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) {
// FIXME make sure rhs is sequentially stored
+ // FIXME not very good if lhs is real and rhs complex while alpha is real too
const int rows = dest.rows();
for (int i=0; i<rows; ++i)
dest.row(i) += (alpha * prod.lhs().coeff(i)) * prod.rhs();
diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h
index b2c4cd989..764dc4d8e 100644
--- a/Eigen/src/Core/ProductBase.h
+++ b/Eigen/src/Core/ProductBase.h
@@ -33,7 +33,7 @@ struct ei_traits<ProductBase<Derived,_Lhs,_Rhs> >
{
typedef typename ei_cleantype<_Lhs>::type Lhs;
typedef typename ei_cleantype<_Rhs>::type Rhs;
- typedef typename ei_traits<Lhs>::Scalar Scalar;
+ typedef typename ei_scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;
enum {
RowsAtCompileTime = ei_traits<Lhs>::RowsAtCompileTime,
ColsAtCompileTime = ei_traits<Rhs>::ColsAtCompileTime,
@@ -146,7 +146,7 @@ class ScaledProduct;
// functions of ProductBase, because, otherwise we would have to
// define all overloads defined in MatrixBase. Furthermore, Using
// "using Base::operator*" would not work with MSVC.
-//
+//
// Also note that here we accept any compatible scalar types
template<typename Derived,typename Lhs,typename Rhs>
const ScaledProduct<Derived>
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index 871259b08..2f8d35d05 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -233,6 +233,10 @@ struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true>
return CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,OtherScalar>, Derived>
(*static_cast<const Derived*>(this), ei_scalar_multiple2_op<Scalar,OtherScalar>(scalar));
}
+
+ inline friend const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,OtherScalar>, Derived>
+ operator*(const OtherScalar& scalar, const Derived& matrix)
+ { return matrix*scalar; }
};
/** \internal Gives the type of a sub-matrix or sub-vector of a matrix of type \a ExpressionType and size \a Size