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