1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2009 Gael Guennebaud <[email protected]> 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 Base::operator=(std::move(other)); 161 return *this; 162 } 163 #endif 164 165 #if EIGEN_HAS_CXX11 166 /** \copydoc PlainObjectBase(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) 167 * 168 * Example: \include Array_variadic_ctor_cxx11.cpp 169 * Output: \verbinclude Array_variadic_ctor_cxx11.out 170 * 171 * \sa Array(const std::initializer_list<std::initializer_list<Scalar>>&) 172 * \sa Array(const Scalar&), Array(const Scalar&,const Scalar&) 173 */ 174 template <typename... ArgTypes> 175 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 176 Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) 177 : Base(a0, a1, a2, a3, args...) {} 178 179 /** \brief Constructs an array and initializes it from the coefficients given as initializer-lists grouped by row. \cpp11 180 * 181 * In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients: 182 * 183 * Example: \include Array_initializer_list_23_cxx11.cpp 184 * Output: \verbinclude Array_initializer_list_23_cxx11.out 185 * 186 * Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is triggered. 187 * 188 * In the case of a compile-time column 1D array, implicit transposition from a single row is allowed. 189 * Therefore <code> Array<int,Dynamic,1>{{1,2,3,4,5}}</code> is legal and the more verbose syntax 190 * <code>Array<int,Dynamic,1>{{1},{2},{3},{4},{5}}</code> can be avoided: 191 * 192 * Example: \include Array_initializer_list_vector_cxx11.cpp 193 * Output: \verbinclude Array_initializer_list_vector_cxx11.out 194 * 195 * In the case of fixed-sized arrays, the initializer list sizes must exactly match the array sizes, 196 * and implicit transposition is allowed for compile-time 1D arrays only. 197 * 198 * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) 199 */ 200 EIGEN_DEVICE_FUNC 201 EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {} 202 #endif // end EIGEN_HAS_CXX11 203 204 #ifndef EIGEN_PARSED_BY_DOXYGEN 205 template<typename T> 206 EIGEN_DEVICE_FUNC 207 EIGEN_STRONG_INLINE explicit Array(const T& x) 208 { 209 Base::_check_template_params(); 210 Base::template _init1<T>(x); 211 } 212 213 template<typename T0, typename T1> 214 EIGEN_DEVICE_FUNC 215 EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1) 216 { 217 Base::_check_template_params(); 218 this->template _init2<T0,T1>(val0, val1); 219 } 220 221 #else 222 /** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */ 223 EIGEN_DEVICE_FUNC explicit Array(const Scalar *data); 224 /** Constructs a vector or row-vector with given dimension. \only_for_vectors 225 * 226 * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, 227 * it is redundant to pass the dimension here, so it makes more sense to use the default 228 * constructor Array() instead. 229 */ 230 EIGEN_DEVICE_FUNC 231 EIGEN_STRONG_INLINE explicit Array(Index dim); 232 /** constructs an initialized 1x1 Array with the given coefficient 233 * \sa const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args */ 234 Array(const Scalar& value); 235 /** constructs an uninitialized array with \a rows rows and \a cols columns. 236 * 237 * This is useful for dynamic-size arrays. For fixed-size arrays, 238 * it is redundant to pass these parameters, so one should use the default constructor 239 * Array() instead. */ 240 Array(Index rows, Index cols); 241 /** constructs an initialized 2D vector with given coefficients 242 * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */ 243 Array(const Scalar& val0, const Scalar& val1); 244 #endif // end EIGEN_PARSED_BY_DOXYGEN 245 246 /** constructs an initialized 3D vector with given coefficients 247 * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) 248 */ 249 EIGEN_DEVICE_FUNC 250 EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) 251 { 252 Base::_check_template_params(); 253 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3) 254 m_storage.data()[0] = val0; 255 m_storage.data()[1] = val1; 256 m_storage.data()[2] = val2; 257 } 258 /** constructs an initialized 4D vector with given coefficients 259 * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) 260 */ 261 EIGEN_DEVICE_FUNC 262 EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3) 263 { 264 Base::_check_template_params(); 265 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4) 266 m_storage.data()[0] = val0; 267 m_storage.data()[1] = val1; 268 m_storage.data()[2] = val2; 269 m_storage.data()[3] = val3; 270 } 271 272 /** Copy constructor */ 273 EIGEN_DEVICE_FUNC 274 EIGEN_STRONG_INLINE Array(const Array& other) 275 : Base(other) 276 { } 277 278 private: 279 struct PrivateType {}; 280 public: 281 282 /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */ 283 template<typename OtherDerived> 284 EIGEN_DEVICE_FUNC 285 EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other, 286 typename internal::enable_if<internal::is_convertible<typename OtherDerived::Scalar,Scalar>::value, 287 PrivateType>::type = PrivateType()) 288 : Base(other.derived()) 289 { } 290 291 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 292 inline Index innerStride() const EIGEN_NOEXCEPT{ return 1; } 293 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR 294 inline Index outerStride() const EIGEN_NOEXCEPT { return this->innerSize(); } 295 296 #ifdef EIGEN_ARRAY_PLUGIN 297 #include EIGEN_ARRAY_PLUGIN 298 #endif 299 300 private: 301 302 template<typename MatrixType, typename OtherDerived, bool SwapPointers> 303 friend struct internal::matrix_swap_impl; 304 }; 305 306 /** \defgroup arraytypedefs Global array typedefs 307 * \ingroup Core_Module 308 * 309 * %Eigen defines several typedef shortcuts for most common 1D and 2D array types. 310 * 311 * The general patterns are the following: 312 * 313 * \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, 314 * 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 315 * for complex double. 316 * 317 * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats. 318 * 319 * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is 320 * a fixed-size 1D array of 4 complex floats. 321 * 322 * With \cpp11, template alias are also defined for common sizes. 323 * They follow the same pattern as above except that the scalar type suffix is replaced by a 324 * template parameter, i.e.: 325 * - `ArrayRowsCols<Type>` where `Rows` and `Cols` can be \c 2,\c 3,\c 4, or \c X for fixed or dynamic size. 326 * - `ArraySize<Type>` where `Size` can be \c 2,\c 3,\c 4 or \c X for fixed or dynamic size 1D arrays. 327 * 328 * \sa class Array 329 */ 330 331 #define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ 332 /** \ingroup arraytypedefs */ \ 333 typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix; \ 334 /** \ingroup arraytypedefs */ \ 335 typedef Array<Type, Size, 1> Array##SizeSuffix##TypeSuffix; 336 337 #define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ 338 /** \ingroup arraytypedefs */ \ 339 typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix; \ 340 /** \ingroup arraytypedefs */ \ 341 typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix; 342 343 #define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ 344 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \ 345 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \ 346 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \ 347 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ 348 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ 349 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ 350 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4) 351 352 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int, i) 353 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float, f) 354 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double, d) 355 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>, cf) 356 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd) 357 358 #undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES 359 #undef EIGEN_MAKE_ARRAY_TYPEDEFS 360 #undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS 361 362 #if EIGEN_HAS_CXX11 363 364 #define EIGEN_MAKE_ARRAY_TYPEDEFS(Size, SizeSuffix) \ 365 /** \ingroup arraytypedefs */ \ 366 /** \brief \cpp11 */ \ 367 template <typename Type> \ 368 using Array##SizeSuffix##SizeSuffix = Array<Type, Size, Size>; \ 369 /** \ingroup arraytypedefs */ \ 370 /** \brief \cpp11 */ \ 371 template <typename Type> \ 372 using Array##SizeSuffix = Array<Type, Size, 1>; 373 374 #define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Size) \ 375 /** \ingroup arraytypedefs */ \ 376 /** \brief \cpp11 */ \ 377 template <typename Type> \ 378 using Array##Size##X = Array<Type, Size, Dynamic>; \ 379 /** \ingroup arraytypedefs */ \ 380 /** \brief \cpp11 */ \ 381 template <typename Type> \ 382 using Array##X##Size = Array<Type, Dynamic, Size>; 383 384 EIGEN_MAKE_ARRAY_TYPEDEFS(2, 2) 385 EIGEN_MAKE_ARRAY_TYPEDEFS(3, 3) 386 EIGEN_MAKE_ARRAY_TYPEDEFS(4, 4) 387 EIGEN_MAKE_ARRAY_TYPEDEFS(Dynamic, X) 388 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(2) 389 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(3) 390 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(4) 391 392 #undef EIGEN_MAKE_ARRAY_TYPEDEFS 393 #undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS 394 395 #endif // EIGEN_HAS_CXX11 396 397 #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ 398 using Eigen::Matrix##SizeSuffix##TypeSuffix; \ 399 using Eigen::Vector##SizeSuffix##TypeSuffix; \ 400 using Eigen::RowVector##SizeSuffix##TypeSuffix; 401 402 #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \ 403 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ 404 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ 405 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ 406 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ 407 408 #define EIGEN_USING_ARRAY_TYPEDEFS \ 409 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \ 410 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \ 411 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ 412 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ 413 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) 414 415 } // end namespace Eigen 416 417 #endif // EIGEN_ARRAY_H 418