27# pragma warning(disable : 4127)
31#include <Eigen/SparseCore>
40static_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),
41 "Eigen support in pybind11 requires Eigen >= 3.2.7");
47template <typename MatrixType>
49template <typename MatrixType>
54#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
56template <
typename Scalar,
int Flags,
typename StorageIndex>
60template <
typename Scalar,
int Flags,
typename StorageIndex>
67 std::is_base_of<Eigen::MapBase<T, Eigen::ReadOnlyAccessors>, T>>;
85template <
bool EigenRowMajor>
99 stride{EigenRowMajor ? (rstride > 0 ? rstride : 0)
100 : (cstride > 0 ? cstride : 0) ,
101 EigenRowMajor ? (cstride > 0 ? cstride : 0)
102 : (rstride > 0 ? rstride : 0) },
108 template <
typename props>
114 && (props::inner_stride == Eigen::Dynamic || props::inner_stride ==
stride.inner()
115 || (EigenRowMajor ?
cols :
rows) == 1)
116 && (props::outer_stride == Eigen::Dynamic || props::outer_stride ==
stride.outer()
117 || (EigenRowMajor ?
rows :
cols) == 1);
123template <
typename Type>
127template <
typename PlainObjectType,
int MapOptions,
typename Str
ideType>
131template <
typename PlainObjectType,
int Options,
typename Str
ideType>
137template <
typename Type_>
143 size = Type::SizeAtCompileTime;
146 = Type::IsVectorAtCompileTime,
151 template <EigenIndex i, EigenIndex ifzero>
152 using if_zero = std::integral_constant<EigenIndex, i == 0 ? ifzero : i>;
170 const auto dims = a.
ndim();
171 if (dims < 1 || dims > 2) {
185 return {np_rows, np_cols, np_rstride, np_cstride};
197 return {
rows == 1 ? 1 : n,
cols == 1 ? 1 : n, stride};
209 return {1, n, stride};
214 return {n, 1, stride};
235 const_name<show_writeable>(
", flags.writeable",
"")
236 + const_name<show_c_contiguous>(
", flags.c_contiguous",
"")
237 + const_name<show_f_contiguous>(
", flags.f_contiguous",
"") +
const_name(
"]");
242template <
typename props>
245 constexpr ssize_t elem_size =
sizeof(
typename props::Scalar);
248 a =
array({src.size()}, {elem_size * src.innerStride()}, src.data(),
base);
250 a =
array({src.rows(), src.cols()},
251 {elem_size * src.rowStride(), elem_size * src.colStride()},
267template <
typename props,
typename Type>
271 return eigen_array_cast<props>(src, parent, !std::is_const<Type>::value);
278template <typename props, typename Type, typename = enable_if_t<is_eigen_dense_plain<Type>::value>>
280 capsule base(src, [](
void *o) {
delete static_cast<Type *
>(o); });
281 return eigen_ref_array<props>(*src,
base);
286template <
typename Type>
304 auto dims = buf.ndim();
305 if (dims < 1 || dims > 2) {
309 auto fits = props::conformable(buf);
315 value = Type(fits.rows, fits.cols);
316 auto ref = reinterpret_steal<array>(eigen_ref_array<props>(
value));
319 }
else if (
ref.ndim() == 1) {
323 int result = detail::npy_api::get().PyArray_CopyInto_(
ref.ptr(), buf.ptr());
335 template <
typename CType>
338 case return_value_policy::take_ownership:
339 case return_value_policy::automatic:
340 return eigen_encapsulate<props>(src);
341 case return_value_policy::move:
342 return eigen_encapsulate<props>(
new CType(std::move(*src)));
343 case return_value_policy::copy:
344 return eigen_array_cast<props>(*src);
345 case return_value_policy::reference:
346 case return_value_policy::automatic_reference:
347 return eigen_ref_array<props>(*src);
348 case return_value_policy::reference_internal:
349 return eigen_ref_array<props>(*src, parent);
351 throw cast_error(
"unhandled return_value_policy: should not happen!");
358 return cast_impl(&src, return_value_policy::move, parent);
362 return cast_impl(&src, return_value_policy::move, parent);
366 if (policy == return_value_policy::automatic
367 || policy == return_value_policy::automatic_reference) {
368 policy = return_value_policy::copy;
370 return cast_impl(&src, policy, parent);
374 if (policy == return_value_policy::automatic
375 || policy == return_value_policy::automatic_reference) {
376 policy = return_value_policy::copy;
378 return cast(&src, policy, parent);
382 return cast_impl(src, policy, parent);
386 return cast_impl(src, policy, parent);
389 static constexpr auto name = props::descriptor;
392 operator Type *() {
return &
value; }
396 operator Type &&() && {
return std::move(
value); }
397 template <
typename T>
405template <
typename MapType>
419 case return_value_policy::copy:
420 return eigen_array_cast<props>(src);
421 case return_value_policy::reference_internal:
423 case return_value_policy::reference:
424 case return_value_policy::automatic:
425 case return_value_policy::automatic_reference:
429 pybind11_fail(
"Invalid return_value_policy for Eigen Map/Ref/Block type");
439 operator MapType() =
delete;
445template <
typename Type>
450template <
typename PlainObjectType,
typename Str
ideType>
452 Eigen::Ref<PlainObjectType, 0, StrideType>,
453 enable_if_t<is_eigen_dense_map<Eigen::Ref<PlainObjectType, 0, StrideType>>::value>>
456 using Type = Eigen::Ref<PlainObjectType, 0, StrideType>;
459 using MapType = Eigen::Map<PlainObjectType, 0, StrideType>;
463 | ((props::row_major ? props::inner_stride : props::outer_stride) == 1
465 : (props::row_major ? props::outer_stride : props::inner_stride) == 1
470 std::unique_ptr<MapType>
map;
471 std::unique_ptr<Type>
ref;
484 bool need_copy = !isinstance<Array>(src);
490 auto aref = reinterpret_borrow<Array>(src);
492 if (aref && (!need_writeable || aref.writeable())) {
493 fits = props::conformable(aref);
497 if (!fits.template stride_compatible<props>()) {
500 copy_or_ref = std::move(aref);
511 if (!convert || need_writeable) {
519 fits = props::conformable(
copy);
520 if (!fits || !fits.template stride_compatible<props>()) {
523 copy_or_ref = std::move(
copy);
531 make_stride(fits.
stride.outer(), fits.
stride.inner())));
541 template <
typename _T>
545 template <typename T = Type, enable_if_t<is_eigen_mutable_map<T>::value,
int> = 0>
550 template <typename T = Type, enable_if_t<!is_eigen_mutable_map<T>::value,
int> = 0>
557 template <
typename S>
559 && S::OuterStrideAtCompileTime != Eigen::Dynamic
560 && std::is_default_constructible<S>::value>;
563 template <
typename S>
566 && std::is_constructible<S, EigenIndex, EigenIndex>::value>;
569 template <
typename S>
572 && S::OuterStrideAtCompileTime == Eigen::Dynamic
573 && S::InnerStrideAtCompileTime != Eigen::Dynamic
574 && std::is_constructible<S, EigenIndex>::value>;
575 template <
typename S>
578 && S::InnerStrideAtCompileTime == Eigen::Dynamic
579 && S::OuterStrideAtCompileTime != Eigen::Dynamic
580 && std::is_constructible<S, EigenIndex>::value>;
582 template <typename S = StrideType, enable_if_t<stride_ctor_default<S>::value,
int> = 0>
586 template <typename S = StrideType, enable_if_t<stride_ctor_dual<S>::value,
int> = 0>
588 return S(outer, inner);
590 template <typename S = StrideType, enable_if_t<stride_ctor_outer<S>::value,
int> = 0>
594 template <typename S = StrideType, enable_if_t<stride_ctor_inner<S>::value,
int> = 0>
604template <
typename Type>
608 = Eigen::Matrix<typename Type::Scalar, Type::RowsAtCompileTime, Type::ColsAtCompileTime>;
617 return cast(*src, policy, parent);
620 static constexpr auto name = props::descriptor;
626 operator Type() =
delete;
631template <
typename Type>
636 static constexpr bool rowMajor = Type::IsRowMajor;
643 auto obj = reinterpret_borrow<object>(src);
645 object matrix_type = sparse_module.attr(rowMajor ?
"csr_matrix" :
"csc_matrix");
649 obj = matrix_type(obj);
658 auto shape = pybind11::tuple((pybind11::object) obj.attr(
"shape"));
659 auto nnz = obj.attr(
"nnz").cast<
Index>();
661 if (!values || !innerIndices || !outerIndices) {
666 Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),
668 shape[1].cast<
Index>(),
670 outerIndices.mutable_data(),
671 innerIndices.mutable_data(),
672 values.mutable_data());
678 const_cast<Type &
>(src).makeCompressed();
681 =
module_::import(
"scipy.sparse").attr(rowMajor ?
"csr_matrix" :
"csc_matrix");
683 array data(src.nonZeros(), src.valuePtr());
684 array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
685 array innerIndices(src.nonZeros(), src.innerIndexPtr());
687 return matrix_type(std::make_tuple(
data, innerIndices, outerIndices),
688 std::make_pair(src.rows(), src.cols()))
693 const_name<(Type::IsRowMajor) != 0>(
"scipy.sparse.csr_matrix[",
694 "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.
all_of< is_template_base_of< Eigen::DenseBase, T >, std::is_base_of< Eigen::MapBase< T, Eigen::ReadOnlyAccessors >, T > > is_eigen_dense_map
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::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
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.
#define PYBIND11_SILENCE_MSVC_C4127(...)
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.
handle eigen_array_cast(typename props::Type const &src, handle base=handle(), bool writeable=true)
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
handle eigen_ref_array(Type &src, handle parent=none())
EIGEN_DEFAULT_DENSE_INDEX_TYPE EigenIndex
Eigen::Stride< Eigen::Dynamic, Eigen::Dynamic > EigenDStride
handle eigen_encapsulate(Type *src)
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)
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)
std::unique_ptr< Type > ref
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
std::unique_ptr< MapType > map
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)