1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
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_EIGENBASE_H
12 #define EIGEN_EIGENBASE_H
13
14 namespace Eigen {
15
16 /** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
17 *
18 * In other words, an EigenBase object is an object that can be copied into a MatrixBase.
19 *
20 * Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc.
21 *
22 * Notice that this class is trivial, it is only used to disambiguate overloaded functions.
23 *
24 * \sa \ref TopicClassHierarchy
25 */
26 template<typename Derived> struct EigenBase
27 {
28 // typedef typename internal::plain_matrix_type<Derived>::type PlainObject;
29
30 typedef typename internal::traits<Derived>::StorageKind StorageKind;
31 typedef typename internal::traits<Derived>::Index Index;
32
33 /** \returns a reference to the derived object */
derivedEigenBase34 Derived& derived() { return *static_cast<Derived*>(this); }
35 /** \returns a const reference to the derived object */
derivedEigenBase36 const Derived& derived() const { return *static_cast<const Derived*>(this); }
37
const_cast_derivedEigenBase38 inline Derived& const_cast_derived() const
39 { return *static_cast<Derived*>(const_cast<EigenBase*>(this)); }
const_derivedEigenBase40 inline const Derived& const_derived() const
41 { return *static_cast<const Derived*>(this); }
42
43 /** \returns the number of rows. \sa cols(), RowsAtCompileTime */
rowsEigenBase44 inline Index rows() const { return derived().rows(); }
45 /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
colsEigenBase46 inline Index cols() const { return derived().cols(); }
47 /** \returns the number of coefficients, which is rows()*cols().
48 * \sa rows(), cols(), SizeAtCompileTime. */
sizeEigenBase49 inline Index size() const { return rows() * cols(); }
50
51 /** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
evalToEigenBase52 template<typename Dest> inline void evalTo(Dest& dst) const
53 { derived().evalTo(dst); }
54
55 /** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */
addToEigenBase56 template<typename Dest> inline void addTo(Dest& dst) const
57 {
58 // This is the default implementation,
59 // derived class can reimplement it in a more optimized way.
60 typename Dest::PlainObject res(rows(),cols());
61 evalTo(res);
62 dst += res;
63 }
64
65 /** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */
subToEigenBase66 template<typename Dest> inline void subTo(Dest& dst) const
67 {
68 // This is the default implementation,
69 // derived class can reimplement it in a more optimized way.
70 typename Dest::PlainObject res(rows(),cols());
71 evalTo(res);
72 dst -= res;
73 }
74
75 /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */
applyThisOnTheRightEigenBase76 template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
77 {
78 // This is the default implementation,
79 // derived class can reimplement it in a more optimized way.
80 dst = dst * this->derived();
81 }
82
83 /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */
applyThisOnTheLeftEigenBase84 template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
85 {
86 // This is the default implementation,
87 // derived class can reimplement it in a more optimized way.
88 dst = this->derived() * dst;
89 }
90
91 };
92
93 /***************************************************************************
94 * Implementation of matrix base methods
95 ***************************************************************************/
96
97 /** \brief Copies the generic expression \a other into *this.
98 *
99 * \details The expression must provide a (templated) evalTo(Derived& dst) const
100 * function which does the actual job. In practice, this allows any user to write
101 * its own special matrix without having to modify MatrixBase
102 *
103 * \returns a reference to *this.
104 */
105 template<typename Derived>
106 template<typename OtherDerived>
107 Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
108 {
109 other.derived().evalTo(derived());
110 return derived();
111 }
112
113 template<typename Derived>
114 template<typename OtherDerived>
115 Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
116 {
117 other.derived().addTo(derived());
118 return derived();
119 }
120
121 template<typename Derived>
122 template<typename OtherDerived>
123 Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
124 {
125 other.derived().subTo(derived());
126 return derived();
127 }
128
129 /** replaces \c *this by \c *this * \a other.
130 *
131 * \returns a reference to \c *this
132 */
133 template<typename Derived>
134 template<typename OtherDerived>
135 inline Derived&
136 MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
137 {
138 other.derived().applyThisOnTheRight(derived());
139 return derived();
140 }
141
142 /** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=() */
143 template<typename Derived>
144 template<typename OtherDerived>
applyOnTheRight(const EigenBase<OtherDerived> & other)145 inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
146 {
147 other.derived().applyThisOnTheRight(derived());
148 }
149
150 /** replaces \c *this by \c *this * \a other. */
151 template<typename Derived>
152 template<typename OtherDerived>
applyOnTheLeft(const EigenBase<OtherDerived> & other)153 inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
154 {
155 other.derived().applyThisOnTheLeft(derived());
156 }
157
158 } // end namespace Eigen
159
160 #endif // EIGEN_EIGENBASE_H
161