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
4014299Sbbruce@ucdavis.educonsideration: 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.
4414299Sbbruce@ucdavis.edupassing an array of integers to an Eigen parameter 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
6012391Sjason@lowepower.com    void scale_by_2(Eigen::Ref<Eigen::VectorXd> v) {
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
9214299Sbbruce@ucdavis.eduexplicitly 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
22914299Sbbruce@ucdavis.eduThe 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
25512391Sjason@lowepower.com        .def("some_method", &MyClass::some_method, py::arg().noconvert());
25612037Sandreas.sandberg@arm.com
25712037Sandreas.sandberg@arm.com    m.def("some_function", &some_function,
25812391Sjason@lowepower.com        "big"_a.noconvert(), // <- Don't allow copying for this arg
25912391Sjason@lowepower.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
27814299Sbbruce@ucdavis.educontrast, 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
29014299Sbbruce@ucdavis.eduvector takes precedence 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
29214299Sbbruce@ucdavis.eduexplicitly 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
29614299Sbbruce@ucdavis.eduWhen 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
29814299Sbbruce@ucdavis.edu2D array of size 1x4.  When encountering 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