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 | |