remove $Id: tags after discussion on the mailign list: http://markmail.org/message...
[blender.git] / extern / Eigen3 / Eigen / src / Core / ArrayBase.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.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_ARRAYBASE_H
26 #define EIGEN_ARRAYBASE_H
27
28 template<typename ExpressionType> class MatrixWrapper;
29
30 /** \class ArrayBase
31   * \ingroup Core_Module
32   *
33   * \brief Base class for all 1D and 2D array, and related expressions
34   *
35   * An array is similar to a dense vector or matrix. While matrices are mathematical
36   * objects with well defined linear algebra operators, an array is just a collection
37   * of scalar values arranged in a one or two dimensionnal fashion. As the main consequence,
38   * all operations applied to an array are performed coefficient wise. Furthermore,
39   * arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient
40   * constructors allowing to easily write generic code working for both scalar values
41   * and arrays.
42   *
43   * This class is the base that is inherited by all array expression types.
44   *
45   * \tparam Derived is the derived type, e.g., an array or an expression type.
46   *
47   * This class can be extended with the help of the plugin mechanism described on the page
48   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN.
49   *
50   * \sa class MatrixBase, \ref TopicClassHierarchy
51   */
52 template<typename Derived> class ArrayBase
53   : public DenseBase<Derived>
54 {
55   public:
56 #ifndef EIGEN_PARSED_BY_DOXYGEN
57     /** The base class for a given storage type. */
58     typedef ArrayBase StorageBaseType;
59
60     typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl;
61
62     using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
63                 typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
64
65     typedef typename internal::traits<Derived>::StorageKind StorageKind;
66     typedef typename internal::traits<Derived>::Index Index;
67     typedef typename internal::traits<Derived>::Scalar Scalar;
68     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
69     typedef typename NumTraits<Scalar>::Real RealScalar;
70
71     typedef DenseBase<Derived> Base;
72     using Base::RowsAtCompileTime;
73     using Base::ColsAtCompileTime;
74     using Base::SizeAtCompileTime;
75     using Base::MaxRowsAtCompileTime;
76     using Base::MaxColsAtCompileTime;
77     using Base::MaxSizeAtCompileTime;
78     using Base::IsVectorAtCompileTime;
79     using Base::Flags;
80     using Base::CoeffReadCost;
81
82     using Base::derived;
83     using Base::const_cast_derived;
84     using Base::rows;
85     using Base::cols;
86     using Base::size;
87     using Base::coeff;
88     using Base::coeffRef;
89     using Base::lazyAssign;
90     using Base::operator=;
91     using Base::operator+=;
92     using Base::operator-=;
93     using Base::operator*=;
94     using Base::operator/=;
95
96     typedef typename Base::CoeffReturnType CoeffReturnType;
97
98 #endif // not EIGEN_PARSED_BY_DOXYGEN
99
100 #ifndef EIGEN_PARSED_BY_DOXYGEN
101     /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily
102       * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const
103       * reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either
104       * PlainObject or const PlainObject&.
105       */
106     typedef Array<typename internal::traits<Derived>::Scalar,
107                 internal::traits<Derived>::RowsAtCompileTime,
108                 internal::traits<Derived>::ColsAtCompileTime,
109                 AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
110                 internal::traits<Derived>::MaxRowsAtCompileTime,
111                 internal::traits<Derived>::MaxColsAtCompileTime
112           > PlainObject;
113
114
115     /** \internal Represents a matrix with all coefficients equal to one another*/
116     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
117 #endif // not EIGEN_PARSED_BY_DOXYGEN
118
119 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
120 #   include "../plugins/CommonCwiseUnaryOps.h"
121 #   include "../plugins/MatrixCwiseUnaryOps.h"
122 #   include "../plugins/ArrayCwiseUnaryOps.h"
123 #   include "../plugins/CommonCwiseBinaryOps.h"
124 #   include "../plugins/MatrixCwiseBinaryOps.h"
125 #   include "../plugins/ArrayCwiseBinaryOps.h"
126 #   ifdef EIGEN_ARRAYBASE_PLUGIN
127 #     include EIGEN_ARRAYBASE_PLUGIN
128 #   endif
129 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
130
131     /** Special case of the template operator=, in order to prevent the compiler
132       * from generating a default operator= (issue hit with g++ 4.1)
133       */
134     Derived& operator=(const ArrayBase& other)
135     {
136       return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
137     }
138
139     Derived& operator+=(const Scalar& scalar)
140     { return *this = derived() + scalar; }
141     Derived& operator-=(const Scalar& scalar)
142     { return *this = derived() - scalar; }
143
144     template<typename OtherDerived>
145     Derived& operator+=(const ArrayBase<OtherDerived>& other);
146     template<typename OtherDerived>
147     Derived& operator-=(const ArrayBase<OtherDerived>& other);
148
149     template<typename OtherDerived>
150     Derived& operator*=(const ArrayBase<OtherDerived>& other);
151
152     template<typename OtherDerived>
153     Derived& operator/=(const ArrayBase<OtherDerived>& other);
154
155   public:
156     ArrayBase<Derived>& array() { return *this; }
157     const ArrayBase<Derived>& array() const { return *this; }
158
159     /** \returns an \link MatrixBase Matrix \endlink expression of this array
160       * \sa MatrixBase::array() */
161     MatrixWrapper<Derived> matrix() { return derived(); }
162     const MatrixWrapper<Derived> matrix() const { return derived(); }
163
164 //     template<typename Dest>
165 //     inline void evalTo(Dest& dst) const { dst = matrix(); }
166
167   protected:
168     ArrayBase() : Base() {}
169
170   private:
171     explicit ArrayBase(Index);
172     ArrayBase(Index,Index);
173     template<typename OtherDerived> explicit ArrayBase(const ArrayBase<OtherDerived>&);
174   protected:
175     // mixing arrays and matrices is not legal
176     template<typename OtherDerived> Derived& operator+=(const MatrixBase<OtherDerived>& )
177     {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);}
178     // mixing arrays and matrices is not legal
179     template<typename OtherDerived> Derived& operator-=(const MatrixBase<OtherDerived>& )
180     {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);}
181 };
182
183 /** replaces \c *this by \c *this - \a other.
184   *
185   * \returns a reference to \c *this
186   */
187 template<typename Derived>
188 template<typename OtherDerived>
189 EIGEN_STRONG_INLINE Derived &
190 ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
191 {
192   SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
193   tmp = other.derived();
194   return derived();
195 }
196
197 /** replaces \c *this by \c *this + \a other.
198   *
199   * \returns a reference to \c *this
200   */
201 template<typename Derived>
202 template<typename OtherDerived>
203 EIGEN_STRONG_INLINE Derived &
204 ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
205 {
206   SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
207   tmp = other.derived();
208   return derived();
209 }
210
211 /** replaces \c *this by \c *this * \a other coefficient wise.
212   *
213   * \returns a reference to \c *this
214   */
215 template<typename Derived>
216 template<typename OtherDerived>
217 EIGEN_STRONG_INLINE Derived &
218 ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
219 {
220   SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, OtherDerived> tmp(derived());
221   tmp = other.derived();
222   return derived();
223 }
224
225 /** replaces \c *this by \c *this / \a other coefficient wise.
226   *
227   * \returns a reference to \c *this
228   */
229 template<typename Derived>
230 template<typename OtherDerived>
231 EIGEN_STRONG_INLINE Derived &
232 ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
233 {
234   SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, OtherDerived> tmp(derived());
235   tmp = other.derived();
236   return derived();
237 }
238
239 #endif // EIGEN_ARRAYBASE_H