22#if defined(__MINGW32__)
27#include <Eigen/SparseCore>
34static_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),
35 "Eigen matrix support in pybind11 requires Eigen >= 3.2.7");
43template <typename MatrixType>
45template <typename MatrixType>
50#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
52template <
typename Scalar,
int Flags,
typename StorageIndex>
56template <
typename Scalar,
int Flags,
typename StorageIndex>
63 std::is_base_of<Eigen::MapBase<T, Eigen::ReadOnlyAccessors>, T>>;
81template <
bool EigenRowMajor>
95 stride{EigenRowMajor ? (rstride > 0 ? rstride : 0)
96 : (cstride > 0 ? cstride : 0) ,
97 EigenRowMajor ? (cstride > 0 ? cstride : 0)
98 : (rstride > 0 ? rstride : 0) },
104 template <
typename props>
116 return (props::inner_stride == Eigen::Dynamic || props::inner_stride ==
stride.inner()
117 || (EigenRowMajor ?
cols :
rows) == 1)
118 && (props::outer_stride == Eigen::Dynamic || props::outer_stride ==
stride.outer()
119 || (EigenRowMajor ?
rows :
cols) == 1);
125template <
typename Type>
129template <
typename PlainObjectType,
int MapOptions,
typename Str
ideType>
133template <
typename PlainObjectType,
int Options,
typename Str
ideType>
139template <
typename Type_>
144 static constexpr EigenIndex rows = Type::RowsAtCompileTime,
cols = Type::ColsAtCompileTime,
145 size = Type::SizeAtCompileTime;
146 static constexpr bool row_major = Type::IsRowMajor,
148 = Type::IsVectorAtCompileTime,
153 template <EigenIndex i, EigenIndex ifzero>
154 using if_zero = std::integral_constant<EigenIndex, i == 0 ? ifzero : i>;
172 const auto dims = a.
ndim();
173 if (dims < 1 || dims > 2) {
186 return {np_rows, np_cols, np_rstride, np_cstride};
198 return {
rows == 1 ? 1 : n,
cols == 1 ? 1 : n, stride};
210 return {1, n, stride};
215 return {n, 1, stride};
236 const_name<show_writeable>(
", flags.writeable",
"")
237 + const_name<show_c_contiguous>(
", flags.c_contiguous",
"")
238 + const_name<show_f_contiguous>(
", flags.f_contiguous",
"") +
const_name(
"]");
243template <
typename props>
246 constexpr ssize_t elem_size =
sizeof(
typename props::Scalar);
249 a =
array({src.size()}, {elem_size * src.innerStride()}, src.data(),
base);
251 a =
array({src.rows(), src.cols()},
252 {elem_size * src.rowStride(), elem_size * src.colStride()},
268template <
typename props,
typename Type>
272 return eigen_array_cast<props>(src, parent, !std::is_const<Type>::value);
279template <typename props, typename Type, typename = enable_if_t<is_eigen_dense_plain<Type>::value>>
281 capsule base(src, [](
void *o) {
delete static_cast<Type *
>(o); });
282 return eigen_ref_array<props>(*src,
base);
287template <
typename Type>
305 auto dims = buf.ndim();
306 if (dims < 1 || dims > 2) {
310 auto fits = props::conformable(buf);
316 value = Type(fits.rows, fits.cols);
317 auto ref = reinterpret_steal<array>(eigen_ref_array<props>(
value));
320 }
else if (
ref.ndim() == 1) {
324 int result = detail::npy_api::get().PyArray_CopyInto_(
ref.ptr(), buf.ptr());
336 template <
typename CType>
339 case return_value_policy::take_ownership:
340 case return_value_policy::automatic:
341 return eigen_encapsulate<props>(src);
342 case return_value_policy::move:
343 return eigen_encapsulate<props>(
new CType(std::move(*src)));
344 case return_value_policy::copy:
345 return eigen_array_cast<props>(*src);
346 case return_value_policy::reference:
347 case return_value_policy::automatic_reference:
348 return eigen_ref_array<props>(*src);
349 case return_value_policy::reference_internal:
350 return eigen_ref_array<props>(*src, parent);
352 throw cast_error(
"unhandled return_value_policy: should not happen!");
359 return cast_impl(&src, return_value_policy::move, parent);
363 return cast_impl(&src, return_value_policy::move, parent);
367 if (policy == return_value_policy::automatic
368 || policy == return_value_policy::automatic_reference) {
369 policy = return_value_policy::copy;
371 return cast_impl(&src, policy, parent);
375 if (policy == return_value_policy::automatic
376 || policy == return_value_policy::automatic_reference) {
377 policy = return_value_policy::copy;
379 return cast(&src, policy, parent);
383 return cast_impl(src, policy, parent);
387 return cast_impl(src, policy, parent);
390 static constexpr auto name = props::descriptor;
393 operator Type *() {
return &
value; }
397 operator Type &&() && {
return std::move(
value); }
398 template <
typename T>
406template <
typename MapType>
420 case return_value_policy::copy:
421 return eigen_array_cast<props>(src);
422 case return_value_policy::reference_internal:
424 case return_value_policy::reference:
425 case return_value_policy::automatic:
426 case return_value_policy::automatic_reference:
430 pybind11_fail(
"Invalid return_value_policy for Eigen Map/Ref/Block type");
440 operator MapType() =
delete;
446template <
typename Type>
451template <
typename PlainObjectType,
typename Str
ideType>
453 Eigen::Ref<PlainObjectType, 0, StrideType>,
454 enable_if_t<is_eigen_dense_map<Eigen::Ref<PlainObjectType, 0, StrideType>>::value>>
457 using Type = Eigen::Ref<PlainObjectType, 0, StrideType>;
460 using MapType = Eigen::Map<PlainObjectType, 0, StrideType>;
464 | ((props::row_major ? props::inner_stride : props::outer_stride) == 1
466 : (props::row_major ? props::outer_stride : props::inner_stride) == 1
471 std::unique_ptr<MapType> map;
472 std::unique_ptr<Type>
ref;
485 bool need_copy = !isinstance<Array>(src);
491 auto aref = reinterpret_borrow<Array>(src);
493 if (aref && (!need_writeable || aref.writeable())) {
494 fits = props::conformable(aref);
498 if (!fits.template stride_compatible<props>()) {
501 copy_or_ref = std::move(aref);
512 if (!convert || need_writeable) {
520 fits = props::conformable(
copy);
521 if (!fits || !fits.template stride_compatible<props>()) {
524 copy_or_ref = std::move(
copy);
532 make_stride(fits.
stride.outer(), fits.
stride.inner())));
542 template <
typename _T>
546 template <typename T = Type, enable_if_t<is_eigen_mutable_map<T>::value,
int> = 0>
551 template <typename T = Type, enable_if_t<!is_eigen_mutable_map<T>::value,
int> = 0>
558 template <
typename S>
560 && S::OuterStrideAtCompileTime != Eigen::Dynamic
561 && std::is_default_constructible<S>::value>;
564 template <
typename S>
567 && std::is_constructible<S, EigenIndex, EigenIndex>::value>;
570 template <
typename S>
573 && S::OuterStrideAtCompileTime == Eigen::Dynamic
574 && S::InnerStrideAtCompileTime != Eigen::Dynamic
575 && std::is_constructible<S, EigenIndex>::value>;
576 template <
typename S>
579 && S::InnerStrideAtCompileTime == Eigen::Dynamic
580 && S::OuterStrideAtCompileTime != Eigen::Dynamic
581 && std::is_constructible<S, EigenIndex>::value>;
583 template <typename S = StrideType, enable_if_t<stride_ctor_default<S>::value,
int> = 0>
587 template <typename S = StrideType, enable_if_t<stride_ctor_dual<S>::value,
int> = 0>
589 return S(outer, inner);
591 template <typename S = StrideType, enable_if_t<stride_ctor_outer<S>::value,
int> = 0>
595 template <typename S = StrideType, enable_if_t<stride_ctor_inner<S>::value,
int> = 0>
605template <
typename Type>
609 = Eigen::Matrix<typename Type::Scalar, Type::RowsAtCompileTime, Type::ColsAtCompileTime>;
618 return cast(*src, policy, parent);
621 static constexpr auto name = props::descriptor;
627 operator Type() =
delete;
632template <
typename Type>
637 static constexpr bool rowMajor = Type::IsRowMajor;
644 auto obj = reinterpret_borrow<object>(src);
646 object matrix_type = sparse_module.attr(rowMajor ?
"csr_matrix" :
"csc_matrix");
650 obj = matrix_type(obj);
659 auto shape = pybind11::tuple((pybind11::object) obj.attr(
"shape"));
660 auto nnz = obj.attr(
"nnz").cast<
Index>();
662 if (!values || !innerIndices || !outerIndices) {
667 Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),
669 shape[1].cast<
Index>(),
671 outerIndices.mutable_data(),
672 innerIndices.mutable_data(),
673 values.mutable_data());
679 const_cast<Type &
>(src).makeCompressed();
682 =
module_::import(
"scipy.sparse").attr(rowMajor ?
"csr_matrix" :
"csc_matrix");
684 array data(src.nonZeros(), src.valuePtr());
685 array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
686 array innerIndices(src.nonZeros(), src.innerIndexPtr());
688 return matrix_type(pybind11::make_tuple(
689 std::move(
data), std::move(innerIndices), std::move(outerIndices)),
690 pybind11::make_tuple(src.rows(), src.cols()))
695 const_name<(Type::IsRowMajor) != 0>(
"scipy.sparse.csr_matrix[",
696 "scipy.sparse.csc_matrix[")
const T * data(Ix... index) const
T * mutable_data(Ix... index)
ssize_t ndim() const
Number of dimensions.
const ssize_t * strides() const
Strides of the array.
static array ensure(handle h, int ExtraFlags=0)
Ensure that the argument is a NumPy array In case of an error, nullptr is returned and the Python err...
const ssize_t * shape() const
Dimensions of the array.
Fetch and hold an error which was already set in Python.
\rst Holds a reference to a Python object (no reference counting)
PyObject * ptr() const
Return the underlying PyObject * pointer.
static PYBIND11_NOINLINE void add_patient(handle h)
This can only be used inside a pybind11-bound function, either by argument_loader at argument prepara...
static module_ import(const char *name)
Import and return a module or throws error_already_set.
handle release()
\rst Resets the internal pointer to nullptr without decreasing the object's reference count.
Reference counting helper.
static handle cast(const itype &src, return_value_policy policy, handle parent)
static handle handle_of()
Convert C++ type to handle if previously registered.
bool isinstance(handle obj)
\rst Return true if obj is an instance of T.
handle eigen_array_cast(typename props::Type const &src, handle base=handle(), bool writeable=true)
handle eigen_ref_array(Type &src, handle parent=none())
EIGEN_DEFAULT_DENSE_INDEX_TYPE EigenIndex
handle eigen_encapsulate(Type *src)
std::is_base_of< Eigen::MapBase< T, Eigen::WriteAccessors >, T > is_eigen_mutable_map
Eigen::MappedSparseMatrix< Scalar, Flags, StorageIndex > EigenMapSparseMatrix
PYBIND11_WARNING_PUSH PYBIND11_WARNING_POP
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
std::integral_constant< bool, B > bool_constant
Backports of std::bool_constant and std::negation to accommodate older compilers.
PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Thrown when pybind11::cast or.
typename std::remove_reference< T >::type remove_reference_t
decltype(is_template_base_of_impl< Base >::check((intrinsic_t< T > *) nullptr)) is_template_base_of
Check if a template is the base of a type.
#define PYBIND11_NAMESPACE_END(name)
#define PYBIND11_NAMESPACE_BEGIN(name)
std::is_same< bools< Ts::value..., true >, bools< true, Ts::value... > > all_of
return_value_policy
Approach used to cast a previously unknown C++ instance into a Python object.
@ copy
Create a new copy of the returned object, which will be owned by Python.
constexpr descr< N - 1 > const_name(char const (&text)[N])
conditional_t< std::is_pointer< typename std::remove_reference< T >::type >::value, typename std::add_pointer< intrinsic_t< T > >::type, conditional_t< std::is_rvalue_reference< T >::value, typename std::add_rvalue_reference< intrinsic_t< T > >::type, typename std::add_lvalue_reference< intrinsic_t< T > >::type > > movable_cast_op_type
Determine suitable casting operator for a type caster with a movable value.
all_of< is_template_base_of< Eigen::DenseBase, T >, std::is_base_of< Eigen::MapBase< T, Eigen::ReadOnlyAccessors >, T > > is_eigen_dense_map
Eigen::Map< MatrixType, 0, EigenDStride > EigenDMap
EIGEN_DEFAULT_DENSE_INDEX_TYPE EigenIndex
Eigen::Stride< Eigen::Dynamic, Eigen::Dynamic > EigenDStride
all_of< negation< is_eigen_dense_map< T > >, is_template_base_of< Eigen::PlainObjectBase, T > > is_eigen_dense_plain
std::is_base_of< Eigen::MapBase< T, Eigen::WriteAccessors >, T > is_eigen_mutable_map
Eigen::Ref< MatrixType, 0, EigenDStride > EigenDRef
Eigen::MappedSparseMatrix< Scalar, Flags, StorageIndex > EigenMapSparseMatrix
all_of< is_template_base_of< Eigen::EigenBase, T >, negation< any_of< is_eigen_dense_map< T >, is_eigen_dense_plain< T >, is_eigen_sparse< T > > > > is_eigen_other
is_template_base_of< Eigen::SparseMatrixBase, T > is_eigen_sparse
PyArray_Proxy * array_proxy(void *ptr)
arr data(const arr &a, Ix... index)
#define PYBIND11_WARNING_DISABLE_GCC(name)
#define PYBIND11_WARNING_DISABLE_MSVC(name)
static constexpr bool fixed
static constexpr EigenIndex rows
static constexpr bool dynamic_stride
typename eigen_extract_stride< Type >::type StrideType
static constexpr bool show_writeable
static constexpr bool requires_row_major
static constexpr bool show_c_contiguous
static EigenConformable< row_major > conformable(const array &a)
static constexpr EigenIndex outer_stride
static constexpr bool row_major
static constexpr EigenIndex size
static constexpr bool vector
static constexpr bool fixed_rows
static constexpr bool show_order
static constexpr EigenIndex inner_stride
static constexpr auto descriptor
std::integral_constant< EigenIndex, i==0 ? ifzero :i > if_zero
static constexpr bool show_f_contiguous
static constexpr bool fixed_cols
static constexpr bool dynamic
typename Type::Scalar Scalar
static constexpr EigenIndex cols
static constexpr bool requires_col_major
Annotation indicating that a class derives from another given type.
bool load(handle, bool)=delete
static handle cast(const MapType &src, return_value_policy policy, handle parent)
Annotation for function names.
bool_constant<!any_of< stride_ctor_default< S >, stride_ctor_dual< S > >::value &&S::InnerStrideAtCompileTime==Eigen::Dynamic &&S::OuterStrideAtCompileTime !=Eigen::Dynamic &&std::is_constructible< S, EigenIndex >::value > stride_ctor_inner
bool_constant<!stride_ctor_default< S >::value &&std::is_constructible< S, EigenIndex, EigenIndex >::value > stride_ctor_dual
static S make_stride(EigenIndex outer, EigenIndex inner)
Eigen::Ref< PlainObjectType, 0, StrideType > Type
pybind11::detail::cast_op_type< _T > cast_op_type
static S make_stride(EigenIndex, EigenIndex inner)
bool_constant<!any_of< stride_ctor_default< S >, stride_ctor_dual< S > >::value &&S::OuterStrideAtCompileTime==Eigen::Dynamic &&S::InnerStrideAtCompileTime !=Eigen::Dynamic &&std::is_constructible< S, EigenIndex >::value > stride_ctor_outer
static S make_stride(EigenIndex outer, EigenIndex)
Eigen::Map< PlainObjectType, 0, StrideType > MapType
bool load(handle src, bool convert)
const Scalar * data(Array &a)
static S make_stride(EigenIndex, EigenIndex)
bool_constant< S::InnerStrideAtCompileTime !=Eigen::Dynamic &&S::OuterStrideAtCompileTime !=Eigen::Dynamic &&std::is_default_constructible< S >::value > stride_ctor_default
typename props::Scalar Scalar
static handle cast(Type &src, return_value_policy policy, handle parent)
static handle cast(Type *src, return_value_policy policy, handle parent)
static handle cast(const Type &src, return_value_policy policy, handle parent)
movable_cast_op_type< T > cast_op_type
static handle cast(Type &&src, return_value_policy, handle parent)
static handle cast_impl(CType *src, return_value_policy policy, handle parent)
bool load(handle src, bool convert)
static handle cast(const Type *src, return_value_policy policy, handle parent)
typename Type::Scalar Scalar
static handle cast(const Type &&src, return_value_policy, handle parent)
Eigen::Matrix< typename Type::Scalar, Type::RowsAtCompileTime, Type::ColsAtCompileTime > Matrix
bool load(handle, bool)=delete
static handle cast(const Type *src, return_value_policy policy, handle parent)
static handle cast(const Type &src, return_value_policy, handle)
static handle cast(const Type &src, return_value_policy, handle)
typename Type::Scalar Scalar
typename Type::Index Index
remove_reference_t< decltype(*std::declval< Type >().outerIndexPtr())> StorageIndex
PYBIND11_TYPE_CASTER(Type, const_name<(Type::IsRowMajor) !=0 >("scipy.sparse.csr_matrix[", "scipy.sparse.csc_matrix[")+npy_format_descriptor< Scalar >::name+const_name("]"))
bool load(handle src, bool)