PR 572: Add initializer list constructors to Matrix and Array (include unit tests and doc)

- {1,2,3,4,5,...} for fixed-size vectors only
- {{1,2,3},{4,5,6}} for the general cases
- {{1,2,3,4,5,....}} is allowed for both row and column-vector
This commit is contained in:
David Tellenbach 2019-01-21 16:25:57 +01:00
parent 543529da6a
commit db152b9ee6
14 changed files with 622 additions and 3 deletions

View File

@ -178,6 +178,20 @@ class Array
Base::_check_template_params(); Base::_check_template_params();
this->template _init2<T0,T1>(val0, val1); this->template _init2<T0,T1>(val0, val1);
} }
#if EIGEN_HAS_CXX11
template<typename T>
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Array(const std::initializer_list<T>& list,
typename internal::enable_if<internal::is_same<T, Scalar>::value, T>::type* = 0,
typename internal::enable_if<RowsAtCompileTime != Dynamic
&& ColsAtCompileTime != Dynamic
&& IsVectorAtCompileTime == 1, T>::type* = 0) : Base(list) {}
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar> >& list) : Base(list) {}
#endif // end EIGEN_HAS_CXX11
#else #else
/** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */ /** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
EIGEN_DEVICE_FUNC explicit Array(const Scalar *data); EIGEN_DEVICE_FUNC explicit Array(const Scalar *data);
@ -199,7 +213,39 @@ class Array
Array(Index rows, Index cols); Array(Index rows, Index cols);
/** constructs an initialized 2D vector with given coefficients */ /** constructs an initialized 2D vector with given coefficients */
Array(const Scalar& val0, const Scalar& val1); Array(const Scalar& val0, const Scalar& val1);
#endif
/** \copydoc PlainObjectBase::PlainObjectBase(const std::initializer_list<Scalar>& list)
*
* Example: \include Array_initializer_list2_cxx11.cpp
* Output: \verbinclude Array_initializer_list2_cxx11.out
*
* \sa Array::Array(const Scalar& val0, const Scalar& val1)
* \sa Array::Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) */
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Array(const std::initializer_list<Scalar>& list);
/**
* \brief Constructs an array and initializes it by elements given by an initializer list of initializer lists \cpp11
*
* This constructor distinguishes between the construction of arbitrary array and arrays with one fixed dimension,
*
* In the general case, the constructor takes an initializer list, representing the array rows, that contains for
* each row an initializer list, representing a single column, containing scalar values. Each of the inner
* initializer lists must contain the same number of elements.
*
* In the case of array with one fixed dimension, an initializer list containing just one other initializer list
* that contains the array elements can be passed. Therefore \c Array<int,\c Dynamic,\c 1>\c {{1,\c 2,\c 3,\c 4}} is
* legal and the more verbose syntax \c Array<int,\c Dynamic,\c 1>\c {{1},\c {2},\c {3},\c {4}} can be avoided.
*
* \warning In the case of fixed-sized arrays, the initializer list size must be equal to the array \a rows rows
* and \a cols columns.
*
* Example: \include Array_initializer_list_cxx11.cpp
* Output: \verbinclude Array_initializer_list_cxx11.out
*/
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar> >& list);
#endif // end EIGEN_PARSED_BY_DOXYGEN
/** constructs an initialized 3D vector with given coefficients */ /** constructs an initialized 3D vector with given coefficients */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC

View File

