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
14namespace 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  */
50template<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
59    inline Cwise(const ExpressionType& matrix) : m_matrix(matrix) {}
60
61    /** \internal */
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>
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>
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  */
171template<typename Derived>
172inline 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  */
184template<typename Derived>
185inline Cwise<Derived> MatrixBase<Derived>::cwise()
186{
187  return derived();
188}
189
190} // end namespace Eigen
191
192#endif // EIGEN_CWISE_H
193