Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • jcarpent/eigenpy
  • gsaurel/eigenpy
  • stack-of-tasks/eigenpy
3 results
Select Git revision
Show changes
Showing
with 1152 additions and 297 deletions
/*
* Copyright 2024 INRIA
*/
#ifndef __eigenpy_decomposition_sparse_accelerate_accelerate_hpp__
#define __eigenpy_decomposition_sparse_accelerate_accelerate_hpp__
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/eigen/EigenBase.hpp"
#include "eigenpy/decompositions/sparse/SparseSolverBase.hpp"
#include <Eigen/AccelerateSupport>
namespace eigenpy {
template <typename AccelerateDerived>
struct AccelerateImplVisitor : public boost::python::def_visitor<
AccelerateImplVisitor<AccelerateDerived>> {
typedef AccelerateDerived Solver;
typedef typename AccelerateDerived::MatrixType MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef MatrixType CholMatrixType;
typedef typename MatrixType::StorageIndex StorageIndex;
template <class PyClass>
void visit(PyClass &cl) const {
cl
.def("analyzePattern", &Solver::analyzePattern,
bp::args("self", "matrix"),
"Performs a symbolic decomposition on the sparcity of matrix.\n"
"This function is particularly useful when solving for several "
"problems having the same structure.")
.def(EigenBaseVisitor<Solver>())
.def(SparseSolverBaseVisitor<Solver>())
.def("compute",
(Solver & (Solver::*)(const MatrixType &matrix)) & Solver::compute,
bp::args("self", "matrix"),
"Computes the sparse Cholesky decomposition of a given matrix.",
bp::return_self<>())
.def("factorize", &Solver::factorize, bp::args("self", "matrix"),
"Performs a numeric decomposition of a given matrix.\n"
"The given matrix must has the same sparcity than the matrix on "
"which the symbolic decomposition has been performed.\n"
"See also analyzePattern().")
.def("info", &Solver::info, bp::arg("self"),
"NumericalIssue if the input contains INF or NaN values or "
"overflow occured. Returns Success otherwise.")
.def("setOrder", &Solver::setOrder, bp::arg("self"), "Set order");
}
static void expose(const std::string &name, const std::string &doc = "") {
bp::class_<Solver, boost::noncopyable>(name.c_str(), doc.c_str(),
bp::no_init)
.def(AccelerateImplVisitor())
.def(bp::init<>(bp::arg("self"), "Default constructor"))
.def(bp::init<MatrixType>(bp::args("self", "matrix"),
"Constructs and performs the "
"factorization from a given matrix."));
}
};
} // namespace eigenpy
#endif // ifndef __eigenpy_decomposition_sparse_accelerate_accelerate_hpp__
/*
* Copyright 2024 INRIA
*/
#ifndef __eigenpy_decomposition_sparse_cholmod_cholmod_base_hpp__
#define __eigenpy_decomposition_sparse_cholmod_cholmod_base_hpp__
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/eigen/EigenBase.hpp"
#include "eigenpy/decompositions/sparse/SparseSolverBase.hpp"
#include <Eigen/CholmodSupport>
namespace eigenpy {
template <typename CholdmodDerived>
struct CholmodBaseVisitor
: public boost::python::def_visitor<CholmodBaseVisitor<CholdmodDerived>> {
typedef CholdmodDerived Solver;
typedef typename CholdmodDerived::MatrixType MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef MatrixType CholMatrixType;
typedef typename MatrixType::StorageIndex StorageIndex;
template <class PyClass>
void visit(PyClass &cl) const {
cl.def("analyzePattern", &Solver::analyzePattern,
bp::args("self", "matrix"),
"Performs a symbolic decomposition on the sparcity of matrix.\n"
"This function is particularly useful when solving for several "
"problems having the same structure.")
.def(EigenBaseVisitor<Solver>())
.def(SparseSolverBaseVisitor<Solver>())
.def("compute",
(Solver & (Solver::*)(const MatrixType &matrix)) & Solver::compute,
bp::args("self", "matrix"),
"Computes the sparse Cholesky decomposition of a given matrix.",
bp::return_self<>())
.def("determinant", &Solver::determinant, bp::arg("self"),
"Returns the determinant of the underlying matrix from the "
"current factorization.")
.def("factorize", &Solver::factorize, bp::args("self", "matrix"),
"Performs a numeric decomposition of a given matrix.\n"
"The given matrix must has the same sparcity than the matrix on "
"which the symbolic decomposition has been performed.\n"
"See also analyzePattern().")
.def("info", &Solver::info, bp::arg("self"),
"NumericalIssue if the input contains INF or NaN values or "
"overflow occured. Returns Success otherwise.")
.def("logDeterminant", &Solver::logDeterminant, bp::arg("self"),
"Returns the log determinant of the underlying matrix from the "
"current factorization.")
.def("setShift", &Solver::setShift, (bp::args("self", "offset")),
"Sets the shift parameters that will be used to adjust the "
"diagonal coefficients during the numerical factorization.\n"
"During the numerical factorization, the diagonal coefficients "
"are transformed by the following linear model: d_ii = offset + "
"d_ii.\n"
"The default is the identity transformation with offset=0.",
bp::return_self<>());
}
};
} // namespace eigenpy
#endif // ifndef __eigenpy_decomposition_sparse_cholmod_cholmod_base_hpp__
/*
* Copyright 2024 INRIA
*/
#ifndef __eigenpy_decomposition_sparse_cholmod_cholmod_decomposition_hpp__
#define __eigenpy_decomposition_sparse_cholmod_cholmod_decomposition_hpp__
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/decompositions/sparse/cholmod/CholmodBase.hpp"
namespace eigenpy {
template <typename CholdmodDerived>
struct CholmodDecompositionVisitor
: public boost::python::def_visitor<
CholmodDecompositionVisitor<CholdmodDerived>> {
typedef CholdmodDerived Solver;
template <class PyClass>
void visit(PyClass &cl) const {
cl
.def(CholmodBaseVisitor<Solver>())
.def("setMode", &Solver::setMode, bp::args("self", "mode"),
"Set the mode for the Cholesky decomposition.");
}
};
} // namespace eigenpy
#endif // ifndef
// __eigenpy_decomposition_sparse_cholmod_cholmod_decomposition_hpp__
/*
* Copyright 2024 INRIA
*/
#ifndef __eigenpy_decomposition_sparse_cholmod_cholmod_simplicial_ldlt_hpp__
#define __eigenpy_decomposition_sparse_cholmod_cholmod_simplicial_ldlt_hpp__
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/decompositions/sparse/cholmod/CholmodDecomposition.hpp"
#include "eigenpy/utils/scalar-name.hpp"
namespace eigenpy {
template <typename MatrixType_, int UpLo_ = Eigen::Lower>
struct CholmodSimplicialLDLTVisitor
: public boost::python::def_visitor<
CholmodSimplicialLDLTVisitor<MatrixType_, UpLo_>> {
typedef MatrixType_ MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef Eigen::CholmodSimplicialLDLT<MatrixType_, UpLo_> Solver;
template <class PyClass>
void visit(PyClass &cl) const {
cl
.def(CholmodBaseVisitor<Solver>())
.def(bp::init<>(bp::arg("self"), "Default constructor"))
.def(bp::init<MatrixType>(bp::args("self", "matrix"),
"Constructs and performs the LDLT "
"factorization from a given matrix."))
;
}
static void expose() {
static const std::string classname =
"CholmodSimplicialLDLT_" + scalar_name<Scalar>::shortname();
expose(classname);
}
static void expose(const std::string &name) {
bp::class_<Solver, boost::noncopyable>(
name.c_str(),
"A simplicial direct Cholesky (LDLT) factorization and solver based on "
"Cholmod.\n\n"
"This class allows to solve for A.X = B sparse linear problems via a "
"simplicial LL^T Cholesky factorization using the Cholmod library."
"This simplicial variant is equivalent to Eigen's built-in "
"SimplicialLDLT class."
"Therefore, it has little practical interest. The sparse matrix A must "
"be selfadjoint and positive definite."
"The vectors or matrices X and B can be either dense or sparse.",
bp::no_init)
.def(CholmodSimplicialLDLTVisitor());
}
};
} // namespace eigenpy
#endif // ifndef
// __eigenpy_decomposition_sparse_cholmod_cholmod_simplicial_ldlt_hpp__
/*
* Copyright 2024 INRIA
*/
#ifndef __eigenpy_decomposition_sparse_cholmod_cholmod_simplicial_llt_hpp__
#define __eigenpy_decomposition_sparse_cholmod_cholmod_simplicial_llt_hpp__
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/decompositions/sparse/cholmod/CholmodDecomposition.hpp"
#include "eigenpy/utils/scalar-name.hpp"
namespace eigenpy {
template <typename MatrixType_, int UpLo_ = Eigen::Lower>
struct CholmodSimplicialLLTVisitor
: public boost::python::def_visitor<
CholmodSimplicialLLTVisitor<MatrixType_, UpLo_>> {
typedef MatrixType_ MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef Eigen::CholmodSimplicialLLT<MatrixType_, UpLo_> Solver;
template <class PyClass>
void visit(PyClass &cl) const {
cl
.def(CholmodBaseVisitor<Solver>())
.def(bp::init<>(bp::arg("self"), "Default constructor"))
.def(bp::init<MatrixType>(bp::args("self", "matrix"),
"Constructs and performs the LLT "
"factorization from a given matrix."))
;
}
static void expose() {
static const std::string classname =
"CholmodSimplicialLLT_" + scalar_name<Scalar>::shortname();
expose(classname);
}
static void expose(const std::string &name) {
bp::class_<Solver, boost::noncopyable>(
name.c_str(),
"A simplicial direct Cholesky (LLT) factorization and solver based on "
"Cholmod.\n\n"
"This class allows to solve for A.X = B sparse linear problems via a "
"simplicial LL^T Cholesky factorization using the Cholmod library."
"This simplicial variant is equivalent to Eigen's built-in "
"SimplicialLLT class."
"Therefore, it has little practical interest. The sparse matrix A must "
"be selfadjoint and positive definite."
"The vectors or matrices X and B can be either dense or sparse.",
bp::no_init)
.def(CholmodSimplicialLLTVisitor());
}
};
} // namespace eigenpy
#endif // ifndef
// __eigenpy_decomposition_sparse_cholmod_cholmod_simplicial_llt_hpp__
/*
* Copyright 2024 INRIA
*/
#ifndef __eigenpy_decomposition_sparse_cholmod_cholmod_supernodal_llt_hpp__
#define __eigenpy_decomposition_sparse_cholmod_cholmod_supernodal_llt_hpp__
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/decompositions/sparse/cholmod/CholmodDecomposition.hpp"
#include "eigenpy/utils/scalar-name.hpp"
namespace eigenpy {
template <typename MatrixType_, int UpLo_ = Eigen::Lower>
struct CholmodSupernodalLLTVisitor
: public boost::python::def_visitor<
CholmodSupernodalLLTVisitor<MatrixType_, UpLo_>> {
typedef MatrixType_ MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef Eigen::CholmodSupernodalLLT<MatrixType_, UpLo_> Solver;
template <class PyClass>
void visit(PyClass &cl) const {
cl
.def(CholmodBaseVisitor<Solver>())
.def(bp::init<>(bp::arg("self"), "Default constructor"))
.def(bp::init<MatrixType>(bp::args("self", "matrix"),
"Constructs and performs the LLT "
"factorization from a given matrix."))
;
}
static void expose() {
static const std::string classname =
"CholmodSupernodalLLT_" + scalar_name<Scalar>::shortname();
expose(classname);
}
static void expose(const std::string &name) {
bp::class_<Solver, boost::noncopyable>(
name.c_str(),
"A supernodal direct Cholesky (LLT) factorization and solver based on "
"Cholmod.\n\n"
"This class allows to solve for A.X = B sparse linear problems via a "
"supernodal LL^T Cholesky factorization using the Cholmod library."
"This supernodal variant performs best on dense enough problems, e.g., "
"3D FEM, or very high order 2D FEM."
"The sparse matrix A must be selfadjoint and positive definite. The "
"vectors or matrices X and B can be either dense or sparse.",
bp::no_init)
.def(CholmodSupernodalLLTVisitor());
}
};
} // namespace eigenpy
#endif // ifndef
// __eigenpy_decomposition_sparse_cholmod_cholmod_supernodal_llt_hpp__
//
// Copyright (C) 2020 INRIA
// Copyright (C) 2024 LAAS-CNRS, INRIA
//
#ifndef __eigenpy_deprecation_hpp__
#define __eigenpy_deprecation_hpp__
#include "eigenpy/fwd.hpp"
namespace eigenpy {
enum class DeprecationType { DEPRECATION, FUTURE };
namespace detail {
inline PyObject *deprecationTypeToPyObj(DeprecationType dep) {
switch (dep) {
case DeprecationType::DEPRECATION:
return PyExc_DeprecationWarning;
case DeprecationType::FUTURE:
return PyExc_FutureWarning;
default: // The switch handles all cases explicitly, this should never be
// triggered.
throw std::invalid_argument(
"Undefined DeprecationType - this should never be triggered.");
}
}
} // namespace detail
/// @brief A Boost.Python call policy which triggers a Python warning on
/// precall.
template <DeprecationType deprecation_type = DeprecationType::DEPRECATION,
class BasePolicy = bp::default_call_policies>
struct deprecation_warning_policy : BasePolicy {
using result_converter = typename BasePolicy::result_converter;
using argument_package = typename BasePolicy::argument_package;
deprecation_warning_policy(const std::string &warning_msg)
: BasePolicy(), m_what(warning_msg) {}
std::string what() const { return m_what; }
const BasePolicy *derived() const {
return static_cast<const BasePolicy *>(this);
}
template <class ArgPackage>
bool precall(const ArgPackage &args) const {
PyErr_WarnEx(detail::deprecationTypeToPyObj(deprecation_type),
m_what.c_str(), 1);
return derived()->precall(args);
}
protected:
const std::string m_what;
};
template <DeprecationType deprecation_type = DeprecationType::DEPRECATION,
class BasePolicy = bp::default_call_policies>
struct deprecated_function
: deprecation_warning_policy<deprecation_type, BasePolicy> {
deprecated_function(const std::string &msg =
"This function has been marked as deprecated, and "
"will be removed in the future.")
: deprecation_warning_policy<deprecation_type, BasePolicy>(msg) {}
};
template <DeprecationType deprecation_type = DeprecationType::DEPRECATION,
class BasePolicy = bp::default_call_policies>
struct deprecated_member
: deprecation_warning_policy<deprecation_type, BasePolicy> {
deprecated_member(const std::string &msg =
"This attribute or method has been marked as "
"deprecated, and will be removed in the future.")
: deprecation_warning_policy<deprecation_type, BasePolicy>(msg) {}
};
} // namespace eigenpy
#endif // ifndef __eigenpy_deprecation_hpp__
/* /*
* Copyright 2014-2019, CNRS * Copyright 2014-2019, CNRS
* Copyright 2018-2023, INRIA * Copyright 2018-2024, INRIA
*/ */
#ifndef __eigenpy_details_hpp__ #ifndef __eigenpy_details_hpp__
...@@ -31,8 +31,8 @@ struct expose_eigen_type_impl<MatType, Eigen::MatrixBase<MatType>, Scalar> { ...@@ -31,8 +31,8 @@ struct expose_eigen_type_impl<MatType, Eigen::MatrixBase<MatType>, Scalar> {
// to-python // to-python
EigenToPyConverter<MatType>::registration(); EigenToPyConverter<MatType>::registration();
#if EIGEN_VERSION_AT_LEAST(3, 2, 0) #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
EigenToPyConverter<Eigen::Ref<MatType> >::registration(); EigenToPyConverter<Eigen::Ref<MatType>>::registration();
EigenToPyConverter<const Eigen::Ref<const MatType> >::registration(); EigenToPyConverter<const Eigen::Ref<const MatType>>::registration();
#endif #endif
// from-python // from-python
...@@ -40,6 +40,24 @@ struct expose_eigen_type_impl<MatType, Eigen::MatrixBase<MatType>, Scalar> { ...@@ -40,6 +40,24 @@ struct expose_eigen_type_impl<MatType, Eigen::MatrixBase<MatType>, Scalar> {
} }
}; };
template <typename MatType, typename Scalar>
struct expose_eigen_type_impl<MatType, Eigen::SparseMatrixBase<MatType>,
Scalar> {
static void run() {
if (check_registration<MatType>()) return;
// to-python
EigenToPyConverter<MatType>::registration();
// #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
// EigenToPyConverter<Eigen::Ref<MatType> >::registration();
// EigenToPyConverter<const Eigen::Ref<const MatType> >::registration();
// #endif
// from-python
EigenFromPyConverter<MatType>::registration();
}
};
#ifdef EIGENPY_WITH_TENSOR_SUPPORT #ifdef EIGENPY_WITH_TENSOR_SUPPORT
template <typename TensorType, typename Scalar> template <typename TensorType, typename Scalar>
struct expose_eigen_type_impl<TensorType, Eigen::TensorBase<TensorType>, struct expose_eigen_type_impl<TensorType, Eigen::TensorBase<TensorType>,
...@@ -49,9 +67,9 @@ struct expose_eigen_type_impl<TensorType, Eigen::TensorBase<TensorType>, ...@@ -49,9 +67,9 @@ struct expose_eigen_type_impl<TensorType, Eigen::TensorBase<TensorType>,
// to-python // to-python
EigenToPyConverter<TensorType>::registration(); EigenToPyConverter<TensorType>::registration();
EigenToPyConverter<Eigen::TensorRef<TensorType> >::registration(); EigenToPyConverter<Eigen::TensorRef<TensorType>>::registration();
EigenToPyConverter< EigenToPyConverter<
const Eigen::TensorRef<const TensorType> >::registration(); const Eigen::TensorRef<const TensorType>>::registration();
// from-python // from-python
EigenFromPyConverter<TensorType>::registration(); EigenFromPyConverter<TensorType>::registration();
......
...@@ -98,7 +98,7 @@ template <typename EigenType, ...@@ -98,7 +98,7 @@ template <typename EigenType,
struct check_swap_impl; struct check_swap_impl;
template <typename MatType> template <typename MatType>
struct check_swap_impl<MatType, Eigen::MatrixBase<MatType> > struct check_swap_impl<MatType, Eigen::MatrixBase<MatType>>
: check_swap_impl_matrix<MatType> {}; : check_swap_impl_matrix<MatType> {};
template <typename MatType> template <typename MatType>
...@@ -127,7 +127,7 @@ struct check_swap_impl_tensor { ...@@ -127,7 +127,7 @@ struct check_swap_impl_tensor {
}; };
template <typename TensorType> template <typename TensorType>
struct check_swap_impl<TensorType, Eigen::TensorBase<TensorType> > struct check_swap_impl<TensorType, Eigen::TensorBase<TensorType>>
: check_swap_impl_tensor<TensorType> {}; : check_swap_impl_tensor<TensorType> {};
#endif #endif
...@@ -198,6 +198,91 @@ struct cast<Scalar, NewScalar, EigenBase, false> { ...@@ -198,6 +198,91 @@ struct cast<Scalar, NewScalar, EigenBase, false> {
mat, NumpyMap<MatType, NewScalar>::map( \ mat, NumpyMap<MatType, NewScalar>::map( \
pyArray, details::check_swap(pyArray, mat))) pyArray, details::check_swap(pyArray, mat)))
// Define specific cast for Windows and Mac
#if defined _WIN32 || defined __CYGWIN__
// Manage NPY_INT on Windows (NPY_INT32 is NPY_LONG).
// See https://github.com/stack-of-tasks/eigenpy/pull/455
#define EIGENPY_CAST_FROM_NUMPY_TO_EIGEN_SWITCH_OS_SPECIFIC( \
MatType, Scalar, pyArray, mat, CAST_MACRO) \
case NPY_INT: \
CAST_MACRO(MatType, int32_t, Scalar, pyArray, mat); \
break; \
case NPY_UINT: \
CAST_MACRO(MatType, uint32_t, Scalar, pyArray, mat); \
break;
#elif defined __APPLE__
// Manage NPY_LONGLONG on Mac (NPY_INT64 is NPY_LONG).
// long long and long are both the same type
// but NPY_LONGLONG and NPY_LONG are different dtype.
// See https://github.com/stack-of-tasks/eigenpy/pull/455
#define EIGENPY_CAST_FROM_NUMPY_TO_EIGEN_SWITCH_OS_SPECIFIC( \
MatType, Scalar, pyArray, mat, CAST_MACRO) \
case NPY_LONGLONG: \
CAST_MACRO(MatType, int64_t, Scalar, pyArray, mat); \
break; \
case NPY_ULONGLONG: \
CAST_MACRO(MatType, uint64_t, Scalar, pyArray, mat); \
break;
#else
#define EIGENPY_CAST_FROM_NUMPY_TO_EIGEN_SWITCH_OS_SPECIFIC( \
MatType, Scalar, pyArray, mat, CAST_MACRO)
#endif
/// Define casting between Numpy matrix type to Eigen type.
#define EIGENPY_CAST_FROM_NUMPY_TO_EIGEN_SWITCH( \
pyArray_type_code, MatType, Scalar, pyArray, mat, CAST_MACRO) \
switch (pyArray_type_code) { \
case NPY_BOOL: \
CAST_MACRO(MatType, bool, Scalar, pyArray, mat); \
break; \
case NPY_INT8: \
CAST_MACRO(MatType, int8_t, Scalar, pyArray, mat); \
break; \
case NPY_INT16: \
CAST_MACRO(MatType, int16_t, Scalar, pyArray, mat); \
break; \
case NPY_INT32: \
CAST_MACRO(MatType, int32_t, Scalar, pyArray, mat); \
break; \
case NPY_INT64: \
CAST_MACRO(MatType, int64_t, Scalar, pyArray, mat); \
break; \
case NPY_UINT8: \
CAST_MACRO(MatType, uint8_t, Scalar, pyArray, mat); \
break; \
case NPY_UINT16: \
CAST_MACRO(MatType, uint16_t, Scalar, pyArray, mat); \
break; \
case NPY_UINT32: \
CAST_MACRO(MatType, uint32_t, Scalar, pyArray, mat); \
break; \
case NPY_UINT64: \
CAST_MACRO(MatType, uint64_t, Scalar, pyArray, mat); \
break; \
case NPY_FLOAT: \
CAST_MACRO(MatType, float, Scalar, pyArray, mat); \
break; \
case NPY_CFLOAT: \
CAST_MACRO(MatType, std::complex<float>, Scalar, pyArray, mat); \
break; \
case NPY_DOUBLE: \
CAST_MACRO(MatType, double, Scalar, pyArray, mat); \
break; \
case NPY_CDOUBLE: \
CAST_MACRO(MatType, std::complex<double>, Scalar, pyArray, mat); \
break; \
case NPY_LONGDOUBLE: \
CAST_MACRO(MatType, long double, Scalar, pyArray, mat); \
break; \
case NPY_CLONGDOUBLE: \
CAST_MACRO(MatType, std::complex<long double>, Scalar, pyArray, mat); \
break; \
EIGENPY_CAST_FROM_NUMPY_TO_EIGEN_SWITCH_OS_SPECIFIC( \
MatType, Scalar, pyArray, mat, CAST_MACRO) \
default: \
throw Exception("You asked for a conversion which is not implemented."); \
}
template <typename EigenType> template <typename EigenType>
struct EigenAllocator; struct EigenAllocator;
...@@ -209,11 +294,11 @@ template <typename MatType> ...@@ -209,11 +294,11 @@ template <typename MatType>
struct eigen_allocator_impl_matrix; struct eigen_allocator_impl_matrix;
template <typename MatType> template <typename MatType>
struct eigen_allocator_impl<MatType, Eigen::MatrixBase<MatType> > struct eigen_allocator_impl<MatType, Eigen::MatrixBase<MatType>>
: eigen_allocator_impl_matrix<MatType> {}; : eigen_allocator_impl_matrix<MatType> {};
template <typename MatType> template <typename MatType>
struct eigen_allocator_impl<const MatType, const Eigen::MatrixBase<MatType> > struct eigen_allocator_impl<const MatType, const Eigen::MatrixBase<MatType>>
: eigen_allocator_impl_matrix<const MatType> {}; : eigen_allocator_impl_matrix<const MatType> {};
template <typename MatType> template <typename MatType>
...@@ -247,43 +332,9 @@ struct eigen_allocator_impl_matrix { ...@@ -247,43 +332,9 @@ struct eigen_allocator_impl_matrix {
pyArray, details::check_swap(pyArray, mat)); // avoid useless cast pyArray, details::check_swap(pyArray, mat)); // avoid useless cast
return; return;
} }
EIGENPY_CAST_FROM_NUMPY_TO_EIGEN_SWITCH(
switch (pyArray_type_code) { pyArray_type_code, MatType, Scalar, pyArray, mat,
case NPY_INT: EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX);
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, int, Scalar, pyArray,
mat);
break;
case NPY_LONG:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, long, Scalar,
pyArray, mat);
break;
case NPY_FLOAT:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, float, Scalar,
pyArray, mat);
break;
case NPY_CFLOAT:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, std::complex<float>,
Scalar, pyArray, mat);
break;
case NPY_DOUBLE:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, double, Scalar,
pyArray, mat);
break;
case NPY_CDOUBLE:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, std::complex<double>,
Scalar, pyArray, mat);
break;
case NPY_LONGDOUBLE:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, long double, Scalar,
pyArray, mat);
break;
case NPY_CLONGDOUBLE:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(
MatType, std::complex<long double>, Scalar, pyArray, mat);
break;
default:
throw Exception("You asked for a conversion which is not implemented.");
}
} }
/// \brief Copy mat into the Python array using Eigen::Map /// \brief Copy mat into the Python array using Eigen::Map
...@@ -301,43 +352,8 @@ struct eigen_allocator_impl_matrix { ...@@ -301,43 +352,8 @@ struct eigen_allocator_impl_matrix {
details::check_swap(pyArray, mat)) = mat; details::check_swap(pyArray, mat)) = mat;
return; return;
} }
throw Exception(
switch (pyArray_type_code) { "Scalar conversion from Eigen to Numpy is not implemented.");
case NPY_INT:
EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(MatType, Scalar, int, mat,
pyArray);
break;
case NPY_LONG:
EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(MatType, Scalar, long, mat,
pyArray);
break;
case NPY_FLOAT:
EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(MatType, Scalar, float, mat,
pyArray);
break;
case NPY_CFLOAT:
EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(
MatType, Scalar, std::complex<float>, mat, pyArray);
break;
case NPY_DOUBLE:
EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(MatType, Scalar, double, mat,
pyArray);
break;
case NPY_CDOUBLE:
EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(
MatType, Scalar, std::complex<double>, mat, pyArray);
break;
case NPY_LONGDOUBLE:
EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(MatType, Scalar, long double,
mat, pyArray);
break;
case NPY_CLONGDOUBLE:
EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(
MatType, Scalar, std::complex<long double>, mat, pyArray);
break;
default:
throw Exception("You asked for a conversion which is not implemented.");
}
} }
}; };
...@@ -346,12 +362,12 @@ template <typename TensorType> ...@@ -346,12 +362,12 @@ template <typename TensorType>
struct eigen_allocator_impl_tensor; struct eigen_allocator_impl_tensor;
template <typename TensorType> template <typename TensorType>
struct eigen_allocator_impl<TensorType, Eigen::TensorBase<TensorType> > struct eigen_allocator_impl<TensorType, Eigen::TensorBase<TensorType>>
: eigen_allocator_impl_tensor<TensorType> {}; : eigen_allocator_impl_tensor<TensorType> {};
template <typename TensorType> template <typename TensorType>
struct eigen_allocator_impl<const TensorType, struct eigen_allocator_impl<const TensorType,
const Eigen::TensorBase<TensorType> > const Eigen::TensorBase<TensorType>>
: eigen_allocator_impl_tensor<const TensorType> {}; : eigen_allocator_impl_tensor<const TensorType> {};
template <typename TensorType> template <typename TensorType>
...@@ -394,42 +410,9 @@ struct eigen_allocator_impl_tensor { ...@@ -394,42 +410,9 @@ struct eigen_allocator_impl_tensor {
return; return;
} }
switch (pyArray_type_code) { EIGENPY_CAST_FROM_NUMPY_TO_EIGEN_SWITCH(
case NPY_INT: pyArray_type_code, TensorType, Scalar, pyArray, tensor,
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR(TensorType, int, Scalar, EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR);
pyArray, tensor);
break;
case NPY_LONG:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR(TensorType, long, Scalar,
pyArray, tensor);
break;
case NPY_FLOAT:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR(TensorType, float, Scalar,
pyArray, tensor);
break;
case NPY_CFLOAT:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR(
TensorType, std::complex<float>, Scalar, pyArray, tensor);
break;
case NPY_DOUBLE:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR(TensorType, double, Scalar,
pyArray, tensor);
break;
case NPY_CDOUBLE:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR(
TensorType, std::complex<double>, Scalar, pyArray, tensor);
break;
case NPY_LONGDOUBLE:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR(TensorType, long double,
Scalar, pyArray, tensor);
break;
case NPY_CLONGDOUBLE:
EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_TENSOR(
TensorType, std::complex<long double>, Scalar, pyArray, tensor);
break;
default:
throw Exception("You asked for a conversion which is not implemented.");
}
} }
#define EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(TensorType, Scalar, \ #define EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(TensorType, Scalar, \
...@@ -454,42 +437,8 @@ struct eigen_allocator_impl_tensor { ...@@ -454,42 +437,8 @@ struct eigen_allocator_impl_tensor {
return; return;
} }
switch (pyArray_type_code) { throw Exception(
case NPY_INT: "Scalar conversion from Eigen to Numpy is not implemented.");
EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(TensorType, Scalar, int,
tensor, pyArray);
break;
case NPY_LONG:
EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(TensorType, Scalar, long,
tensor, pyArray);
break;
case NPY_FLOAT:
EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(TensorType, Scalar, float,
tensor, pyArray);
break;
case NPY_CFLOAT:
EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(
TensorType, Scalar, std::complex<float>, tensor, pyArray);
break;
case NPY_DOUBLE:
EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(TensorType, Scalar, double,
tensor, pyArray);
break;
case NPY_CDOUBLE:
EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(
TensorType, Scalar, std::complex<double>, tensor, pyArray);
break;
case NPY_LONGDOUBLE:
EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(TensorType, Scalar,
long double, tensor, pyArray);
break;
case NPY_CLONGDOUBLE:
EIGENPY_CAST_FROM_EIGEN_TENSOR_TO_PYARRAY(
TensorType, Scalar, std::complex<long double>, tensor, pyArray);
break;
default:
throw Exception("You asked for a conversion which is not implemented.");
}
} }
}; };
#endif #endif
...@@ -513,7 +462,7 @@ inline bool is_arr_layout_compatible_with_mat_type(PyArrayObject *pyArray) { ...@@ -513,7 +462,7 @@ inline bool is_arr_layout_compatible_with_mat_type(PyArrayObject *pyArray) {
} }
template <typename MatType, int Options, typename Stride> template <typename MatType, int Options, typename Stride>
struct eigen_allocator_impl_matrix<Eigen::Ref<MatType, Options, Stride> > { struct eigen_allocator_impl_matrix<Eigen::Ref<MatType, Options, Stride>> {
typedef Eigen::Ref<MatType, Options, Stride> RefType; typedef Eigen::Ref<MatType, Options, Stride> RefType;
typedef typename MatType::Scalar Scalar; typedef typename MatType::Scalar Scalar;
...@@ -574,7 +523,7 @@ struct eigen_allocator_impl_matrix<Eigen::Ref<MatType, Options, Stride> > { ...@@ -574,7 +523,7 @@ struct eigen_allocator_impl_matrix<Eigen::Ref<MatType, Options, Stride> > {
template <typename MatType, int Options, typename Stride> template <typename MatType, int Options, typename Stride>
struct eigen_allocator_impl_matrix< struct eigen_allocator_impl_matrix<
const Eigen::Ref<const MatType, Options, Stride> > { const Eigen::Ref<const MatType, Options, Stride>> {
typedef const Eigen::Ref<const MatType, Options, Stride> RefType; typedef const Eigen::Ref<const MatType, Options, Stride> RefType;
typedef typename MatType::Scalar Scalar; typedef typename MatType::Scalar Scalar;
...@@ -641,14 +590,14 @@ template <typename TensorType, typename TensorRef> ...@@ -641,14 +590,14 @@ template <typename TensorType, typename TensorRef>
struct eigen_allocator_impl_tensor_ref; struct eigen_allocator_impl_tensor_ref;
template <typename TensorType> template <typename TensorType>
struct eigen_allocator_impl_tensor<Eigen::TensorRef<TensorType> > struct eigen_allocator_impl_tensor<Eigen::TensorRef<TensorType>>
: eigen_allocator_impl_tensor_ref<TensorType, : eigen_allocator_impl_tensor_ref<TensorType,
Eigen::TensorRef<TensorType> > {}; Eigen::TensorRef<TensorType>> {};
template <typename TensorType> template <typename TensorType>
struct eigen_allocator_impl_tensor<const Eigen::TensorRef<const TensorType> > struct eigen_allocator_impl_tensor<const Eigen::TensorRef<const TensorType>>
: eigen_allocator_impl_tensor_ref< : eigen_allocator_impl_tensor_ref<
const TensorType, const Eigen::TensorRef<const TensorType> > {}; const TensorType, const Eigen::TensorRef<const TensorType>> {};
template <typename TensorType, typename RefType> template <typename TensorType, typename RefType>
struct eigen_allocator_impl_tensor_ref { struct eigen_allocator_impl_tensor_ref {
......
...@@ -17,7 +17,7 @@ template <typename EigenType, ...@@ -17,7 +17,7 @@ template <typename EigenType,
struct expected_pytype_for_arg {}; struct expected_pytype_for_arg {};
template <typename MatType> template <typename MatType>
struct expected_pytype_for_arg<MatType, Eigen::MatrixBase<MatType> > { struct expected_pytype_for_arg<MatType, Eigen::MatrixBase<MatType>> {
static PyTypeObject const *get_pytype() { static PyTypeObject const *get_pytype() {
PyTypeObject const *py_type = eigenpy::getPyArrayType(); PyTypeObject const *py_type = eigenpy::getPyArrayType();
return py_type; return py_type;
...@@ -33,9 +33,9 @@ namespace converter { ...@@ -33,9 +33,9 @@ namespace converter {
template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, template <typename Scalar, int Rows, int Cols, int Options, int MaxRows,
int MaxCols> int MaxCols>
struct expected_pytype_for_arg< struct expected_pytype_for_arg<
Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
: eigenpy::expected_pytype_for_arg< : eigenpy::expected_pytype_for_arg<
Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > {}; Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> {};
} // namespace converter } // namespace converter
} // namespace python } // namespace python
...@@ -62,7 +62,7 @@ struct copy_if_non_const<const MatType, true> { ...@@ -62,7 +62,7 @@ struct copy_if_non_const<const MatType, true> {
template <typename _RefType> template <typename _RefType>
struct referent_storage_eigen_ref { struct referent_storage_eigen_ref {
typedef _RefType RefType; typedef _RefType RefType;
typedef typename get_eigen_ref_plain_type<RefType>::type PlainObjectType; typedef typename get_eigen_plain_type<RefType>::type PlainObjectType;
typedef typename ::eigenpy::aligned_storage< typedef typename ::eigenpy::aligned_storage<
::boost::python::detail::referent_size<RefType &>::value>::type ::boost::python::detail::referent_size<RefType &>::value>::type
AlignedStorage; AlignedStorage;
...@@ -277,7 +277,7 @@ struct eigen_from_py_impl { ...@@ -277,7 +277,7 @@ struct eigen_from_py_impl {
}; };
template <typename MatType> template <typename MatType>
struct eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType> > { struct eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType>> {
typedef typename MatType::Scalar Scalar; typedef typename MatType::Scalar Scalar;
/// \brief Determine if pyObj can be converted into a MatType object /// \brief Determine if pyObj can be converted into a MatType object
...@@ -290,19 +290,13 @@ struct eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType> > { ...@@ -290,19 +290,13 @@ struct eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType> > {
static void registration(); static void registration();
}; };
#ifdef EIGENPY_MSVC_COMPILER template <typename EigenType,
template <typename EigenType> typename Scalar =
struct EigenFromPy<EigenType, typename boost::remove_reference<EigenType>::type::Scalar>
typename boost::remove_reference<EigenType>::type::Scalar> struct EigenFromPy : eigen_from_py_impl<EigenType> {};
#else
template <typename EigenType, typename _Scalar>
struct EigenFromPy
#endif
: eigen_from_py_impl<EigenType> {
};
template <typename MatType> template <typename MatType>
void *eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType> >::convertible( void *eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType>>::convertible(
PyObject *pyObj) { PyObject *pyObj) {
if (!call_PyArray_Check(reinterpret_cast<PyObject *>(pyObj))) return 0; if (!call_PyArray_Check(reinterpret_cast<PyObject *>(pyObj))) return 0;
...@@ -404,13 +398,13 @@ void *eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType> >::convertible( ...@@ -404,13 +398,13 @@ void *eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType> >::convertible(
} }
template <typename MatType> template <typename MatType>
void eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType> >::construct( void eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType>>::construct(
PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) { PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) {
eigen_from_py_construct<MatType>(pyObj, memory); eigen_from_py_construct<MatType>(pyObj, memory);
} }
template <typename MatType> template <typename MatType>
void eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType> >::registration() { void eigen_from_py_impl<MatType, Eigen::MatrixBase<MatType>>::registration() {
bp::converter::registry::push_back( bp::converter::registry::push_back(
reinterpret_cast<void *(*)(_object *)>(&eigen_from_py_impl::convertible), reinterpret_cast<void *(*)(_object *)>(&eigen_from_py_impl::convertible),
&eigen_from_py_impl::construct, bp::type_id<MatType>() &eigen_from_py_impl::construct, bp::type_id<MatType>()
...@@ -429,7 +423,7 @@ template <typename EigenType> ...@@ -429,7 +423,7 @@ template <typename EigenType>
struct EigenFromPyConverter : eigen_from_py_converter_impl<EigenType> {}; struct EigenFromPyConverter : eigen_from_py_converter_impl<EigenType> {};
template <typename MatType> template <typename MatType>
struct eigen_from_py_converter_impl<MatType, Eigen::MatrixBase<MatType> > { struct eigen_from_py_converter_impl<MatType, Eigen::MatrixBase<MatType>> {
static void registration() { static void registration() {
EigenFromPy<MatType>::registration(); EigenFromPy<MatType>::registration();
...@@ -458,7 +452,7 @@ struct eigen_from_py_converter_impl<MatType, Eigen::MatrixBase<MatType> > { ...@@ -458,7 +452,7 @@ struct eigen_from_py_converter_impl<MatType, Eigen::MatrixBase<MatType> > {
}; };
template <typename MatType> template <typename MatType>
struct EigenFromPy<Eigen::MatrixBase<MatType> > : EigenFromPy<MatType> { struct EigenFromPy<Eigen::MatrixBase<MatType>> : EigenFromPy<MatType> {
typedef EigenFromPy<MatType> EigenFromPyDerived; typedef EigenFromPy<MatType> EigenFromPyDerived;
typedef Eigen::MatrixBase<MatType> Base; typedef Eigen::MatrixBase<MatType> Base;
...@@ -493,7 +487,7 @@ struct EigenFromPy<Eigen::EigenBase<MatType>, typename MatType::Scalar> ...@@ -493,7 +487,7 @@ struct EigenFromPy<Eigen::EigenBase<MatType>, typename MatType::Scalar>
}; };
template <typename MatType> template <typename MatType>
struct EigenFromPy<Eigen::PlainObjectBase<MatType> > : EigenFromPy<MatType> { struct EigenFromPy<Eigen::PlainObjectBase<MatType>> : EigenFromPy<MatType> {
typedef EigenFromPy<MatType> EigenFromPyDerived; typedef EigenFromPy<MatType> EigenFromPyDerived;
typedef Eigen::PlainObjectBase<MatType> Base; typedef Eigen::PlainObjectBase<MatType> Base;
...@@ -512,7 +506,7 @@ struct EigenFromPy<Eigen::PlainObjectBase<MatType> > : EigenFromPy<MatType> { ...@@ -512,7 +506,7 @@ struct EigenFromPy<Eigen::PlainObjectBase<MatType> > : EigenFromPy<MatType> {
#if EIGEN_VERSION_AT_LEAST(3, 2, 0) #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
template <typename MatType, int Options, typename Stride> template <typename MatType, int Options, typename Stride>
struct EigenFromPy<Eigen::Ref<MatType, Options, Stride> > { struct EigenFromPy<Eigen::Ref<MatType, Options, Stride>> {
typedef Eigen::Ref<MatType, Options, Stride> RefType; typedef Eigen::Ref<MatType, Options, Stride> RefType;
typedef typename MatType::Scalar Scalar; typedef typename MatType::Scalar Scalar;
...@@ -537,7 +531,7 @@ struct EigenFromPy<Eigen::Ref<MatType, Options, Stride> > { ...@@ -537,7 +531,7 @@ struct EigenFromPy<Eigen::Ref<MatType, Options, Stride> > {
}; };
template <typename MatType, int Options, typename Stride> template <typename MatType, int Options, typename Stride>
struct EigenFromPy<const Eigen::Ref<const MatType, Options, Stride> > { struct EigenFromPy<const Eigen::Ref<const MatType, Options, Stride>> {
typedef const Eigen::Ref<const MatType, Options, Stride> ConstRefType; typedef const Eigen::Ref<const MatType, Options, Stride> ConstRefType;
typedef typename MatType::Scalar Scalar; typedef typename MatType::Scalar Scalar;
...@@ -565,4 +559,6 @@ struct EigenFromPy<const Eigen::Ref<const MatType, Options, Stride> > { ...@@ -565,4 +559,6 @@ struct EigenFromPy<const Eigen::Ref<const MatType, Options, Stride> > {
#include "eigenpy/tensor/eigen-from-python.hpp" #include "eigenpy/tensor/eigen-from-python.hpp"
#endif #endif
#include "eigenpy/sparse/eigen-from-python.hpp"
#endif // __eigenpy_eigen_from_python_hpp__ #endif // __eigenpy_eigen_from_python_hpp__
This diff is collapsed.
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
EIGENPY_MAKE_FIXED_TYPEDEFS(Type, Options, TypeSuffix, 2) \ EIGENPY_MAKE_FIXED_TYPEDEFS(Type, Options, TypeSuffix, 2) \
EIGENPY_MAKE_FIXED_TYPEDEFS(Type, Options, TypeSuffix, 3) \ EIGENPY_MAKE_FIXED_TYPEDEFS(Type, Options, TypeSuffix, 3) \
EIGENPY_MAKE_FIXED_TYPEDEFS(Type, Options, TypeSuffix, 4) \ EIGENPY_MAKE_FIXED_TYPEDEFS(Type, Options, TypeSuffix, 4) \
EIGENPY_MAKE_TYPEDEFS(Type, Options, TypeSuffix, 1, 1) EIGENPY_MAKE_TYPEDEFS(Type, Options, TypeSuffix, 1, 1) \
typedef Eigen::SparseMatrix<Scalar, Options> SparseMatrixX##TypeSuffix
#endif // ifndef __eigenpy_eigen_typedef_hpp__ #endif // ifndef __eigenpy_eigen_typedef_hpp__
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.