@ -301,6 +301,20 @@ class Matrix
Base::_check_template_params(); Base::_check_template_params();
Base::template _init2<T0,T1>(x, y); Base::template _init2<T0,T1>(x, y);
} }
#if EIGEN_HAS_CXX11
template<typename T>
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<T>& list,
typename internal::enable_if<internal::is_same<T, Scalar>::value, T>::type* = 0,
typename internal::enable_if<RowsAtCompileTime != Dynamic
&& ColsAtCompileTime != Dynamic
&& IsVectorAtCompileTime == 1, T>::type* = 0) : Base(list) {}
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}
#endif // end EIGEN_HAS_CXX11
#else #else
/** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */ /** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
@ -338,7 +352,41 @@ class Matrix
/** \brief Constructs an initialized 2D vector with given coefficients */ /** \brief Constructs an initialized 2D vector with given coefficients */
Matrix(const Scalar& x, const Scalar& y); Matrix(const Scalar& x, const Scalar& y);
#endif
/** \copydoc PlainObjectBase::PlainObjectBase(const std::initializer_list<Scalar>& list)
*
* Example: \include Matrix_initializer_list2_cxx11.cpp
* Output: \verbinclude Matrix_initializer_list2_cxx11.out
*
* \sa Matrix::Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
* \sa Matrix::Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) */
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<Scalar>& list);
/**
* \brief Constructs a matrix and initializes it by elements given by an initializer list of initializer lists \cpp11
*
* This constructor distinguishes between the construction of arbitrary matrices and matrices with one fixed dimension,
* i.e., vectors or rowvectors.
*
* In the general case, the constructor takes an initializer list, representing the matrix rows, that contains for
* each row an initializer list, representing a single column, containing scalar values. Each of the inner
* initializer lists must contain the same number of elements.
*
* In the case of matrices with one fixed dimension, an initializer list containing just one other initializer list
* that contains the matrix elements can be passed. Therefore \c VectorXi\c {{1,\c 2,\c 3,\c 4}} is legal and the more
* verbose syntax \c VectorXi\c {{1},\c {2},\c {3},\c {4}} can be avoided.
*
* \warning In the case of fixed-sized matrices, the initializer list size must be equal to the matrix \a rows rows
* and \a cols columns.
*
* Example: \include Matrix_initializer_list_cxx11.cpp
* Output: \verbinclude Matrix_initializer_list_cxx11.out
*/
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list);
#endif // end EIGEN_PARSED_BY_DOXYGEN
/** \brief Constructs an initialized 3D vector with given coefficients */ /** \brief Constructs an initialized 3D vector with given coefficients */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC

View File

@ -526,6 +526,77 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
} }
#ifdef EIGEN_PARSED_BY_DOXYGEN
/**
* \brief Construct a vector with fixed number of rows or a rowvector with fixed number of
* columns by passing an initializer list \cpp11
*
* \only_for_vectors
*
* \warning To construct a vector or rowvector of fixed size, the number of values passed through
* the initializer list must match the the fixed number of rows in the vector case or
* the fixed number of columns in the rowvector case. */
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<Scalar>& list);
/**
* \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer
* lists \cpp11 */
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<std::initializer_list<Scalar>>& list);
#else // EIGEN_PARSED_BY_DOXYGEN
#if EIGEN_HAS_CXX11
template<typename T>
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<T>& list,
typename internal::enable_if<internal::is_same<T, Scalar>::value, T>::type* = 0,
typename internal::enable_if<RowsAtCompileTime != Dynamic
&& ColsAtCompileTime != Dynamic
&& IsVectorAtCompileTime == 1, T>::type* = 0)
: m_storage()
{
_check_template_params();
EIGEN_STATIC_ASSERT_FIXED_SIZE(PlainObjectBase);
resize(list.size());
std::copy(list.begin(), list.end(), m_storage.data());
}
EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<std::initializer_list<Scalar>>& list)
: m_storage()
{
_check_template_params();
size_t list_size = 0;
if (list.begin() != list.end()) {
list_size = list.begin()->size();
}
// This is to allow syntax like VectorXi {{1, 2, 3, 4}}
if (ColsAtCompileTime == 1 && list.size() == 1) {
eigen_assert(list_size == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
resize(list_size, ColsAtCompileTime);
std::copy(list.begin()->begin(), list.begin()->end(), m_storage.data());
} else {
eigen_assert(list.size() == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
eigen_assert(list_size == static_cast<size_t>(ColsAtCompileTime) || ColsAtCompileTime == Dynamic);
resize(list.size(), list_size);
Index row_index = 0;
for (const std::initializer_list<Scalar>& row : list) {
eigen_assert(list_size == row.size());
Index col_index = 0;
for (const Scalar& e : row) {
coeffRef(row_index, col_index) = e;
++col_index;
}
++row_index;
}
}
}
#endif // end EIGEN_HAS_CXX11
#endif // end EIGEN_PARSED_BY_DOXYGEN
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */ /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
template<typename OtherDerived> template<typename OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC

View File

@ -101,13 +101,40 @@ Matrix3f a(3,3);
\endcode \endcode
and is a no-operation. and is a no-operation.
Finally, we also offer some constructors to initialize the coefficients of small fixed-size vectors up to size 4: Additionally, we also offer some constructors to initialize the coefficients of small fixed-size vectors up to size 4:
\code \code
Vector2d a(5.0, 6.0); Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0); Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0); Vector4d c(5.0, 6.0, 7.0, 8.0);
\endcode \endcode
If C++11 is enabled, matrices can be constructed and initialized using initializer lists. In the case of fixed-sized vectors
and rowvectors a simple initializer list can be passed:
\code
Vector2i a {1, 2}; // A vector containing the elements {1, 2}
Matrix<int, 4, 1> b {1, 2, 3, 4}; // A row-vector containing the elements {1, 2, 3, 4}
Matrix<int, 1, 4> c {1, 2, 3, 4}; // A vector containing the elements {1, 2, 3, 4}
\endcode
In the case of fixed or dynamically sized matrices an initializer list containing an initializer list for each row
can be passed. If the matrix is fixed-sized, the number of elements that are passed must match the dimensions.
\code
MatrixXi a {
{1, 2}, // first row
{3, 4} // second row
};
Matrix<double, 2, 3> b {
{2.0, 3.0, 4.0},
{5.0, 6.0, 7.0},
};
\endcode
In the case of vectors and rowvectors, the following shorthand notation can be used:
\code
VectorXd a {{1.5, 2.5, 3.5}}; // A vector with 3 rows
RowVectorXd b {{1.0, 2.0, 3.0, 4.0}}; // A rowvector with 4 columns
\endcode
\section TutorialMatrixCoeffAccessors Coefficient accessors \section TutorialMatrixCoeffAccessors Coefficient accessors
The primary coefficient accessors and mutators in Eigen are the overloaded parenthesis operators. The primary coefficient accessors and mutators in Eigen are the overloaded parenthesis operators.

