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 if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) 157 Base::_set_noalias(other); 158 } 159 EIGEN_DEVICE_FUNC 160 Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value) 161 { 162 other.swap(*this); 163 return *this; 164 } 165 #endif 166 167 #ifndef EIGEN_PARSED_BY_DOXYGEN 168 template<typename T> 169 EIGEN_DEVICE_FUNC 170 EIGEN_STRONG_INLINE explicit Array(const T& x) 171 { 172 Base::_check_template_params(); 173 Base::template _init1<T>(x); 174 } 175 176 template<typename T0, typename T1> 177 EIGEN_DEVICE_FUNC 178 EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1) 179 { 180 Base::_check_template_params(); 181 this->template _init2<T0,T1>(val0, val1); 182 } 183 #else 184 /** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */ 185 EIGEN_DEVICE_FUNC explicit Array(const Scalar *data); 186 /** Constructs a vector or row-vector with given dimension. \only_for_vectors 187 * 188 * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, 189 * it is redundant to pass the dimension here, so it makes more sense to use the default 190 * constructor Array() instead. 191 */ 192 EIGEN_DEVICE_FUNC 193 EIGEN_STRONG_INLINE explicit Array(Index dim); 194 /** constructs an initialized 1x1 Array with the given coefficient */ 195 Array(const Scalar& value); 196 /** constructs an uninitialized array with \a rows rows and \a cols columns. 197 * 198 * This is useful for dynamic-size arrays. For fixed-size arrays, 199 * it is redundant to pass these parameters, so one should use the default constructor 200 * Array() instead. */ 201 Array(Index rows, Index cols); 202 /** constructs an initialized 2D vector with given coefficients */ 203 Array(const Scalar& val0, const Scalar& val1); 204 #endif 205 206 /** constructs an initialized 3D vector with given coefficients */ 207 EIGEN_DEVICE_FUNC 208 EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) 209 { 210 Base::_check_template_params(); 211 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3) 212 m_storage.data()[0] = val0; 213 m_storage.data()[1] = val1; 214 m_storage.data()[2] = val2; 215 } 216 /** constructs an initialized 4D vector with given coefficients */ 217 EIGEN_DEVICE_FUNC 218 EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3) 219 { 220 Base::_check_template_params(); 221 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4) 222 m_storage.data()[0] = val0; 223 m_storage.data()[1] = val1; 224 m_storage.data()[2] = val2; 225 m_storage.data()[3] = val3; 226 } 227 228 /** Copy constructor */ 229 EIGEN_DEVICE_FUNC 230 EIGEN_STRONG_INLINE Array(const Array& other) 231 : Base(other) 232 { } 233 234 private: 235 struct PrivateType {}; 236 public: 237 238 /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */ 239 template<typename OtherDerived> 240 EIGEN_DEVICE_FUNC 241 EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other, 242 typename internal::enable_if<internal::is_convertible<typename OtherDerived::Scalar,Scalar>::value, 243 PrivateType>::type = PrivateType()) 244 : Base(other.derived()) 245 { } 246 247 EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; } 248 EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); } 249 250 #ifdef EIGEN_ARRAY_PLUGIN 251 #include EIGEN_ARRAY_PLUGIN 252 #endif 253 254 private: 255 256 template<typename MatrixType, typename OtherDerived, bool SwapPointers> 257 friend struct internal::matrix_swap_impl; 258 }; 259 260 /** \defgroup arraytypedefs Global array typedefs 261 * \ingroup Core_Module 262 * 263 * Eigen defines several typedef shortcuts for most common 1D and 2D array types. 264 * 265 * The general patterns are the following: 266 * 267 * \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, 268 * 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 269 * for complex double. 270 * 271 * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats. 272 * 273 * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is 274 * a fixed-size 1D array of 4 complex floats. 275 * 276 * \sa class Array 277 */ 278 279 #define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ 280 /** \ingroup arraytypedefs */ \ 281 typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix; \ 282 /** \ingroup arraytypedefs */ \ 283 typedef Array<Type, Size, 1> Array##SizeSuffix##TypeSuffix; 284 285 #define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ 286 /** \ingroup arraytypedefs */ \ 287 typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix; \ 288 /** \ingroup arraytypedefs */ \ 289 typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix; 290 291 #define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ 292 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \ 293 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \ 294 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \ 295 EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ 296 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ 297 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ 298 EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4) 299 300 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int, i) 301 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float, f) 302 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double, d) 303 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>, cf) 304 EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd) 305 306 #undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES 307 #undef EIGEN_MAKE_ARRAY_TYPEDEFS 308 309 #undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE 310 311 #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ 312 using Eigen::Matrix##SizeSuffix##TypeSuffix; \ 313 using Eigen::Vector##SizeSuffix##TypeSuffix; \ 314 using Eigen::RowVector##SizeSuffix##TypeSuffix; 315 316 #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \ 317 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ 318 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ 319 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ 320 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ 321 322 #define EIGEN_USING_ARRAY_TYPEDEFS \ 323 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \ 324 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \ 325 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ 326 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ 327 EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) 328 329 } // end namespace Eigen 330 331 #endif // EIGEN_ARRAY_H 332