| // This file is part of Eigen, a lightweight C++ template library | |
| // for linear algebra. | |
| // | |
| // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | |
| // | |
| // This Source Code Form is subject to the terms of the Mozilla | |
| // Public License v. 2.0. If a copy of the MPL was not distributed | |
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| // SPDX-License-Identifier: MPL-2.0 | |
| #ifndef EIGEN_ARRAY_H | |
| #define EIGEN_ARRAY_H | |
| // IWYU pragma: private | |
| #include "./InternalHeaderCheck.h" | |
| namespace Eigen { | |
| namespace internal { | |
| // Preserve Array's scalar-conversion gate for non-dense expressions such as permutations. | |
| template <typename Scalar, typename OtherDerived> | |
| using is_valid_array_conversion = std::conditional_t<std::is_base_of<DenseBase<OtherDerived>, OtherDerived>::value, | |
| is_valid_dense_conversion<Scalar, OtherDerived>, | |
| std::is_convertible<typename OtherDerived::Scalar, Scalar>>; | |
| template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_> | |
| struct traits<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> | |
| : traits<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> { | |
| using XprKind = ArrayXpr; | |
| using XprBase = ArrayBase<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>>; | |
| }; | |
| } // namespace internal | |
| /** \class Array | |
| * \ingroup Core_Module | |
| * | |
| * \brief General-purpose arrays with easy API for coefficient-wise operations | |
| * | |
| * The %Array class is very similar to the Matrix class. It provides | |
| * general-purpose one- and two-dimensional arrays. The difference between the | |
| * %Array and the %Matrix class is primarily in the API: the API for the | |
| * %Array class provides easy access to coefficient-wise operations, while the | |
| * API for the %Matrix class provides easy access to linear-algebra | |
| * operations. | |
| * | |
| * See documentation of class Matrix for detailed information on the template parameters | |
| * storage layout. | |
| * | |
| * This class can be extended with the help of the plugin mechanism described on the page | |
| * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN. | |
| * | |
| * \sa \blank \ref TutorialArrayClass, \ref TopicClassHierarchy | |
| */ | |
| template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_> | |
| class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> { | |
| public: | |
| using Base = PlainObjectBase<Array>; | |
| EIGEN_DENSE_PUBLIC_INTERFACE(Array) | |
| enum { Options = Options_ }; | |
| using PlainObject = typename Base::PlainObject; | |
| protected: | |
| template <typename Derived, typename OtherDerived, bool IsVector> | |
| friend struct internal::conservative_resize_like_impl; | |
| using Base::m_storage; | |
| public: | |
| using Base::base; | |
| using Base::coeff; | |
| using Base::coeffRef; | |
| /** Copies the value of the expression \a other into \c *this with automatic resizing. | |
| * | |
| * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), | |
| * it will be initialized. | |
| * | |
| * Note that copying a row-vector into a vector (and conversely) is allowed. | |
| * The resizing, if any, is then done in the appropriate way so that row-vectors | |
| * remain row-vectors and vectors remain vectors. | |
| */ | |
| template <typename OtherDerived> | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const DenseBase<OtherDerived>& other) { | |
| return Base::_set(other); | |
| } | |
| /** Set all the entries to \a value. | |
| * \sa DenseBase::setConstant(), DenseBase::fill() | |
| */ | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const Scalar& value) { | |
| Base::setConstant(value); | |
| return *this; | |
| } | |
| /** | |
| * \brief Assigns arrays to each other. | |
| * | |
| * \note This is a special case of the templated operator=. Its purpose is | |
| * to prevent a default operator= from hiding the templated operator=. | |
| * | |
| * \callgraph | |
| */ | |
| EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Array& operator=(const Array& other) { return Base::_set(other); } | |
| /** Default constructor. | |
| * | |
| * For fixed-size matrices, does nothing. | |
| * | |
| * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix | |
| * is called a null matrix. An existing matrix can also be turned into a null matrix by resizing it to 0. | |
| * | |
| * \sa resize(Index,Index) | |
| */ | |
| #ifdef EIGEN_INITIALIZE_COEFFS | |
| EIGEN_DEVICE_FUNC constexpr Array() : Base() { EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } | |
| #else | |
| EIGEN_DEVICE_FUNC constexpr Array() = default; | |
| #endif | |
| /** \brief Move constructor */ | |
| EIGEN_DEVICE_FUNC constexpr Array(Array&&) = default; | |
| EIGEN_DEVICE_FUNC constexpr Array& operator=(Array&& other) noexcept(std::is_nothrow_move_assignable<Scalar>::value) { | |
| this->m_storage = std::move(other.m_storage); | |
| return *this; | |
| } | |
| /** \brief Construct a row or column vector with fixed size from an arbitrary number of coefficients. | |
| * | |
| * \only_for_vectors | |
| * | |
| * This constructor is for 1D array or vectors with more than 4 coefficients. | |
| * | |
| * \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this | |
| * constructor must match the fixed number of rows (resp. columns) of \c *this. | |
| * | |
| * | |
| * Example: \include Array_variadic_ctor.cpp | |
| * Output: \verbinclude Array_variadic_ctor.out | |
| * | |
| * \sa Array(const std::initializer_list<std::initializer_list<Scalar>>&) | |
| * \sa Array(const Scalar&), Array(const Scalar&,const Scalar&) | |
| */ | |
| template <typename... ArgTypes> | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, | |
| const ArgTypes&... args) | |
| : Base(a0, a1, a2, a3, args...) {} | |
| /** \brief Constructs an array and initializes it from the coefficients given as initializer-lists grouped by row. | |
| * | |
| * In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients: | |
| * | |
| * Example: \include Array_initializer_list_23.cpp | |
| * Output: \verbinclude Array_initializer_list_23.out | |
| * | |
| * Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is | |
| * triggered. | |
| * | |
| * In the case of a compile-time column 1D array, implicit transposition from a single row is allowed. | |
| * Therefore <code> Array<int,Dynamic,1>{{1,2,3,4,5}}</code> is legal and the more verbose syntax | |
| * <code>Array<int,Dynamic,1>{{1},{2},{3},{4},{5}}</code> can be avoided: | |
| * | |
| * Example: \include Array_initializer_list_vector.cpp | |
| * Output: \verbinclude Array_initializer_list_vector.out | |
| * | |
| * In the case of fixed-sized arrays, the initializer list sizes must exactly match the array sizes, | |
| * and implicit transposition is allowed for compile-time 1D arrays only. | |
| * | |
| * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) | |
| */ | |
| EIGEN_DEVICE_FUNC constexpr Array(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {} | |
| #ifndef EIGEN_PARSED_BY_DOXYGEN | |
| template <typename T> | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit Array(const T& x) { | |
| Base::template _init1<T>(x); | |
| } | |
| template <typename T0, typename T1> | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1) { | |
| this->template _init2<T0, T1>(val0, val1); | |
| } | |
| #else | |
| /** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */ | |
| EIGEN_DEVICE_FUNC explicit Array(const Scalar* data); | |
| /** Constructs a vector or row-vector with given dimension. \only_for_vectors | |
| * | |
| * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, | |
| * it is redundant to pass the dimension here, so it makes more sense to use the default | |
| * constructor Array() instead. | |
| */ | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit Array(Index dim); | |
| /** constructs an initialized 1x1 Array with the given coefficient | |
| * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */ | |
| Array(const Scalar& value); | |
| /** constructs an uninitialized array with \a rows rows and \a cols columns. | |
| * | |
| * This is useful for dynamic-size arrays. For fixed-size arrays, | |
| * it is redundant to pass these parameters, so one should use the default constructor | |
| * Array() instead. */ | |
| Array(Index rows, Index cols); | |
| /** constructs an initialized 2D vector with given coefficients | |
| * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) */ | |
| Array(const Scalar& val0, const Scalar& val1); | |
| #endif // end EIGEN_PARSED_BY_DOXYGEN | |
| /** constructs an initialized 3D vector with given coefficients | |
| * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) | |
| */ | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) { | |
| EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3) | |
| m_storage.data()[0] = val0; | |
| m_storage.data()[1] = val1; | |
| m_storage.data()[2] = val2; | |
| } | |
| /** constructs an initialized 4D vector with given coefficients | |
| * \sa Array(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args) | |
| */ | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, | |
| const Scalar& val3) { | |
| EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4) | |
| m_storage.data()[0] = val0; | |
| m_storage.data()[1] = val1; | |
| m_storage.data()[2] = val2; | |
| m_storage.data()[3] = val3; | |
| } | |
| /** Copy constructor */ | |
| EIGEN_DEVICE_FUNC constexpr Array(const Array&) = default; | |
| private: | |
| struct PrivateType {}; | |
| public: | |
| /** Constructs an array from an expression with compatible scalar types. | |
| * Use \c .cast<NewScalar>() to convert between scalar types. | |
| * \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) | |
| */ | |
| template <typename OtherDerived, | |
| std::enable_if_t<internal::is_valid_array_conversion<Scalar, OtherDerived>::value, int> = 0> | |
| EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived>& other) : Base(other.derived()) {} | |
| template <typename OtherDerived> | |
| EIGEN_DEPRECATED_WITH_REASON("Omit the implementation-only second argument.") | |
| EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Array( | |
| const EigenBase<OtherDerived>& other, | |
| std::enable_if_t<internal::is_valid_array_conversion<Scalar, OtherDerived>::value, PrivateType>) | |
| : Array(other) {} | |
| EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return 1; } | |
| EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return this->innerSize(); } | |
| #ifdef EIGEN_ARRAY_PLUGIN | |
| #include EIGEN_ARRAY_PLUGIN | |
| #endif | |
| template <typename OtherDerived> | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived>& other) { | |
| return Base::operator=(other); | |
| } | |
| template <typename OtherDerived> | |
| EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const ReturnByValue<OtherDerived>& func) { | |
| return Base::operator=(func); | |
| } | |
| private: | |
| template <typename MatrixType, typename OtherDerived, bool SwapPointers> | |
| friend struct internal::matrix_swap_impl; | |
| }; | |
| /** \defgroup arraytypedefs Global array typedefs | |
| * \ingroup Core_Module | |
| * | |
| * %Eigen defines several typedef shortcuts for most common 1D and 2D array types. | |
| * | |
| * The general patterns are the following: | |
| * | |
| * \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, 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 for complex double. | |
| * | |
| * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of | |
| * floats. | |
| * | |
| * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is | |
| * a fixed-size 1D array of 4 complex floats. | |
| * | |
| * Template alias are also defined for common sizes. | |
| * They follow the same pattern as above except that the scalar type suffix is replaced by a | |
| * template parameter, i.e.: | |
| * - `ArrayRowsCols<Type>` where `Rows` and `Cols` can be \c 2,\c 3,\c 4, or \c X for fixed or dynamic size. | |
| * - `ArraySize<Type>` where `Size` can be \c 2,\c 3,\c 4 or \c X for fixed or dynamic size 1D arrays. | |
| * | |
| * \sa class Array | |
| */ | |
| #define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ | |
| /** \ingroup arraytypedefs */ \ | |
| typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix; \ | |
| /** \ingroup arraytypedefs */ \ | |
| typedef Array<Type, Size, 1> Array##SizeSuffix##TypeSuffix; | |
| #define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ | |
| /** \ingroup arraytypedefs */ \ | |
| typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix; \ | |
| /** \ingroup arraytypedefs */ \ | |
| typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix; | |
| #define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ | |
| EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \ | |
| EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \ | |
| EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \ | |
| EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ | |
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ | |
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ | |
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4) | |
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int, i) | |
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float, f) | |
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double, d) | |
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>, cf) | |
| EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd) | |
| #undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES | |
| #undef EIGEN_MAKE_ARRAY_TYPEDEFS | |
| #undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS | |
| #define EIGEN_MAKE_ARRAY_TYPEDEFS(Size, SizeSuffix) \ | |
| /** \ingroup arraytypedefs */ \ | |
| template <typename Type> \ | |
| using Array##SizeSuffix##SizeSuffix = Array<Type, Size, Size>; \ | |
| /** \ingroup arraytypedefs */ \ | |
| template <typename Type> \ | |
| using Array##SizeSuffix = Array<Type, Size, 1>; | |
| #define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Size) \ | |
| /** \ingroup arraytypedefs */ \ | |
| template <typename Type> \ | |
| using Array##Size##X = Array<Type, Size, Dynamic>; \ | |
| /** \ingroup arraytypedefs */ \ | |
| template <typename Type> \ | |
| using Array##X##Size = Array<Type, Dynamic, Size>; | |
| EIGEN_MAKE_ARRAY_TYPEDEFS(2, 2) | |
| EIGEN_MAKE_ARRAY_TYPEDEFS(3, 3) | |
| EIGEN_MAKE_ARRAY_TYPEDEFS(4, 4) | |
| EIGEN_MAKE_ARRAY_TYPEDEFS(Dynamic, X) | |
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(2) | |
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(3) | |
| EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(4) | |
| #undef EIGEN_MAKE_ARRAY_TYPEDEFS | |
| #undef EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS | |
| #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ | |
| using Eigen::Matrix##SizeSuffix##TypeSuffix; \ | |
| using Eigen::Vector##SizeSuffix##TypeSuffix; \ | |
| using Eigen::RowVector##SizeSuffix##TypeSuffix; | |
| #define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) | |
| #define EIGEN_USING_ARRAY_TYPEDEFS \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ | |
| EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) | |
| } // end namespace Eigen | |
| #endif // EIGEN_ARRAY_H |