eigen.rst revision 12037
111986Sandreas.sandberg@arm.comEigen 212037Sandreas.sandberg@arm.com##### 311986Sandreas.sandberg@arm.com 411986Sandreas.sandberg@arm.com`Eigen <http://eigen.tuxfamily.org>`_ is C++ header-based library for dense and 511986Sandreas.sandberg@arm.comsparse linear algebra. Due to its popularity and widespread adoption, pybind11 612037Sandreas.sandberg@arm.comprovides transparent conversion and limited mapping support between Eigen and 712037Sandreas.sandberg@arm.comScientific Python linear algebra data types. 811986Sandreas.sandberg@arm.com 912037Sandreas.sandberg@arm.comTo enable the built-in Eigen support you must include the optional header file 1012037Sandreas.sandberg@arm.com:file:`pybind11/eigen.h`. 1111986Sandreas.sandberg@arm.com 1212037Sandreas.sandberg@arm.comPass-by-value 1312037Sandreas.sandberg@arm.com============= 1411986Sandreas.sandberg@arm.com 1512037Sandreas.sandberg@arm.comWhen binding a function with ordinary Eigen dense object arguments (for 1612037Sandreas.sandberg@arm.comexample, ``Eigen::MatrixXd``), pybind11 will accept any input value that is 1712037Sandreas.sandberg@arm.comalready (or convertible to) a ``numpy.ndarray`` with dimensions compatible with 1812037Sandreas.sandberg@arm.comthe Eigen type, copy its values into a temporary Eigen variable of the 1912037Sandreas.sandberg@arm.comappropriate type, then call the function with this temporary variable. 2011986Sandreas.sandberg@arm.com 2112037Sandreas.sandberg@arm.comSparse matrices are similarly copied to or from 2212037Sandreas.sandberg@arm.com``scipy.sparse.csr_matrix``/``scipy.sparse.csc_matrix`` objects. 2311986Sandreas.sandberg@arm.com 2412037Sandreas.sandberg@arm.comPass-by-reference 2512037Sandreas.sandberg@arm.com================= 2611986Sandreas.sandberg@arm.com 2712037Sandreas.sandberg@arm.comOne major limitation of the above is that every data conversion implicitly 2812037Sandreas.sandberg@arm.cominvolves a copy, which can be both expensive (for large matrices) and disallows 2912037Sandreas.sandberg@arm.combinding functions that change their (Matrix) arguments. Pybind11 allows you to 3012037Sandreas.sandberg@arm.comwork around this by using Eigen's ``Eigen::Ref<MatrixType>`` class much as you 3112037Sandreas.sandberg@arm.comwould when writing a function taking a generic type in Eigen itself (subject to 3212037Sandreas.sandberg@arm.comsome limitations discussed below). 3312037Sandreas.sandberg@arm.com 3412037Sandreas.sandberg@arm.comWhen calling a bound function accepting a ``Eigen::Ref<const MatrixType>`` 3512037Sandreas.sandberg@arm.comtype, pybind11 will attempt to avoid copying by using an ``Eigen::Map`` object 3612037Sandreas.sandberg@arm.comthat maps into the source ``numpy.ndarray`` data: this requires both that the 3712037Sandreas.sandberg@arm.comdata types are the same (e.g. ``dtype='float64'`` and ``MatrixType::Scalar`` is 3812037Sandreas.sandberg@arm.com``double``); and that the storage is layout compatible. The latter limitation 3912037Sandreas.sandberg@arm.comis discussed in detail in the section below, and requires careful 4012037Sandreas.sandberg@arm.comconsideration: by default, numpy matrices and eigen matrices are *not* storage 4112037Sandreas.sandberg@arm.comcompatible. 4212037Sandreas.sandberg@arm.com 4312037Sandreas.sandberg@arm.comIf the numpy matrix cannot be used as is (either because its types differ, e.g. 4412037Sandreas.sandberg@arm.compassing an array of integers to an Eigen paramater requiring doubles, or 4512037Sandreas.sandberg@arm.combecause the storage is incompatible), pybind11 makes a temporary copy and 4612037Sandreas.sandberg@arm.compasses the copy instead. 4712037Sandreas.sandberg@arm.com 4812037Sandreas.sandberg@arm.comWhen a bound function parameter is instead ``Eigen::Ref<MatrixType>`` (note the 4912037Sandreas.sandberg@arm.comlack of ``const``), pybind11 will only allow the function to be called if it 5012037Sandreas.sandberg@arm.comcan be mapped *and* if the numpy array is writeable (that is 5112037Sandreas.sandberg@arm.com``a.flags.writeable`` is true). Any access (including modification) made to 5212037Sandreas.sandberg@arm.comthe passed variable will be transparently carried out directly on the 5312037Sandreas.sandberg@arm.com``numpy.ndarray``. 5412037Sandreas.sandberg@arm.com 5512037Sandreas.sandberg@arm.comThis means you can can write code such as the following and have it work as 5612037Sandreas.sandberg@arm.comexpected: 5711986Sandreas.sandberg@arm.com 5811986Sandreas.sandberg@arm.com.. code-block:: cpp 5911986Sandreas.sandberg@arm.com 6012037Sandreas.sandberg@arm.com void scale_by_2(Eigen::Ref<Eigen::VectorXd> m) { 6111986Sandreas.sandberg@arm.com v *= 2; 6211986Sandreas.sandberg@arm.com } 6311986Sandreas.sandberg@arm.com 6412037Sandreas.sandberg@arm.comNote, however, that you will likely run into limitations due to numpy and 6512037Sandreas.sandberg@arm.comEigen's difference default storage order for data; see the below section on 6612037Sandreas.sandberg@arm.com:ref:`storage_orders` for details on how to bind code that won't run into such 6712037Sandreas.sandberg@arm.comlimitations. 6812037Sandreas.sandberg@arm.com 6912037Sandreas.sandberg@arm.com.. note:: 7012037Sandreas.sandberg@arm.com 7112037Sandreas.sandberg@arm.com Passing by reference is not supported for sparse types. 7212037Sandreas.sandberg@arm.com 7312037Sandreas.sandberg@arm.comReturning values to Python 7412037Sandreas.sandberg@arm.com========================== 7512037Sandreas.sandberg@arm.com 7612037Sandreas.sandberg@arm.comWhen returning an ordinary dense Eigen matrix type to numpy (e.g. 7712037Sandreas.sandberg@arm.com``Eigen::MatrixXd`` or ``Eigen::RowVectorXf``) pybind11 keeps the matrix and 7812037Sandreas.sandberg@arm.comreturns a numpy array that directly references the Eigen matrix: no copy of the 7912037Sandreas.sandberg@arm.comdata is performed. The numpy array will have ``array.flags.owndata`` set to 8012037Sandreas.sandberg@arm.com``False`` to indicate that it does not own the data, and the lifetime of the 8112037Sandreas.sandberg@arm.comstored Eigen matrix will be tied to the returned ``array``. 8212037Sandreas.sandberg@arm.com 8312037Sandreas.sandberg@arm.comIf you bind a function with a non-reference, ``const`` return type (e.g. 8412037Sandreas.sandberg@arm.com``const Eigen::MatrixXd``), the same thing happens except that pybind11 also 8512037Sandreas.sandberg@arm.comsets the numpy array's ``writeable`` flag to false. 8612037Sandreas.sandberg@arm.com 8712037Sandreas.sandberg@arm.comIf you return an lvalue reference or pointer, the usual pybind11 rules apply, 8812037Sandreas.sandberg@arm.comas dictated by the binding function's return value policy (see the 8912037Sandreas.sandberg@arm.comdocumentation on :ref:`return_value_policies` for full details). That means, 9012037Sandreas.sandberg@arm.comwithout an explicit return value policy, lvalue references will be copied and 9112037Sandreas.sandberg@arm.compointers will be managed by pybind11. In order to avoid copying, you should 9212037Sandreas.sandberg@arm.comexplictly specify an appropriate return value policy, as in the following 9312037Sandreas.sandberg@arm.comexample: 9412037Sandreas.sandberg@arm.com 9512037Sandreas.sandberg@arm.com.. code-block:: cpp 9612037Sandreas.sandberg@arm.com 9712037Sandreas.sandberg@arm.com class MyClass { 9812037Sandreas.sandberg@arm.com Eigen::MatrixXd big_mat = Eigen::MatrixXd::Zero(10000, 10000); 9912037Sandreas.sandberg@arm.com public: 10012037Sandreas.sandberg@arm.com Eigen::MatrixXd &getMatrix() { return big_mat; } 10112037Sandreas.sandberg@arm.com const Eigen::MatrixXd &viewMatrix() { return big_mat; } 10212037Sandreas.sandberg@arm.com }; 10312037Sandreas.sandberg@arm.com 10412037Sandreas.sandberg@arm.com // Later, in binding code: 10512037Sandreas.sandberg@arm.com py::class_<MyClass>(m, "MyClass") 10612037Sandreas.sandberg@arm.com .def(py::init<>()) 10712037Sandreas.sandberg@arm.com .def("copy_matrix", &MyClass::getMatrix) // Makes a copy! 10812037Sandreas.sandberg@arm.com .def("get_matrix", &MyClass::getMatrix, py::return_value_policy::reference_internal) 10912037Sandreas.sandberg@arm.com .def("view_matrix", &MyClass::viewMatrix, py::return_value_policy::reference_internal) 11012037Sandreas.sandberg@arm.com ; 11112037Sandreas.sandberg@arm.com 11212037Sandreas.sandberg@arm.com.. code-block:: python 11312037Sandreas.sandberg@arm.com 11412037Sandreas.sandberg@arm.com a = MyClass() 11512037Sandreas.sandberg@arm.com m = a.get_matrix() # flags.writeable = True, flags.owndata = False 11612037Sandreas.sandberg@arm.com v = a.view_matrix() # flags.writeable = False, flags.owndata = False 11712037Sandreas.sandberg@arm.com c = a.copy_matrix() # flags.writeable = True, flags.owndata = True 11812037Sandreas.sandberg@arm.com # m[5,6] and v[5,6] refer to the same element, c[5,6] does not. 11912037Sandreas.sandberg@arm.com 12012037Sandreas.sandberg@arm.comNote in this example that ``py::return_value_policy::reference_internal`` is 12112037Sandreas.sandberg@arm.comused to tie the life of the MyClass object to the life of the returned arrays. 12212037Sandreas.sandberg@arm.com 12312037Sandreas.sandberg@arm.comYou may also return an ``Eigen::Ref``, ``Eigen::Map`` or other map-like Eigen 12412037Sandreas.sandberg@arm.comobject (for example, the return value of ``matrix.block()`` and related 12512037Sandreas.sandberg@arm.commethods) that map into a dense Eigen type. When doing so, the default 12612037Sandreas.sandberg@arm.combehaviour of pybind11 is to simply reference the returned data: you must take 12712037Sandreas.sandberg@arm.comcare to ensure that this data remains valid! You may ask pybind11 to 12812037Sandreas.sandberg@arm.comexplicitly *copy* such a return value by using the 12912037Sandreas.sandberg@arm.com``py::return_value_policy::copy`` policy when binding the function. You may 13012037Sandreas.sandberg@arm.comalso use ``py::return_value_policy::reference_internal`` or a 13112037Sandreas.sandberg@arm.com``py::keep_alive`` to ensure the data stays valid as long as the returned numpy 13212037Sandreas.sandberg@arm.comarray does. 13312037Sandreas.sandberg@arm.com 13412037Sandreas.sandberg@arm.comWhen returning such a reference of map, pybind11 additionally respects the 13512037Sandreas.sandberg@arm.comreadonly-status of the returned value, marking the numpy array as non-writeable 13612037Sandreas.sandberg@arm.comif the reference or map was itself read-only. 13712037Sandreas.sandberg@arm.com 13812037Sandreas.sandberg@arm.com.. note:: 13912037Sandreas.sandberg@arm.com 14012037Sandreas.sandberg@arm.com Sparse types are always copied when returned. 14112037Sandreas.sandberg@arm.com 14212037Sandreas.sandberg@arm.com.. _storage_orders: 14312037Sandreas.sandberg@arm.com 14412037Sandreas.sandberg@arm.comStorage orders 14512037Sandreas.sandberg@arm.com============== 14612037Sandreas.sandberg@arm.com 14712037Sandreas.sandberg@arm.comPassing arguments via ``Eigen::Ref`` has some limitations that you must be 14812037Sandreas.sandberg@arm.comaware of in order to effectively pass matrices by reference. First and 14912037Sandreas.sandberg@arm.comforemost is that the default ``Eigen::Ref<MatrixType>`` class requires 15012037Sandreas.sandberg@arm.comcontiguous storage along columns (for column-major types, the default in Eigen) 15112037Sandreas.sandberg@arm.comor rows if ``MatrixType`` is specifically an ``Eigen::RowMajor`` storage type. 15212037Sandreas.sandberg@arm.comThe former, Eigen's default, is incompatible with ``numpy``'s default row-major 15312037Sandreas.sandberg@arm.comstorage, and so you will not be able to pass numpy arrays to Eigen by reference 15412037Sandreas.sandberg@arm.comwithout making one of two changes. 15512037Sandreas.sandberg@arm.com 15612037Sandreas.sandberg@arm.com(Note that this does not apply to vectors (or column or row matrices): for such 15712037Sandreas.sandberg@arm.comtypes the "row-major" and "column-major" distinction is meaningless). 15812037Sandreas.sandberg@arm.com 15912037Sandreas.sandberg@arm.comThe first approach is to change the use of ``Eigen::Ref<MatrixType>`` to the 16012037Sandreas.sandberg@arm.commore general ``Eigen::Ref<MatrixType, 0, Eigen::Stride<Eigen::Dynamic, 16112037Sandreas.sandberg@arm.comEigen::Dynamic>>`` (or similar type with a fully dynamic stride type in the 16212037Sandreas.sandberg@arm.comthird template argument). Since this is a rather cumbersome type, pybind11 16312037Sandreas.sandberg@arm.comprovides a ``py::EigenDRef<MatrixType>`` type alias for your convenience (along 16412037Sandreas.sandberg@arm.comwith EigenDMap for the equivalent Map, and EigenDStride for just the stride 16512037Sandreas.sandberg@arm.comtype). 16612037Sandreas.sandberg@arm.com 16712037Sandreas.sandberg@arm.comThis type allows Eigen to map into any arbitrary storage order. This is not 16812037Sandreas.sandberg@arm.comthe default in Eigen for performance reasons: contiguous storage allows 16912037Sandreas.sandberg@arm.comvectorization that cannot be done when storage is not known to be contiguous at 17012037Sandreas.sandberg@arm.comcompile time. The default ``Eigen::Ref`` stride type allows non-contiguous 17112037Sandreas.sandberg@arm.comstorage along the outer dimension (that is, the rows of a column-major matrix 17212037Sandreas.sandberg@arm.comor columns of a row-major matrix), but not along the inner dimension. 17312037Sandreas.sandberg@arm.com 17412037Sandreas.sandberg@arm.comThis type, however, has the added benefit of also being able to map numpy array 17512037Sandreas.sandberg@arm.comslices. For example, the following (contrived) example uses Eigen with a numpy 17612037Sandreas.sandberg@arm.comslice to multiply by 2 all coefficients that are both on even rows (0, 2, 4, 17712037Sandreas.sandberg@arm.com...) and in columns 2, 5, or 8: 17812037Sandreas.sandberg@arm.com 17912037Sandreas.sandberg@arm.com.. code-block:: cpp 18012037Sandreas.sandberg@arm.com 18112037Sandreas.sandberg@arm.com m.def("scale", [](py::EigenDRef<Eigen::MatrixXd> m, double c) { m *= c; }); 18212037Sandreas.sandberg@arm.com 18312037Sandreas.sandberg@arm.com.. code-block:: python 18412037Sandreas.sandberg@arm.com 18512037Sandreas.sandberg@arm.com # a = np.array(...) 18612037Sandreas.sandberg@arm.com scale_by_2(myarray[0::2, 2:9:3]) 18712037Sandreas.sandberg@arm.com 18812037Sandreas.sandberg@arm.comThe second approach to avoid copying is more intrusive: rearranging the 18912037Sandreas.sandberg@arm.comunderlying data types to not run into the non-contiguous storage problem in the 19012037Sandreas.sandberg@arm.comfirst place. In particular, that means using matrices with ``Eigen::RowMajor`` 19112037Sandreas.sandberg@arm.comstorage, where appropriate, such as: 19212037Sandreas.sandberg@arm.com 19312037Sandreas.sandberg@arm.com.. code-block:: cpp 19412037Sandreas.sandberg@arm.com 19512037Sandreas.sandberg@arm.com using RowMatrixXd = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>; 19612037Sandreas.sandberg@arm.com // Use RowMatrixXd instead of MatrixXd 19712037Sandreas.sandberg@arm.com 19812037Sandreas.sandberg@arm.comNow bound functions accepting ``Eigen::Ref<RowMatrixXd>`` arguments will be 19912037Sandreas.sandberg@arm.comcallable with numpy's (default) arrays without involving a copying. 20012037Sandreas.sandberg@arm.com 20112037Sandreas.sandberg@arm.comYou can, alternatively, change the storage order that numpy arrays use by 20212037Sandreas.sandberg@arm.comadding the ``order='F'`` option when creating an array: 20312037Sandreas.sandberg@arm.com 20412037Sandreas.sandberg@arm.com.. code-block:: python 20512037Sandreas.sandberg@arm.com 20612037Sandreas.sandberg@arm.com myarray = np.array(source, order='F') 20712037Sandreas.sandberg@arm.com 20812037Sandreas.sandberg@arm.comSuch an object will be passable to a bound function accepting an 20912037Sandreas.sandberg@arm.com``Eigen::Ref<MatrixXd>`` (or similar column-major Eigen type). 21012037Sandreas.sandberg@arm.com 21112037Sandreas.sandberg@arm.comOne major caveat with this approach, however, is that it is not entirely as 21212037Sandreas.sandberg@arm.comeasy as simply flipping all Eigen or numpy usage from one to the other: some 21312037Sandreas.sandberg@arm.comoperations may alter the storage order of a numpy array. For example, ``a2 = 21412037Sandreas.sandberg@arm.comarray.transpose()`` results in ``a2`` being a view of ``array`` that references 21512037Sandreas.sandberg@arm.comthe same data, but in the opposite storage order! 21612037Sandreas.sandberg@arm.com 21712037Sandreas.sandberg@arm.comWhile this approach allows fully optimized vectorized calculations in Eigen, it 21812037Sandreas.sandberg@arm.comcannot be used with array slices, unlike the first approach. 21912037Sandreas.sandberg@arm.com 22012037Sandreas.sandberg@arm.comWhen *returning* a matrix to Python (either a regular matrix, a reference via 22112037Sandreas.sandberg@arm.com``Eigen::Ref<>``, or a map/block into a matrix), no special storage 22212037Sandreas.sandberg@arm.comconsideration is required: the created numpy array will have the required 22312037Sandreas.sandberg@arm.comstride that allows numpy to properly interpret the array, whatever its storage 22412037Sandreas.sandberg@arm.comorder. 22512037Sandreas.sandberg@arm.com 22612037Sandreas.sandberg@arm.comFailing rather than copying 22712037Sandreas.sandberg@arm.com=========================== 22812037Sandreas.sandberg@arm.com 22912037Sandreas.sandberg@arm.comThe default behaviour when binding ``Eigen::Ref<const MatrixType>`` eigen 23012037Sandreas.sandberg@arm.comreferences is to copy matrix values when passed a numpy array that does not 23112037Sandreas.sandberg@arm.comconform to the element type of ``MatrixType`` or does not have a compatible 23212037Sandreas.sandberg@arm.comstride layout. If you want to explicitly avoid copying in such a case, you 23312037Sandreas.sandberg@arm.comshould bind arguments using the ``py::arg().noconvert()`` annotation (as 23412037Sandreas.sandberg@arm.comdescribed in the :ref:`nonconverting_arguments` documentation). 23512037Sandreas.sandberg@arm.com 23612037Sandreas.sandberg@arm.comThe following example shows an example of arguments that don't allow data 23712037Sandreas.sandberg@arm.comcopying to take place: 23812037Sandreas.sandberg@arm.com 23912037Sandreas.sandberg@arm.com.. code-block:: cpp 24012037Sandreas.sandberg@arm.com 24112037Sandreas.sandberg@arm.com // The method and function to be bound: 24212037Sandreas.sandberg@arm.com class MyClass { 24312037Sandreas.sandberg@arm.com // ... 24412037Sandreas.sandberg@arm.com double some_method(const Eigen::Ref<const MatrixXd> &matrix) { /* ... */ } 24512037Sandreas.sandberg@arm.com }; 24612037Sandreas.sandberg@arm.com float some_function(const Eigen::Ref<const MatrixXf> &big, 24712037Sandreas.sandberg@arm.com const Eigen::Ref<const MatrixXf> &small) { 24812037Sandreas.sandberg@arm.com // ... 24912037Sandreas.sandberg@arm.com } 25012037Sandreas.sandberg@arm.com 25112037Sandreas.sandberg@arm.com // The associated binding code: 25212037Sandreas.sandberg@arm.com using namespace pybind11::literals; // for "arg"_a 25312037Sandreas.sandberg@arm.com py::class_<MyClass>(m, "MyClass") 25412037Sandreas.sandberg@arm.com // ... other class definitions 25512037Sandreas.sandberg@arm.com .def("some_method", &MyClass::some_method, py::arg().nocopy()); 25612037Sandreas.sandberg@arm.com 25712037Sandreas.sandberg@arm.com m.def("some_function", &some_function, 25812037Sandreas.sandberg@arm.com "big"_a.nocopy(), // <- Don't allow copying for this arg 25912037Sandreas.sandberg@arm.com "small"_a // <- This one can be copied if needed 26012037Sandreas.sandberg@arm.com ); 26112037Sandreas.sandberg@arm.com 26212037Sandreas.sandberg@arm.comWith the above binding code, attempting to call the the ``some_method(m)`` 26312037Sandreas.sandberg@arm.commethod on a ``MyClass`` object, or attempting to call ``some_function(m, m2)`` 26412037Sandreas.sandberg@arm.comwill raise a ``RuntimeError`` rather than making a temporary copy of the array. 26512037Sandreas.sandberg@arm.comIt will, however, allow the ``m2`` argument to be copied into a temporary if 26612037Sandreas.sandberg@arm.comnecessary. 26712037Sandreas.sandberg@arm.com 26812037Sandreas.sandberg@arm.comNote that explicitly specifying ``.noconvert()`` is not required for *mutable* 26912037Sandreas.sandberg@arm.comEigen references (e.g. ``Eigen::Ref<MatrixXd>`` without ``const`` on the 27012037Sandreas.sandberg@arm.com``MatrixXd``): mutable references will never be called with a temporary copy. 27112037Sandreas.sandberg@arm.com 27212037Sandreas.sandberg@arm.comVectors versus column/row matrices 27312037Sandreas.sandberg@arm.com================================== 27412037Sandreas.sandberg@arm.com 27512037Sandreas.sandberg@arm.comEigen and numpy have fundamentally different notions of a vector. In Eigen, a 27612037Sandreas.sandberg@arm.comvector is simply a matrix with the number of columns or rows set to 1 at 27712037Sandreas.sandberg@arm.comcompile time (for a column vector or row vector, respectively). Numpy, in 27812037Sandreas.sandberg@arm.comcontast, has comparable 2-dimensional 1xN and Nx1 arrays, but *also* has 27912037Sandreas.sandberg@arm.com1-dimensional arrays of size N. 28012037Sandreas.sandberg@arm.com 28112037Sandreas.sandberg@arm.comWhen passing a 2-dimensional 1xN or Nx1 array to Eigen, the Eigen type must 28212037Sandreas.sandberg@arm.comhave matching dimensions: That is, you cannot pass a 2-dimensional Nx1 numpy 28312037Sandreas.sandberg@arm.comarray to an Eigen value expecting a row vector, or a 1xN numpy array as a 28412037Sandreas.sandberg@arm.comcolumn vector argument. 28512037Sandreas.sandberg@arm.com 28612037Sandreas.sandberg@arm.comOn the other hand, pybind11 allows you to pass 1-dimensional arrays of length N 28712037Sandreas.sandberg@arm.comas Eigen parameters. If the Eigen type can hold a column vector of length N it 28812037Sandreas.sandberg@arm.comwill be passed as such a column vector. If not, but the Eigen type constraints 28912037Sandreas.sandberg@arm.comwill accept a row vector, it will be passed as a row vector. (The column 29012037Sandreas.sandberg@arm.comvector takes precendence when both are supported, for example, when passing a 29112037Sandreas.sandberg@arm.com1D numpy array to a MatrixXd argument). Note that the type need not be 29212037Sandreas.sandberg@arm.comexpicitly a vector: it is permitted to pass a 1D numpy array of size 5 to an 29312037Sandreas.sandberg@arm.comEigen ``Matrix<double, Dynamic, 5>``: you would end up with a 1x5 Eigen matrix. 29412037Sandreas.sandberg@arm.comPassing the same to an ``Eigen::MatrixXd`` would result in a 5x1 Eigen matrix. 29512037Sandreas.sandberg@arm.com 29612037Sandreas.sandberg@arm.comWhen returning an eigen vector to numpy, the conversion is ambiguous: a row 29712037Sandreas.sandberg@arm.comvector of length 4 could be returned as either a 1D array of length 4, or as a 29812037Sandreas.sandberg@arm.com2D array of size 1x4. When encoutering such a situation, pybind11 compromises 29912037Sandreas.sandberg@arm.comby considering the returned Eigen type: if it is a compile-time vector--that 30012037Sandreas.sandberg@arm.comis, the type has either the number of rows or columns set to 1 at compile 30112037Sandreas.sandberg@arm.comtime--pybind11 converts to a 1D numpy array when returning the value. For 30212037Sandreas.sandberg@arm.cominstances that are a vector only at run-time (e.g. ``MatrixXd``, 30312037Sandreas.sandberg@arm.com``Matrix<float, Dynamic, 4>``), pybind11 returns the vector as a 2D array to 30412037Sandreas.sandberg@arm.comnumpy. If this isn't want you want, you can use ``array.reshape(...)`` to get 30512037Sandreas.sandberg@arm.coma view of the same data in the desired dimensions. 30611986Sandreas.sandberg@arm.com 30711986Sandreas.sandberg@arm.com.. seealso:: 30811986Sandreas.sandberg@arm.com 30911986Sandreas.sandberg@arm.com The file :file:`tests/test_eigen.cpp` contains a complete example that 31011986Sandreas.sandberg@arm.com shows how to pass Eigen sparse and dense data types in more detail. 311