Select.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_SELECT_H
00026 #define EIGEN_SELECT_H
00027 
00028 namespace Eigen { 
00029 
00045 namespace internal {
00046 template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
00047 struct traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
00048  : traits<ThenMatrixType>
00049 {
00050   typedef typename traits<ThenMatrixType>::Scalar Scalar;
00051   typedef Dense StorageKind;
00052   typedef typename traits<ThenMatrixType>::XprKind XprKind;
00053   typedef typename ConditionMatrixType::Nested ConditionMatrixNested;
00054   typedef typename ThenMatrixType::Nested ThenMatrixNested;
00055   typedef typename ElseMatrixType::Nested ElseMatrixNested;
00056   enum {
00057     RowsAtCompileTime = ConditionMatrixType::RowsAtCompileTime,
00058     ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime,
00059     MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
00060     MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
00061     Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits,
00062     CoeffReadCost = traits<typename remove_all<ConditionMatrixNested>::type>::CoeffReadCost
00063                   + EIGEN_SIZE_MAX(traits<typename remove_all<ThenMatrixNested>::type>::CoeffReadCost,
00064                                    traits<typename remove_all<ElseMatrixNested>::type>::CoeffReadCost)
00065   };
00066 };
00067 }
00068 
00069 template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
00070 class Select : internal::no_assignment_operator,
00071   public internal::dense_xpr_base< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::type
00072 {
00073   public:
00074 
00075     typedef typename internal::dense_xpr_base<Select>::type Base;
00076     EIGEN_DENSE_PUBLIC_INTERFACE(Select)
00077 
00078     Select(const ConditionMatrixType& conditionMatrix,
00079            const ThenMatrixType& thenMatrix,
00080            const ElseMatrixType& elseMatrix)
00081       : m_condition(conditionMatrix), m_then(thenMatrix), m_else(elseMatrix)
00082     {
00083       eigen_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows());
00084       eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
00085     }
00086 
00087     Index rows() const { return m_condition.rows(); }
00088     Index cols() const { return m_condition.cols(); }
00089 
00090     const Scalar coeff(Index i, Index j) const
00091     {
00092       if (m_condition.coeff(i,j))
00093         return m_then.coeff(i,j);
00094       else
00095         return m_else.coeff(i,j);
00096     }
00097 
00098     const Scalar coeff(Index i) const
00099     {
00100       if (m_condition.coeff(i))
00101         return m_then.coeff(i);
00102       else
00103         return m_else.coeff(i);
00104     }
00105 
00106     const ConditionMatrixType& conditionMatrix() const
00107     {
00108       return m_condition;
00109     }
00110 
00111     const ThenMatrixType& thenMatrix() const
00112     {
00113       return m_then;
00114     }
00115 
00116     const ElseMatrixType& elseMatrix() const
00117     {
00118       return m_else;
00119     }
00120 
00121   protected:
00122     typename ConditionMatrixType::Nested m_condition;
00123     typename ThenMatrixType::Nested m_then;
00124     typename ElseMatrixType::Nested m_else;
00125 };
00126 
00127 
00136 template<typename Derived>
00137 template<typename ThenDerived,typename ElseDerived>
00138 inline const Select<Derived,ThenDerived,ElseDerived>
00139 DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
00140                             const DenseBase<ElseDerived>& elseMatrix) const
00141 {
00142   return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived());
00143 }
00144 
00150 template<typename Derived>
00151 template<typename ThenDerived>
00152 inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
00153 DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
00154                             typename ThenDerived::Scalar elseScalar) const
00155 {
00156   return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>(
00157     derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
00158 }
00159 
00165 template<typename Derived>
00166 template<typename ElseDerived>
00167 inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
00168 DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar,
00169                             const DenseBase<ElseDerived>& elseMatrix) const
00170 {
00171   return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>(
00172     derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
00173 }
00174 
00175 } // end namespace Eigen
00176 
00177 #endif // EIGEN_SELECT_H