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 13namespace 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 30namespace internal { 31template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> 32struct 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 & HereditaryBits, 47 CoeffReadCost = traits<typename remove_all<ConditionMatrixNested>::type>::CoeffReadCost 48 + EIGEN_SIZE_MAX(traits<typename remove_all<ThenMatrixNested>::type>::CoeffReadCost, 49 traits<typename remove_all<ElseMatrixNested>::type>::CoeffReadCost) 50 }; 51}; 52} 53 54template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> 55class Select : internal::no_assignment_operator, 56 public internal::dense_xpr_base< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::type 57{ 58 public: 59 60 typedef typename internal::dense_xpr_base<Select>::type Base; 61 EIGEN_DENSE_PUBLIC_INTERFACE(Select) 62 63 Select(const ConditionMatrixType& conditionMatrix, 64 const ThenMatrixType& thenMatrix, 65 const ElseMatrixType& elseMatrix) 66 : m_condition(conditionMatrix), m_then(thenMatrix), m_else(elseMatrix) 67 { 68 eigen_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows()); 69 eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols()); 70 } 71 72 Index rows() const { return m_condition.rows(); } 73 Index cols() const { return m_condition.cols(); } 74 75 const Scalar coeff(Index i, Index j) const 76 { 77 if (m_condition.coeff(i,j)) 78 return m_then.coeff(i,j); 79 else 80 return m_else.coeff(i,j); 81 } 82 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 const ConditionMatrixType& conditionMatrix() const 92 { 93 return m_condition; 94 } 95 96 const ThenMatrixType& thenMatrix() const 97 { 98 return m_then; 99 } 100 101 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 */ 121template<typename Derived> 122template<typename ThenDerived,typename ElseDerived> 123inline const Select<Derived,ThenDerived,ElseDerived> 124DenseBase<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 */ 135template<typename Derived> 136template<typename ThenDerived> 137inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> 138DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix, 139 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 */ 150template<typename Derived> 151template<typename ElseDerived> 152inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > 153DenseBase<Derived>::select(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