soc-2008-mxcurioni: merged changes to revision 23516
[blender.git] / extern / Eigen2 / Eigen / src / Array / Select.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_SELECT_H
26 #define EIGEN_SELECT_H
27
28 /** \array_module \ingroup Array
29   *
30   * \class Select
31   *
32   * \brief Expression of a coefficient wise version of the C++ ternary operator ?:
33   *
34   * \param ConditionMatrixType the type of the \em condition expression which must be a boolean matrix
35   * \param ThenMatrixType the type of the \em then expression
36   * \param ElseMatrixType the type of the \em else expression
37   *
38   * This class represents an expression of a coefficient wise version of the C++ ternary operator ?:.
39   * It is the return type of MatrixBase::select() and most of the time this is the only way it is used.
40   *
41   * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const
42   */
43
44 template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
45 struct ei_traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
46 {
47   typedef typename ei_traits<ThenMatrixType>::Scalar Scalar;
48   typedef typename ConditionMatrixType::Nested ConditionMatrixNested;
49   typedef typename ThenMatrixType::Nested ThenMatrixNested;
50   typedef typename ElseMatrixType::Nested ElseMatrixNested;
51   enum {
52     RowsAtCompileTime = ConditionMatrixType::RowsAtCompileTime,
53     ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime,
54     MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
55     MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
56     Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits,
57         CoeffReadCost = ei_traits<typename ei_cleantype<ConditionMatrixNested>::type>::CoeffReadCost
58         + EIGEN_ENUM_MAX(ei_traits<typename ei_cleantype<ThenMatrixNested>::type>::CoeffReadCost,
59                          ei_traits<typename ei_cleantype<ElseMatrixNested>::type>::CoeffReadCost)
60   };
61 };
62
63 template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
64 class Select : ei_no_assignment_operator,
65   public MatrixBase<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
66 {
67   public:
68
69     EIGEN_GENERIC_PUBLIC_INTERFACE(Select)
70
71     Select(const ConditionMatrixType& conditionMatrix,
72            const ThenMatrixType& thenMatrix,
73            const ElseMatrixType& elseMatrix)
74       : m_condition(conditionMatrix), m_then(thenMatrix), m_else(elseMatrix)
75     {
76       ei_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows());
77       ei_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
78     }
79
80     int rows() const { return m_condition.rows(); }
81     int cols() const { return m_condition.cols(); }
82
83     const Scalar coeff(int i, int j) const
84     {
85       if (m_condition.coeff(i,j))
86         return m_then.coeff(i,j);
87       else
88         return m_else.coeff(i,j);
89     }
90     
91     const Scalar coeff(int i) const
92     {
93       if (m_condition.coeff(i))
94         return m_then.coeff(i);
95       else
96         return m_else.coeff(i);
97     }
98
99   protected:
100     const typename ConditionMatrixType::Nested m_condition;
101     const typename ThenMatrixType::Nested m_then;
102     const typename ElseMatrixType::Nested m_else;
103 };
104
105
106 /** \array_module
107   *
108   * \returns a matrix where each coefficient (i,j) is equal to \a thenMatrix(i,j)
109   * if \c *this(i,j), and \a elseMatrix(i,j) otherwise.
110   *
111   * Example: \include MatrixBase_select.cpp
112   * Output: \verbinclude MatrixBase_select.out
113   *
114   * \sa class Select
115   */
116 template<typename Derived>
117 template<typename ThenDerived,typename ElseDerived>
118 inline const Select<Derived,ThenDerived,ElseDerived>
119 MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix,
120                             const MatrixBase<ElseDerived>& elseMatrix) const
121 {
122   return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived());
123 }
124
125 /** \array_module
126   *
127   * Version of MatrixBase::select(const MatrixBase&, const MatrixBase&) with
128   * the \em else expression being a scalar value.
129   *
130   * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const, class Select
131   */
132 template<typename Derived>
133 template<typename ThenDerived>
134 inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> >
135 MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix,
136                             typename ThenDerived::Scalar elseScalar) const
137 {
138   return Select<Derived,ThenDerived,NestByValue<typename ThenDerived::ConstantReturnType> >(
139     derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
140 }
141
142 /** \array_module
143   *
144   * Version of MatrixBase::select(const MatrixBase&, const MatrixBase&) with
145   * the \em then expression being a scalar value.
146   *
147   * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const, class Select
148   */
149 template<typename Derived>
150 template<typename ElseDerived>
151 inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived >
152 MatrixBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
153                             const MatrixBase<ElseDerived>& elseMatrix) const
154 {
155   return Select<Derived,NestByValue<typename ElseDerived::ConstantReturnType>,ElseDerived>(
156     derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
157 }
158
159 #endif // EIGEN_SELECT_H