| 1 | // This file is part of Eigen, a lightweight C++ template library | 
|---|
| 2 | // for linear algebra. | 
|---|
| 3 | // | 
|---|
| 4 | // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> | 
|---|
| 5 | // | 
|---|
| 6 | // This Source Code Form is subject to the terms of the Mozilla | 
|---|
| 7 | // Public License v. 2.0. If a copy of the MPL was not distributed | 
|---|
| 8 | // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | 
|---|
| 9 |  | 
|---|
| 10 | #ifndef EIGEN_SELECT_H | 
|---|
| 11 | #define EIGEN_SELECT_H | 
|---|
| 12 |  | 
|---|
| 13 | namespace Eigen { | 
|---|
| 14 |  | 
|---|
| 15 | /** \class Select | 
|---|
| 16 | * \ingroup Core_Module | 
|---|
| 17 | * | 
|---|
| 18 | * \brief Expression of a coefficient wise version of the C++ ternary operator ?: | 
|---|
| 19 | * | 
|---|
| 20 | * \param ConditionMatrixType the type of the \em condition expression which must be a boolean matrix | 
|---|
| 21 | * \param ThenMatrixType the type of the \em then expression | 
|---|
| 22 | * \param ElseMatrixType the type of the \em else expression | 
|---|
| 23 | * | 
|---|
| 24 | * This class represents an expression of a coefficient wise version of the C++ ternary operator ?:. | 
|---|
| 25 | * It is the return type of DenseBase::select() and most of the time this is the only way it is used. | 
|---|
| 26 | * | 
|---|
| 27 | * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const | 
|---|
| 28 | */ | 
|---|
| 29 |  | 
|---|
| 30 | namespace internal { | 
|---|
| 31 | template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> | 
|---|
| 32 | struct traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> > | 
|---|
| 33 | : traits<ThenMatrixType> | 
|---|
| 34 | { | 
|---|
| 35 | typedef typename traits<ThenMatrixType>::Scalar Scalar; | 
|---|
| 36 | typedef Dense StorageKind; | 
|---|
| 37 | typedef typename traits<ThenMatrixType>::XprKind XprKind; | 
|---|
| 38 | typedef typename ConditionMatrixType::Nested ConditionMatrixNested; | 
|---|
| 39 | typedef typename ThenMatrixType::Nested ThenMatrixNested; | 
|---|
| 40 | typedef typename ElseMatrixType::Nested ElseMatrixNested; | 
|---|
| 41 | enum { | 
|---|
| 42 | RowsAtCompileTime = ConditionMatrixType::RowsAtCompileTime, | 
|---|
| 43 | ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime, | 
|---|
| 44 | MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime, | 
|---|
| 45 | MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime, | 
|---|
| 46 | Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & RowMajorBit | 
|---|
| 47 | }; | 
|---|
| 48 | }; | 
|---|
| 49 | } | 
|---|
| 50 |  | 
|---|
| 51 | template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> | 
|---|
| 52 | class Select : public internal::dense_xpr_base< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::type, | 
|---|
| 53 | internal::no_assignment_operator | 
|---|
| 54 | { | 
|---|
| 55 | public: | 
|---|
| 56 |  | 
|---|
| 57 | typedef typename internal::dense_xpr_base<Select>::type Base; | 
|---|
| 58 | EIGEN_DENSE_PUBLIC_INTERFACE(Select) | 
|---|
| 59 |  | 
|---|
| 60 | inline EIGEN_DEVICE_FUNC | 
|---|
| 61 | Select(const ConditionMatrixType& a_conditionMatrix, | 
|---|
| 62 | const ThenMatrixType& a_thenMatrix, | 
|---|
| 63 | const ElseMatrixType& a_elseMatrix) | 
|---|
| 64 | : m_condition(a_conditionMatrix), m_then(a_thenMatrix), m_else(a_elseMatrix) | 
|---|
| 65 | { | 
|---|
| 66 | eigen_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows()); | 
|---|
| 67 | eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols()); | 
|---|
| 68 | } | 
|---|
| 69 |  | 
|---|
| 70 | inline EIGEN_DEVICE_FUNC Index rows() const { return m_condition.rows(); } | 
|---|
| 71 | inline EIGEN_DEVICE_FUNC Index cols() const { return m_condition.cols(); } | 
|---|
| 72 |  | 
|---|
| 73 | inline EIGEN_DEVICE_FUNC | 
|---|
| 74 | const Scalar coeff(Index i, Index j) const | 
|---|
| 75 | { | 
|---|
| 76 | if (m_condition.coeff(i,j)) | 
|---|
| 77 | return m_then.coeff(i,j); | 
|---|
| 78 | else | 
|---|
| 79 | return m_else.coeff(i,j); | 
|---|
| 80 | } | 
|---|
| 81 |  | 
|---|
| 82 | inline EIGEN_DEVICE_FUNC | 
|---|
| 83 | const Scalar coeff(Index i) const | 
|---|
| 84 | { | 
|---|
| 85 | if (m_condition.coeff(i)) | 
|---|
| 86 | return m_then.coeff(i); | 
|---|
| 87 | else | 
|---|
| 88 | return m_else.coeff(i); | 
|---|
| 89 | } | 
|---|
| 90 |  | 
|---|
| 91 | inline EIGEN_DEVICE_FUNC const ConditionMatrixType& conditionMatrix() const | 
|---|
| 92 | { | 
|---|
| 93 | return m_condition; | 
|---|
| 94 | } | 
|---|
| 95 |  | 
|---|
| 96 | inline EIGEN_DEVICE_FUNC const ThenMatrixType& thenMatrix() const | 
|---|
| 97 | { | 
|---|
| 98 | return m_then; | 
|---|
| 99 | } | 
|---|
| 100 |  | 
|---|
| 101 | inline EIGEN_DEVICE_FUNC const ElseMatrixType& elseMatrix() const | 
|---|
| 102 | { | 
|---|
| 103 | return m_else; | 
|---|
| 104 | } | 
|---|
| 105 |  | 
|---|
| 106 | protected: | 
|---|
| 107 | typename ConditionMatrixType::Nested m_condition; | 
|---|
| 108 | typename ThenMatrixType::Nested m_then; | 
|---|
| 109 | typename ElseMatrixType::Nested m_else; | 
|---|
| 110 | }; | 
|---|
| 111 |  | 
|---|
| 112 |  | 
|---|
| 113 | /** \returns a matrix where each coefficient (i,j) is equal to \a thenMatrix(i,j) | 
|---|
| 114 | * if \c *this(i,j), and \a elseMatrix(i,j) otherwise. | 
|---|
| 115 | * | 
|---|
| 116 | * Example: \include MatrixBase_select.cpp | 
|---|
| 117 | * Output: \verbinclude MatrixBase_select.out | 
|---|
| 118 | * | 
|---|
| 119 | * \sa class Select | 
|---|
| 120 | */ | 
|---|
| 121 | template<typename Derived> | 
|---|
| 122 | template<typename ThenDerived,typename ElseDerived> | 
|---|
| 123 | inline const Select<Derived,ThenDerived,ElseDerived> | 
|---|
| 124 | DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix, | 
|---|
| 125 | const DenseBase<ElseDerived>& elseMatrix) const | 
|---|
| 126 | { | 
|---|
| 127 | return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived()); | 
|---|
| 128 | } | 
|---|
| 129 |  | 
|---|
| 130 | /** Version of DenseBase::select(const DenseBase&, const DenseBase&) with | 
|---|
| 131 | * the \em else expression being a scalar value. | 
|---|
| 132 | * | 
|---|
| 133 | * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select | 
|---|
| 134 | */ | 
|---|
| 135 | template<typename Derived> | 
|---|
| 136 | template<typename ThenDerived> | 
|---|
| 137 | inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> | 
|---|
| 138 | DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix, | 
|---|
| 139 | const typename ThenDerived::Scalar& elseScalar) const | 
|---|
| 140 | { | 
|---|
| 141 | return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>( | 
|---|
| 142 | derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar)); | 
|---|
| 143 | } | 
|---|
| 144 |  | 
|---|
| 145 | /** Version of DenseBase::select(const DenseBase&, const DenseBase&) with | 
|---|
| 146 | * the \em then expression being a scalar value. | 
|---|
| 147 | * | 
|---|
| 148 | * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select | 
|---|
| 149 | */ | 
|---|
| 150 | template<typename Derived> | 
|---|
| 151 | template<typename ElseDerived> | 
|---|
| 152 | inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > | 
|---|
| 153 | DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar, | 
|---|
| 154 | const DenseBase<ElseDerived>& elseMatrix) const | 
|---|
| 155 | { | 
|---|
| 156 | return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>( | 
|---|
| 157 | derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived()); | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 | } // end namespace Eigen | 
|---|
| 161 |  | 
|---|
| 162 | #endif // EIGEN_SELECT_H | 
|---|
| 163 |  | 
|---|