From ae039dde135a6af852d7028abd772316613a5249 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 27 Jun 2014 15:53:51 +0200 Subject: [PATCH] Add a NoPreferredStorageOrderBit flag for expression having no preferred storage order. It is currently only used in Product. --- Eigen/src/Core/DiagonalMatrix.h | 6 +++--- Eigen/src/Core/Product.h | 15 ++++++++++++++- Eigen/src/Core/util/Constants.h | 10 ++++++++++ Eigen/src/SparseCore/SparseAssign.h | 2 +- Eigen/src/SparseCore/SparseMatrix.h | 2 +- Eigen/src/SparseCore/SparseUtil.h | 2 +- 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h index fc9ecf561..7a0b736f1 100644 --- a/Eigen/src/Core/DiagonalMatrix.h +++ b/Eigen/src/Core/DiagonalMatrix.h @@ -30,7 +30,7 @@ class DiagonalBase : public EigenBase MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, IsVectorAtCompileTime = 0, - Flags = 0 + Flags = NoPreferredStorageOrderBit }; typedef Matrix DenseMatrixType; @@ -159,7 +159,7 @@ struct traits > typedef Dense StorageKind; typedef DenseIndex Index; enum { - Flags = LvalueBit + Flags = LvalueBit | NoPreferredStorageOrderBit }; }; } @@ -287,7 +287,7 @@ struct traits > ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, - Flags = traits::Flags & LvalueBit + Flags = (traits::Flags & LvalueBit) | NoPreferredStorageOrderBit #ifndef EIGEN_TEST_EVALUATORS , CoeffReadCost = traits<_DiagonalVectorType>::CoeffReadCost diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 626b737c7..e381ac46a 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -82,7 +82,10 @@ struct traits > #endif // The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator. - Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0) + Flags = ( MaxRowsAtCompileTime==1 + || ((LhsCleaned::Flags&NoPreferredStorageOrderBit) && (RhsCleaned::Flags&RowMajorBit)) + || ((RhsCleaned::Flags&NoPreferredStorageOrderBit) && (LhsCleaned::Flags&RowMajorBit)) ) + ? RowMajorBit : (MaxColsAtCompileTime==1 ? 0 : NoPreferredStorageOrderBit) }; }; @@ -156,6 +159,16 @@ public: } // namespace internal +#ifdef EIGEN_TEST_EVALUATORS +// Generic API dispatcher +template +class ProductImpl : public internal::generic_xpr_base, MatrixXpr, StorageKind>::type +{ + public: + typedef typename internal::generic_xpr_base, MatrixXpr, StorageKind>::type Base; +}; +#endif + template class ProductImpl : public internal::dense_product_base diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index aae8625d1..131f5d793 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -154,6 +154,16 @@ const unsigned int AlignedBit = 0x80; const unsigned int NestByRefBit = 0x100; +/** \ingroup flags + * + * for an expression, this means that the storage order + * can be either row-major or column-major. + * The precise choice will be decided at evaluation time or when + * combined with other expressions. + * \sa \ref RowMajorBit, \ref TopicStorageOrders */ +const unsigned int NoPreferredStorageOrderBit = 0x200; + + // list of flags that are inherited by default const unsigned int HereditaryBits = RowMajorBit | EvalBeforeNestingBit diff --git a/Eigen/src/SparseCore/SparseAssign.h b/Eigen/src/SparseCore/SparseAssign.h index 86a0b08c5..68a6ca20e 100644 --- a/Eigen/src/SparseCore/SparseAssign.h +++ b/Eigen/src/SparseCore/SparseAssign.h @@ -220,7 +220,7 @@ void assign_sparse_to_sparse(DstXprType &dst, const SrcXprType &src) for (Index j=0; j& SparseMatrix::value), YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + const bool needToTranspose = (Flags & RowMajorBit) != (internal::evaluator::Flags & RowMajorBit); if (needToTranspose) { // two passes algorithm: diff --git a/Eigen/src/SparseCore/SparseUtil.h b/Eigen/src/SparseCore/SparseUtil.h index 2a67af291..0dfa15f7c 100644 --- a/Eigen/src/SparseCore/SparseUtil.h +++ b/Eigen/src/SparseCore/SparseUtil.h @@ -149,7 +149,7 @@ template struct plain_matrix_type { typedef typename traits::Scalar _Scalar; typedef typename traits::Index _Index; - enum { _Options = ((traits::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor }; + enum { _Options = ((evaluator::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor }; public: typedef SparseMatrix<_Scalar, _Options, _Index> type; };