1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_CWISE_H
12 #define EIGEN_CWISE_H
13 
14 namespace Eigen {
15 
16 /** \internal
17   * convenient macro to defined the return type of a cwise binary operation */
18 #define EIGEN_CWISE_BINOP_RETURN_TYPE(OP) \
19     CwiseBinaryOp<OP<typename internal::traits<ExpressionType>::Scalar>, ExpressionType, OtherDerived>
20 
21 /** \internal
22   * convenient macro to defined the return type of a cwise unary operation */
23 #define EIGEN_CWISE_UNOP_RETURN_TYPE(OP) \
24     CwiseUnaryOp<OP<typename internal::traits<ExpressionType>::Scalar>, ExpressionType>
25 
26 /** \internal
27   * convenient macro to defined the return type of a cwise comparison to a scalar */
28 #define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \
29     CwiseBinaryOp<OP<typename internal::traits<ExpressionType>::Scalar>, ExpressionType, \
30         typename ExpressionType::ConstantReturnType >
31 
32 /** \class Cwise
33   *
34   * \brief Pseudo expression providing additional coefficient-wise operations
35   *
36   * \param ExpressionType the type of the object on which to do coefficient-wise operations
37   *
38   * This class represents an expression with additional coefficient-wise features.
39   * It is the return type of MatrixBase::cwise()
40   * and most of the time this is the only way it is used.
41   *
42   * Example: \include MatrixBase_cwise_const.cpp
43   * Output: \verbinclude MatrixBase_cwise_const.out
44   *
45   * This class can be extended with the help of the plugin mechanism described on the page
46   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_CWISE_PLUGIN.
47   *
48   * \sa MatrixBase::cwise() const, MatrixBase::cwise()
49   */
50 template<typename ExpressionType> class Cwise
51 {
52   public:
53 
54     typedef typename internal::traits<ExpressionType>::Scalar Scalar;
55     typedef typename internal::conditional<internal::must_nest_by_value<ExpressionType>::ret,
56         ExpressionType, const ExpressionType&>::type ExpressionTypeNested;
57     typedef CwiseUnaryOp<internal::scalar_add_op<Scalar>, ExpressionType> ScalarAddReturnType;
58 
Cwise(const ExpressionType & matrix)59     inline Cwise(const ExpressionType& matrix) : m_matrix(matrix) {}
60 
61     /** \internal */
_expression()62     inline const ExpressionType& _expression() const { return m_matrix; }
63 
64     template<typename OtherDerived>
65     const EIGEN_CWISE_PRODUCT_RETURN_TYPE(ExpressionType,OtherDerived)
66     operator*(const MatrixBase<OtherDerived> &other) const;
67 
68     template<typename OtherDerived>
69     const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_quotient_op)
70     operator/(const MatrixBase<OtherDerived> &other) const;
71 
72     /** \deprecated ArrayBase::min() */
73     template<typename OtherDerived>
EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)74     const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)
75     (min)(const MatrixBase<OtherDerived> &other) const
76     { return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_min_op)(_expression(), other.derived()); }
77 
78     /** \deprecated ArrayBase::max() */
79     template<typename OtherDerived>
EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)80     const EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)
81     (max)(const MatrixBase<OtherDerived> &other) const
82     { return EIGEN_CWISE_BINOP_RETURN_TYPE(internal::scalar_max_op)(_expression(), other.derived()); }
83 
84     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs_op)      abs() const;
85     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_abs2_op)     abs2() const;
86     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_square_op)   square() const;
87     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_cube_op)     cube() const;
88     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_inverse_op)  inverse() const;
89     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_sqrt_op)     sqrt() const;
90     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_exp_op)      exp() const;
91     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_log_op)      log() const;
92     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_cos_op)      cos() const;
93     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_sin_op)      sin() const;
94     const EIGEN_CWISE_UNOP_RETURN_TYPE(internal::scalar_pow_op)      pow(const Scalar& exponent) const;
95 
96     const ScalarAddReturnType
97     operator+(const Scalar& scalar) const;
98 
99     /** \relates Cwise */
100     friend const ScalarAddReturnType
101     operator+(const Scalar& scalar, const Cwise& mat)
102     { return mat + scalar; }
103 
104     ExpressionType& operator+=(const Scalar& scalar);
105 
106     const ScalarAddReturnType
107     operator-(const Scalar& scalar) const;
108 
109     ExpressionType& operator-=(const Scalar& scalar);
110 
111     template<typename OtherDerived>
112     inline ExpressionType& operator*=(const MatrixBase<OtherDerived> &other);
113 
114     template<typename OtherDerived>
115     inline ExpressionType& operator/=(const MatrixBase<OtherDerived> &other);
116 
117     template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less)
118     operator<(const MatrixBase<OtherDerived>& other) const;
119 
120     template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal)
121     operator<=(const MatrixBase<OtherDerived>& other) const;
122 
123     template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater)
124     operator>(const MatrixBase<OtherDerived>& other) const;
125 
126     template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal)
127     operator>=(const MatrixBase<OtherDerived>& other) const;
128 
129     template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)
130     operator==(const MatrixBase<OtherDerived>& other) const;
131 
132     template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)
133     operator!=(const MatrixBase<OtherDerived>& other) const;
134 
135     // comparisons to a scalar value
136     const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)
137     operator<(Scalar s) const;
138 
139     const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)
140     operator<=(Scalar s) const;
141 
142     const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)
143     operator>(Scalar s) const;
144 
145     const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)
146     operator>=(Scalar s) const;
147 
148     const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)
149     operator==(Scalar s) const;
150 
151     const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)
152     operator!=(Scalar s) const;
153 
154     // allow to extend Cwise outside Eigen
155     #ifdef EIGEN_CWISE_PLUGIN
156     #include EIGEN_CWISE_PLUGIN
157     #endif
158 
159   protected:
160     ExpressionTypeNested m_matrix;
161 };
162 
163 
164 /** \returns a Cwise wrapper of *this providing additional coefficient-wise operations
165   *
166   * Example: \include MatrixBase_cwise_const.cpp
167   * Output: \verbinclude MatrixBase_cwise_const.out
168   *
169   * \sa class Cwise, cwise()
170   */
171 template<typename Derived>
cwise()172 inline const Cwise<Derived> MatrixBase<Derived>::cwise() const
173 {
174   return derived();
175 }
176 
177 /** \returns a Cwise wrapper of *this providing additional coefficient-wise operations
178   *
179   * Example: \include MatrixBase_cwise.cpp
180   * Output: \verbinclude MatrixBase_cwise.out
181   *
182   * \sa class Cwise, cwise() const
183   */
184 template<typename Derived>
cwise()185 inline Cwise<Derived> MatrixBase<Derived>::cwise()
186 {
187   return derived();
188 }
189 
190 } // end namespace Eigen
191 
192 #endif // EIGEN_CWISE_H
193