• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_ARRAY_H
11 #define EIGEN_ARRAY_H
12 
13 namespace Eigen {
14 
15 /** \class Array
16   * \ingroup Core_Module
17   *
18   * \brief General-purpose arrays with easy API for coefficient-wise operations
19   *
20   * The %Array class is very similar to the Matrix class. It provides
21   * general-purpose one- and two-dimensional arrays. The difference between the
22   * %Array and the %Matrix class is primarily in the API: the API for the
23   * %Array class provides easy access to coefficient-wise operations, while the
24   * API for the %Matrix class provides easy access to linear-algebra
25   * operations.
26   *
27   * This class can be extended with the help of the plugin mechanism described on the page
28   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.
29   *
30   * \sa \ref TutorialArrayClass, \ref TopicClassHierarchy
31   */
32 namespace internal {
33 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
34 struct traits<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > : traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
35 {
36   typedef ArrayXpr XprKind;
37   typedef ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > XprBase;
38 };
39 }
40 
41 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
42 class Array
43   : public PlainObjectBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
44 {
45   public:
46 
47     typedef PlainObjectBase<Array> Base;
48     EIGEN_DENSE_PUBLIC_INTERFACE(Array)
49 
50     enum { Options = _Options };
51     typedef typename Base::PlainObject PlainObject;
52 
53   protected:
54     template <typename Derived, typename OtherDerived, bool IsVector>
55     friend struct internal::conservative_resize_like_impl;
56 
57     using Base::m_storage;
58 
59   public:
60 
61     using Base::base;
62     using Base::coeff;
63     using Base::coeffRef;
64 
65     /**
66       * The usage of
67       *   using Base::operator=;
68       * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped
69       * the usage of 'using'. This should be done only for operator=.
70       */
71     template<typename OtherDerived>
72     EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived> &other)
73     {
74       return Base::operator=(other);
75     }
76 
77     /** Copies the value of the expression \a other into \c *this with automatic resizing.
78       *
79       * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
80       * it will be initialized.
81       *
82       * Note that copying a row-vector into a vector (and conversely) is allowed.
83       * The resizing, if any, is then done in the appropriate way so that row-vectors
84       * remain row-vectors and vectors remain vectors.
85       */
86     template<typename OtherDerived>
87     EIGEN_STRONG_INLINE Array& operator=(const ArrayBase<OtherDerived>& other)
88     {
89       return Base::_set(other);
90     }
91 
92     /** This is a special case of the templated operator=. Its purpose is to
93       * prevent a default operator= from hiding the templated operator=.
94       */
95     EIGEN_STRONG_INLINE Array& operator=(const Array& other)
96     {
97       return Base::_set(other);
98     }
99 
100     /** Default constructor.
101       *
102       * For fixed-size matrices, does nothing.
103       *
104       * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
105       * is called a null matrix. This constructor is the unique way to create null matrices: resizing
106       * a matrix to 0 is not supported.
107       *
108       * \sa resize(Index,Index)
109       */
110     EIGEN_STRONG_INLINE Array() : Base()
111     {
112       Base::_check_template_params();
113       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
114     }
115 
116 #ifndef EIGEN_PARSED_BY_DOXYGEN
117     // FIXME is it still needed ??
118     /** \internal */
119     Array(internal::constructor_without_unaligned_array_assert)
120       : Base(internal::constructor_without_unaligned_array_assert())
121     {
122       Base::_check_template_params();
123       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
124     }
125 #endif
126 
127     /** Constructs a vector or row-vector with given dimension. \only_for_vectors
128       *
129       * Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
130       * it is redundant to pass the dimension here, so it makes more sense to use the default
131       * constructor Matrix() instead.
132       */
133     EIGEN_STRONG_INLINE explicit Array(Index dim)
134       : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
135     {
136       Base::_check_template_params();
137       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array)
138       eigen_assert(dim >= 0);
139       eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
140       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
141     }
142 
143     #ifndef EIGEN_PARSED_BY_DOXYGEN
144     template<typename T0, typename T1>
145     EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1)
146     {
147       Base::_check_template_params();
148       this->template _init2<T0,T1>(val0, val1);
149     }
150     #else
151     /** constructs an uninitialized matrix with \a rows rows and \a cols columns.
152       *
153       * This is useful for dynamic-size matrices. For fixed-size matrices,
154       * it is redundant to pass these parameters, so one should use the default constructor
155       * Matrix() instead. */
156     Array(Index rows, Index cols);
157     /** constructs an initialized 2D vector with given coefficients */
158     Array(const Scalar& val0, const Scalar& val1);
159     #endif
160 
161     /** constructs an initialized 3D vector with given coefficients */
162     EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
163     {
164       Base::_check_template_params();
165       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3)
166       m_storage.data()[0] = val0;
167       m_storage.data()[1] = val1;
168       m_storage.data()[2] = val2;
169     }
170     /** constructs an initialized 4D vector with given coefficients */
171     EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
172     {
173       Base::_check_template_params();
174       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4)
175       m_storage.data()[0] = val0;
176       m_storage.data()[1] = val1;
177       m_storage.data()[2] = val2;
178       m_storage.data()[3] = val3;
179     }
180 
181     explicit Array(const Scalar *data);
182 
183     /** Constructor copying the value of the expression \a other */
184     template<typename OtherDerived>
185     EIGEN_STRONG_INLINE Array(const ArrayBase<OtherDerived>& other)
186              : Base(other.rows() * other.cols(), other.rows(), other.cols())
187     {
188       Base::_check_template_params();
189       Base::_set_noalias(other);
190     }
191     /** Copy constructor */
192     EIGEN_STRONG_INLINE Array(const Array& other)
193             : Base(other.rows() * other.cols(), other.rows(), other.cols())
194     {
195       Base::_check_template_params();
196       Base::_set_noalias(other);
197     }
198     /** Copy constructor with in-place evaluation */
199     template<typename OtherDerived>
200     EIGEN_STRONG_INLINE Array(const ReturnByValue<OtherDerived>& other)
201     {
202       Base::_check_template_params();
203       Base::resize(other.rows(), other.cols());
204       other.evalTo(*this);
205     }
206 
207     /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
208     template<typename OtherDerived>
209     EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other)
210       : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
211     {
212       Base::_check_template_params();
213       Base::_resize_to_match(other);
214       *this = other;
215     }
216 
217     /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
218       * data pointers.
219       */
220     template<typename OtherDerived>
221     void swap(ArrayBase<OtherDerived> const & other)
222     { this->_swap(other.derived()); }
223 
224     inline Index innerStride() const { return 1; }
225     inline Index outerStride() const { return this->innerSize(); }
226 
227     #ifdef EIGEN_ARRAY_PLUGIN
228     #include EIGEN_ARRAY_PLUGIN
229     #endif
230 
231   private:
232 
233     template<typename MatrixType, typename OtherDerived, bool SwapPointers>
234     friend struct internal::matrix_swap_impl;
235 };
236 
237 /** \defgroup arraytypedefs Global array typedefs
238   * \ingroup Core_Module
239   *
240   * Eigen defines several typedef shortcuts for most common 1D and 2D array types.
241   *
242   * The general patterns are the following:
243   *
244   * \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size,
245   * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd
246   * for complex double.
247   *
248   * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats.
249   *
250   * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is
251   * a fixed-size 1D array of 4 complex floats.
252   *
253   * \sa class Array
254   */
255 
256 #define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)   \
257 /** \ingroup arraytypedefs */                                    \
258 typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix;  \
259 /** \ingroup arraytypedefs */                                    \
260 typedef Array<Type, Size, 1>    Array##SizeSuffix##TypeSuffix;
261 
262 #define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size)         \
263 /** \ingroup arraytypedefs */                                    \
264 typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix;  \
265 /** \ingroup arraytypedefs */                                    \
266 typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix;
267 
268 #define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
269 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \
270 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \
271 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \
272 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \
273 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \
274 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \
275 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4)
276 
277 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int,                  i)
278 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float,                f)
279 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double,               d)
280 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>,  cf)
281 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
282 
283 #undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES
284 #undef EIGEN_MAKE_ARRAY_TYPEDEFS
285 
286 #undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE
287 
288 #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
289 using Eigen::Matrix##SizeSuffix##TypeSuffix; \
290 using Eigen::Vector##SizeSuffix##TypeSuffix; \
291 using Eigen::RowVector##SizeSuffix##TypeSuffix;
292 
293 #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \
294 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
295 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
296 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
297 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \
298 
299 #define EIGEN_USING_ARRAY_TYPEDEFS \
300 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \
301 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \
302 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \
303 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \
304 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd)
305 
306 } // end namespace Eigen
307 
308 #endif // EIGEN_ARRAY_H
309