View File

@ -0,0 +1,3 @@
Array<int, 1, 6> a {1, 2, 3, 4, 5, 6};
Array<int, 3, 1> b {1, 2, 3};
cout << a << "\n\n" << b << endl;

View File

@ -0,0 +1,6 @@
Array<int, 2, 3> a {
{1, 2, 3},
{3, 4, 5}
};
Array<int, Dynamic, 1> v {{1, 2, 3, 4, 5}};
cout << a << "\n\n" << v << endl;

View File

@ -0,0 +1,3 @@
Matrix<int, 1, 6> a {1, 2, 3, 4, 5, 6};
Matrix<int, 3, 1> b {1, 2, 3};
cout << a << "\n\n" << b << endl;

View File

@ -0,0 +1,6 @@
Matrix<int, 2, 3> m {
{1, 2, 3},
{4, 5, 6}
};
VectorXi v {{1, 2}};
cout << m << "\n\n" << v << endl;

View File

@ -63,3 +63,8 @@ ei_add_failtest("bdcsvd_int")
ei_add_failtest("eigensolver_int") ei_add_failtest("eigensolver_int")
ei_add_failtest("eigensolver_cplx") ei_add_failtest("eigensolver_cplx")
if(EIGEN_TEST_CXX11)
ei_add_failtest("initializer_list_1")
ei_add_failtest("initializer_list_2")
endif()

View File

@ -0,0 +1,14 @@
#include "../Eigen/Core"
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
#define ROWS Dynamic
#else
#define ROWS 3
#endif
using namespace Eigen;
int main()
{
Matrix<int, ROWS, 1> {1, 2, 3};
}

View File

@ -0,0 +1,16 @@
#include "../Eigen/Core"
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
#define ROWS Dynamic
#define COLS Dynamic
#else
#define ROWS 3
#define COLS 1
#endif
using namespace Eigen;
int main()
{
Matrix<int, ROWS, COLS> {1, 2, 3};
}

View File

@ -287,6 +287,9 @@ ei_add_test(half_float)
ei_add_test(array_of_string) ei_add_test(array_of_string)
ei_add_test(num_dimensions) ei_add_test(num_dimensions)
ei_add_test(stl_iterators) ei_add_test(stl_iterators)
if(EIGEN_TEST_CXX11)
ei_add_test(initializer_list_construction)
endif()
add_executable(bug1213 bug1213.cpp bug1213_main.cpp) add_executable(bug1213 bug1213.cpp bug1213_main.cpp)

View File

@ -0,0 +1,371 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2019 David Tellenbach <david.tellenbach@tellnotes.org>
//
// 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/.
#define EIGEN_NO_STATIC_ASSERT
#include "main.h"
template<typename Scalar, bool is_integer = NumTraits<Scalar>::IsInteger>
struct TestMethodDispatching {
static void run() {}
};
template<typename Scalar>
struct TestMethodDispatching<Scalar, 1> {
static void run()
{
{
Matrix<Scalar, Dynamic, Dynamic> m {3, 4};
Array<Scalar, Dynamic, Dynamic> a {3, 4};
VERIFY(m.rows() == 3);
VERIFY(m.cols() == 4);
VERIFY(a.rows() == 3);
VERIFY(a.cols() == 4);
}
{
Matrix<Scalar, 1, 2> m {3, 4};
Array<Scalar, 1, 2> a {3, 4};
VERIFY(m(0) == 3);
VERIFY(m(1) == 4);
VERIFY(a(0) == 3);
VERIFY(a(1) == 4);
}
{
Matrix<Scalar, 2, 1> m {3, 4};
Array<Scalar, 2, 1> a {3, 4};
VERIFY(m(0) == 3);
VERIFY(m(1) == 4);
VERIFY(a(0) == 3);
VERIFY(a(1) == 4);
}
}
};
template<typename Scalar> void singleInitializerListVectorConstruction()
{
Scalar raw[4];
for(int k = 0; k < 4; ++k) {
raw[k] = internal::random<Scalar>();
}
{
Matrix<Scalar, 1, 4> m { raw[0], raw[1], raw[2], raw[3] };
Array<Scalar, 1, 4> a { raw[0], raw[1], raw[2], raw[3] };
for(int k = 0; k < 4; ++k) {
VERIFY(m(k) == raw[k]);
}
for(int k = 0; k < 4; ++k) {
VERIFY(a(k) == raw[k]);
}
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 1, 4>(raw[0], raw[1], raw[2], raw[3])));
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 1, 4>({raw[0], raw[1], raw[2], raw[3]})));
VERIFY((a == (Array<Scalar, 1, 4>(raw[0], raw[1], raw[2], raw[3]))).all());
VERIFY((a == (Array<Scalar, 1, 4>({raw[0], raw[1], raw[2], raw[3]}))).all());
}
{
Matrix<Scalar, 4, 1> m { raw[0], raw[1], raw[2], raw[3] };
Array<Scalar, 4, 1> a { raw[0], raw[1], raw[2], raw[3] };
for(int k = 0; k < 4; ++k) {
VERIFY(m(k) == raw[k]);
}
for(int k = 0; k < 4; ++k) {
VERIFY(a(k) == raw[k]);
}
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 4, 1>(raw[0], raw[1], raw[2], raw[3])));
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 4, 1>({raw[0], raw[1], raw[2], raw[3]})));
VERIFY((a == (Array<Scalar, 4, 1>(raw[0], raw[1], raw[2], raw[3]))).all());
VERIFY((a == (Array<Scalar, 4, 1>({raw[0], raw[1], raw[2], raw[3]}))).all());
}
}
template<typename Scalar> void initializerListVectorConstruction()
{
Scalar raw[4];
for(int k = 0; k < 4; ++k) {
raw[k] = internal::random<Scalar>();
}
{
Matrix<Scalar, 4, 1> m { {raw[0]}, {raw[1]},{raw[2]},{raw[3]} };
Array<Scalar, 4, 1> a { {raw[0]}, {raw[1]}, {raw[2]}, {raw[3]} };
for(int k = 0; k < 4; ++k) {
VERIFY(m(k) == raw[k]);
}
for(int k = 0; k < 4; ++k) {
VERIFY(a(k) == raw[k]);
}
VERIFY_IS_EQUAL(m, (Matrix<Scalar,4,1>({ {raw[0]}, {raw[1]}, {raw[2]}, {raw[3]} })));
VERIFY((a == (Array<Scalar,4,1>({ {raw[0]}, {raw[1]}, {raw[2]}, {raw[3]} }))).all());
}
{
Matrix<Scalar, 1, 4> m { {raw[0], raw[1], raw[2], raw[3]} };
Array<Scalar, 1, 4> a { {raw[0], raw[1], raw[2], raw[3]} };
for(int k = 0; k < 4; ++k) {
VERIFY(m(k) == raw[k]);
}
for(int k = 0; k < 4; ++k) {
VERIFY(a(k) == raw[k]);
}
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 1, 4>({{raw[0],raw[1],raw[2],raw[3]}})));
VERIFY((a == (Array<Scalar, 1, 4>({{raw[0],raw[1],raw[2],raw[3]}}))).all());
}
{
Matrix<Scalar, 4, Dynamic> m { {raw[0]}, {raw[1]}, {raw[2]}, {raw[3]} };
Array<Scalar, 4, Dynamic> a { {raw[0]}, {raw[1]}, {raw[2]}, {raw[3]} };
for(int k=0; k < 4; ++k) {
VERIFY(m(k) == raw[k]);
}
for(int k=0; k < 4; ++k) {
VERIFY(a(k) == raw[k]);
}
VERIFY_IS_EQUAL(m, (Matrix<Scalar, 4, Dynamic>({ {raw[0]}, {raw[1]}, {raw[2]}, {raw[3]} })));
VERIFY((a == (Array<Scalar, 4, Dynamic>({ {raw[0]}, {raw[1]}, {raw[2]}, {raw[3]} }))).all());
}
{
Matrix<Scalar, Dynamic, 4> m {{raw[0],raw[1],raw[2],raw[3]}};
Array<Scalar, Dynamic, 4> a {{raw[0],raw[1],raw[2],raw[3]}};
for(int k=0; k < 4; ++k) {
VERIFY(m(k) == raw[k]);
}
for(int k=0; k < 4; ++k) {
VERIFY(a(k) == raw[k]);
}
VERIFY_IS_EQUAL(m, (Matrix<Scalar, Dynamic, 4>({{raw[0],raw[1],raw[2],raw[3]}})));
VERIFY((a == (Array<Scalar, Dynamic, 4>({{raw[0],raw[1],raw[2],raw[3]}}))).all());
}
}
template<typename Scalar> void initializerListMatrixConstruction()
{
const Index RowsAtCompileTime = 5;
const Index ColsAtCompileTime = 4;
const Index SizeAtCompileTime = RowsAtCompileTime * ColsAtCompileTime;
Scalar raw[SizeAtCompileTime];
for (int i = 0; i < SizeAtCompileTime; ++i) {
raw[i] = internal::random<Scalar>();
}
{
Matrix<Scalar, Dynamic, Dynamic> m {};
VERIFY(m.cols() == 0);
VERIFY(m.rows() == 0);
VERIFY_IS_EQUAL(m, (Matrix<Scalar, Dynamic, Dynamic>()));
}
{
Matrix<Scalar, 5, 4> m {
{raw[0], raw[1], raw[2], raw[3]},
{raw[4], raw[5], raw[6], raw[7]},
{raw[8], raw[9], raw[10], raw[11]},
{raw[12], raw[13], raw[14], raw[15]},
{raw[16], raw[17], raw[18], raw[19]}
};
Matrix<Scalar, 5, 4> m2;
m2 << raw[0], raw[1], raw[2], raw[3],
raw[4], raw[5], raw[6], raw[7],
raw[8], raw[9], raw[10], raw[11],
raw[12], raw[13], raw[14], raw[15],
raw[16], raw[17], raw[18], raw[19];
int k = 0;
for(int i = 0; i < RowsAtCompileTime; ++i) {
for (int j = 0; j < ColsAtCompileTime; ++j) {
VERIFY(m(i, j) == raw[k]);
++k;
}
}
VERIFY_IS_EQUAL(m, m2);
}
{
Matrix<Scalar, Dynamic, Dynamic> m{
{raw[0], raw[1], raw[2], raw[3]},
{raw[4], raw[5], raw[6], raw[7]},
{raw[8], raw[9], raw[10], raw[11]},
{raw[12], raw[13], raw[14], raw[15]},
{raw[16], raw[17], raw[18], raw[19]}
};
VERIFY(m.cols() == 4);
VERIFY(m.rows() == 5);
int k = 0;
for(int i = 0; i < RowsAtCompileTime; ++i) {
for (int j = 0; j < ColsAtCompileTime; ++j) {
VERIFY(m(i, j) == raw[k]);
++k;
}
}
Matrix<Scalar, Dynamic, Dynamic> m2(RowsAtCompileTime, ColsAtCompileTime);
k = 0;
for(int i = 0; i < RowsAtCompileTime; ++i) {
for (int j = 0; j < ColsAtCompileTime; ++j) {
m2(i, j) = raw[k];
++k;
}
}
VERIFY_IS_EQUAL(m, m2);
}
}
template<typename Scalar> void initializerListArrayConstruction()
{
const Index RowsAtCompileTime = 5;
const Index ColsAtCompileTime = 4;
const Index SizeAtCompileTime = RowsAtCompileTime * ColsAtCompileTime;
Scalar raw[SizeAtCompileTime];
for (int i = 0; i < SizeAtCompileTime; ++i) {
raw[i] = internal::random<Scalar>();
}
{
Array<Scalar, Dynamic, Dynamic> a {};
VERIFY(a.cols() == 0);
VERIFY(a.rows() == 0);
}
{
Array<Scalar, 5, 4> m {
{raw[0], raw[1], raw[2], raw[3]},
{raw[4], raw[5], raw[6], raw[7]},
{raw[8], raw[9], raw[10], raw[11]},
{raw[12], raw[13], raw[14], raw[15]},
{raw[16], raw[17], raw[18], raw[19]}
};
Array<Scalar, 5, 4> m2;
m2 << raw[0], raw[1], raw[2], raw[3],
raw[4], raw[5], raw[6], raw[7],
raw[8], raw[9], raw[10], raw[11],
raw[12], raw[13], raw[14], raw[15],
raw[16], raw[17], raw[18], raw[19];
int k = 0;
for(int i = 0; i < RowsAtCompileTime; ++i) {
for (int j = 0; j < ColsAtCompileTime; ++j) {
VERIFY(m(i, j) == raw[k]);
++k;
}
}
VERIFY_IS_APPROX(m, m2);
}
{
Array<Scalar, Dynamic, Dynamic> m {
{raw[0], raw[1], raw[2], raw[3]},
{raw[4], raw[5], raw[6], raw[7]},
{raw[8], raw[9], raw[10], raw[11]},
{raw[12], raw[13], raw[14], raw[15]},
{raw[16], raw[17], raw[18], raw[19]}
};
VERIFY(m.cols() == 4);
VERIFY(m.rows() == 5);
int k = 0;
for(int i = 0; i < RowsAtCompileTime; ++i) {
for (int j = 0; j < ColsAtCompileTime; ++j) {
VERIFY(m(i, j) == raw[k]);
++k;
}
}
Array<Scalar, Dynamic, Dynamic> m2(RowsAtCompileTime, ColsAtCompileTime);
k = 0;
for(int i = 0; i < RowsAtCompileTime; ++i) {
for (int j = 0; j < ColsAtCompileTime; ++j) {
m2(i, j) = raw[k];
++k;
}
}
VERIFY_IS_APPROX(m, m2);
}
}
template<typename Scalar> void dynamicVectorConstruction()
{
const Index size = 4;
Scalar raw[size];
for (int i = 0; i < size; ++i) {
raw[i] = internal::random<Scalar>();
}
typedef Matrix<Scalar, Dynamic, 1> VectorX;
{
VectorX v {{raw[0], raw[1], raw[2], raw[3]}};
for (int i = 0; i < size; ++i) {
VERIFY(v(i) == raw[i]);
}
VERIFY(v.rows() == size);
VERIFY(v.cols() == 1);
VERIFY_IS_EQUAL(v, (VectorX {{raw[0], raw[1], raw[2], raw[3]}}));
}
{
VERIFY_RAISES_ASSERT((VectorX {raw[0], raw[1], raw[2], raw[3]}));
}
{
VERIFY_RAISES_ASSERT((VectorX {
{raw[0], raw[1], raw[2], raw[3]},
{raw[0], raw[1], raw[2], raw[3]},
}));
}
}
EIGEN_DECLARE_TEST(initializer_list_construction)
{
CALL_SUBTEST_1(initializerListVectorConstruction<unsigned char>());
CALL_SUBTEST_1(initializerListVectorConstruction<float>());
CALL_SUBTEST_1(initializerListVectorConstruction<double>());
CALL_SUBTEST_1(initializerListVectorConstruction<int>());
CALL_SUBTEST_1(initializerListVectorConstruction<long int>());
CALL_SUBTEST_1(initializerListVectorConstruction<std::ptrdiff_t>());
CALL_SUBTEST_1(initializerListVectorConstruction<std::complex<int>>());
CALL_SUBTEST_1(initializerListVectorConstruction<std::complex<double>>());
CALL_SUBTEST_1(initializerListVectorConstruction<std::complex<float>>());
CALL_SUBTEST_2(initializerListMatrixConstruction<unsigned char>());
CALL_SUBTEST_2(initializerListMatrixConstruction<float>());
CALL_SUBTEST_2(initializerListMatrixConstruction<double>());
CALL_SUBTEST_2(initializerListMatrixConstruction<int>());
CALL_SUBTEST_2(initializerListMatrixConstruction<long int>());
CALL_SUBTEST_2(initializerListMatrixConstruction<std::ptrdiff_t>());
CALL_SUBTEST_2(initializerListMatrixConstruction<std::complex<int>>());
CALL_SUBTEST_2(initializerListMatrixConstruction<std::complex<double>>());
CALL_SUBTEST_2(initializerListMatrixConstruction<std::complex<float>>());
CALL_SUBTEST_3(initializerListArrayConstruction<unsigned char>());
CALL_SUBTEST_3(initializerListArrayConstruction<float>());
CALL_SUBTEST_3(initializerListArrayConstruction<double>());
CALL_SUBTEST_3(initializerListArrayConstruction<int>());
CALL_SUBTEST_3(initializerListArrayConstruction<long int>());
CALL_SUBTEST_3(initializerListArrayConstruction<std::ptrdiff_t>());
CALL_SUBTEST_3(initializerListArrayConstruction<std::complex<int>>());
CALL_SUBTEST_3(initializerListArrayConstruction<std::complex<double>>());
CALL_SUBTEST_3(initializerListArrayConstruction<std::complex<float>>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<unsigned char>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<float>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<double>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<int>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<long int>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<std::ptrdiff_t>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<std::complex<int>>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<std::complex<double>>());
CALL_SUBTEST_4(singleInitializerListVectorConstruction<std::complex<float>>());
CALL_SUBTEST_5(TestMethodDispatching<int>::run());
CALL_SUBTEST_5(TestMethodDispatching<long int>::run());
CALL_SUBTEST_6(dynamicVectorConstruction<unsigned char>());
CALL_SUBTEST_6(dynamicVectorConstruction<float>());
CALL_SUBTEST_6(dynamicVectorConstruction<double>());
CALL_SUBTEST_6(dynamicVectorConstruction<int>());
CALL_SUBTEST_6(dynamicVectorConstruction<long int>());
CALL_SUBTEST_6(dynamicVectorConstruction<std::ptrdiff_t>());
CALL_SUBTEST_6(dynamicVectorConstruction<std::complex<int>>());
CALL_SUBTEST_6(dynamicVectorConstruction<std::complex<double>>());
CALL_SUBTEST_6(dynamicVectorConstruction<std::complex<float>>());
}