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

Target

Select target project
  • jcarpent/eigenpy
  • gsaurel/eigenpy
  • stack-of-tasks/eigenpy
3 results
Show changes
Showing
with 1162 additions and 305 deletions
from __future__ import print_function
import eigenpy
import numpy as np
eigenpy.switchToNumpyMatrix()
quat = eigenpy.Quaternion()
# By default, we convert as numpy.matrix
coeffs_vector = quat.coeffs()
print(type(coeffs_vector))
assert isinstance(coeffs_vector,np.matrixlib.defmatrix.matrix)
assert eigenpy.getNumpyType() == np.matrix
# Switch to numpy.array
eigenpy.switchToNumpyArray()
coeffs_array = quat.coeffs()
print(type(coeffs_array))
assert isinstance(coeffs_vector,np.ndarray)
assert eigenpy.getNumpyType() == np.ndarray
import numpy as np
import tensor
dim = np.array([10, 20, 30], dtype=np.int64)
t = tensor.TensorContainer3(dim)
r = t.get_ref()
r[:] = 0.0
c = t.get_copy()
r2 = tensor.ref(r)
cr = tensor.const_ref(r)
c2 = tensor.copy(cr)
assert np.all(c == r)
assert np.all(r2 == r)
assert np.all(cr == r)
assert np.all(c2 == r)
tensor.print_base(cr)
tensor.print_ref(cr)
tensor.print(cr)
r2[:] = 100.0
assert not np.all(c == r)
assert not np.all(c2 == r)
assert np.all(r2 == r)
assert np.all(cr == r)
tensor.print_base(cr)
tensor.print_ref(cr)
tensor.print(cr)
import type_info
d = type_info.Dummy()
assert "Dummy" in d.type_info().pretty_name()
assert type_info.type_info(1).pretty_name() == "int"
assert "basic_string" in type_info.type_info("toto").pretty_name()
import numpy as np
from user_struct import MyStruct
x = np.ones(3)
y = np.ones(4)
ms = MyStruct(x, y)
print(ms.x)
print(ms.y)
ms.x[0] = 0.0
ms.x = x # ok
assert np.allclose(ms.x, x)
ms.y[:] = y
ms.y = y # segfault
import user_type
import numpy as np import numpy as np
#from packaging import version import user_type
# from packaging import version
rows = 10 rows = 10
cols = 20 cols = 20
def test(dtype): def test(dtype):
mat = np.ones((rows,cols),dtype=dtype) rng = np.random.default_rng()
mat_copy = mat.copy() mat = np.ones((rows, cols), dtype=dtype)
assert (mat == mat_copy).all() mat = rng.random((rows, cols)).astype(dtype)
assert not (mat != mat_copy).all() mat_copy = mat.copy()
assert (mat == mat_copy).all()
# if version.parse(np.__version__) >= version.parse("1.21.0"): # check if it fixes for new versio of NumPy assert not (mat != mat_copy).all()
# mat.fill(mat.dtype.type(20.))
# mat_copy = mat.copy()
# assert((mat == mat_copy).all())
# assert(not (mat != mat_copy).all())
mat_op = mat + mat
mat_op = mat.copy(order='F') + mat.copy(order='C')
mat_op = mat - mat
mat_op = mat * mat
mat_op = mat.dot(mat.T)
mat_op = mat / mat
mat_op = -mat
assert (mat >= mat).all()
assert (mat <= mat).all()
assert not (mat > mat).all()
assert not (mat < mat).all()
mat2 = mat.dot(mat.T)
if np.__version__ >= '1.17.0':
mat2 = np.matmul(mat,mat.T)
def test_cast(from_dtype,to_dtype):
np.can_cast(from_dtype,to_dtype)
from_mat = np.zeros((rows,cols),dtype=from_dtype)
to_mat = from_mat.astype(dtype=to_dtype)
test(user_type.CustomDouble)
test_cast(user_type.CustomDouble,np.double) # if version.parse(np.__version__) >= version.parse("1.21.0"):
test_cast(np.double,user_type.CustomDouble) # # check if it fixes for new version of NumPy
# mat.fill(mat.dtype.type(20.0))
# mat_copy = mat.copy()
# assert (mat == mat_copy).all()
# assert not (mat != mat_copy).all()
test_cast(user_type.CustomDouble,np.int64) mat_op = mat + mat
test_cast(np.int64,user_type.CustomDouble) mat_op = mat.copy(order="F") + mat.copy(order="C")
test_cast(user_type.CustomDouble,np.int32) mat_op = mat - mat
test_cast(np.int32,user_type.CustomDouble) mat_op = mat * mat
mat_op = mat.dot(mat.T)
mat_op = mat / mat
test(user_type.CustomFloat) mat_op = -mat # noqa
assert (mat >= mat).all()
assert (mat <= mat).all()
assert not (mat > mat).all()
assert not (mat < mat).all()
mat2 = mat.dot(mat.T)
mat2_ref = mat.astype(np.double).dot(mat.T.astype(np.double))
assert np.isclose(mat2.astype(np.double), mat2_ref).all()
if np.__version__ >= "1.17.0":
mat2 = np.matmul(mat, mat.T)
assert np.isclose(mat2.astype(np.double), mat2_ref).all()
vec = np.ones((rows,), dtype=dtype)
norm = np.linalg.norm(vec)
norm_ref = np.linalg.norm(vec.astype(np.double))
assert norm == norm_ref
def test_cast(from_dtype, to_dtype):
np.can_cast(from_dtype, to_dtype)
from_mat = np.zeros((rows, cols), dtype=from_dtype)
to_mat = from_mat.astype(dtype=to_dtype) # noqa
test(user_type.CustomDouble)
test_cast(user_type.CustomDouble, np.double)
test_cast(np.double, user_type.CustomDouble)
test_cast(user_type.CustomDouble, np.int64)
test_cast(np.int64, user_type.CustomDouble)
test_cast(user_type.CustomDouble, np.int32)
test_cast(np.int32, user_type.CustomDouble)
v = user_type.CustomDouble(1) v = user_type.CustomDouble(1)
a = np.array(v) a = np.array(v)
assert type(v) == a.dtype.type assert type(v) is a.dtype.type
test(user_type.CustomFloat)
test_cast(user_type.CustomFloat, np.float32)
test_cast(np.double, user_type.CustomFloat)
test_cast(user_type.CustomFloat, np.int64)
test_cast(np.int64, user_type.CustomFloat)
test_cast(user_type.CustomFloat, np.int32)
test_cast(np.int32, user_type.CustomFloat)
import importlib
variant_module = importlib.import_module("@MODNAME@")
V1 = variant_module.V1
V2 = variant_module.V2
VariantHolder = variant_module.VariantHolder
VariantFullHolder = variant_module.VariantFullHolder
make_variant = variant_module.make_variant
make_variant_full_none = variant_module.make_variant_full_none
make_variant_full_float = variant_module.make_variant_full_float
make_variant_full_int = variant_module.make_variant_full_int
make_variant_full_bool = variant_module.make_variant_full_bool
make_variant_full_str = variant_module.make_variant_full_str
make_variant_full_complex = variant_module.make_variant_full_complex
variant = make_variant()
assert isinstance(variant, V1)
v1 = V1()
v1.v = 10
v2 = V2()
v2.v = "c"
variant_holder = VariantHolder()
# Test copy from variant alternative V1 to non initialized variant
variant_holder.variant = v1
assert isinstance(variant_holder.variant, V1)
assert variant_holder.variant.v == v1.v
# variant_holder.variant is a copy of v1
variant_holder.variant.v = 11
assert v1.v != variant_holder.variant.v
# Test variant_holder.variant return by reference
# v1 reference variant_holder.variant
v1 = variant_holder.variant
variant_holder.variant.v = 100
assert variant_holder.variant.v == 100
assert v1.v == 100
v1.v = 1000
assert variant_holder.variant.v == 1000
assert v1.v == 1000
# Test with the second alternative type
variant_holder.variant = v2
assert isinstance(variant_holder.variant, V2)
assert variant_holder.variant.v == v2.v
# Test variant that hold a None value
v_full = make_variant_full_none()
assert v_full is None
# Test variant that hold a float value
v_full = make_variant_full_float()
assert v_full == 3.14
assert isinstance(v_full, float)
# Test variant that hold a int value
v_full = make_variant_full_int()
assert v_full == 3
assert isinstance(v_full, int)
# Test variant that hold a bool value
v_full = make_variant_full_bool()
assert not v_full
assert isinstance(v_full, bool)
# Test variant that hold a str value
v_full = make_variant_full_str()
assert v_full == "str"
assert isinstance(v_full, str)
# Test variant that hold a complex value
v_full = make_variant_full_complex()
assert v_full == 1 + 0j
assert isinstance(v_full, complex)
variant_full_holder = VariantFullHolder()
# Test None
v_none = variant_full_holder.variant
assert v_none is None
variant_full_holder.variant = None
assert v_none is None
# Test V1
v1 = V1()
v1.v = 10
variant_full_holder.variant = v1
assert variant_full_holder.variant.v == 10
assert isinstance(variant_full_holder.variant, V1)
# Test V1 ref
v1 = variant_full_holder.variant
v1.v = 100
assert variant_full_holder.variant.v == 100
variant_full_holder.variant = None
# Test bool
variant_full_holder.variant = True
assert variant_full_holder.variant
assert isinstance(variant_full_holder.variant, bool)
# Test int
variant_full_holder.variant = 3
assert variant_full_holder.variant == 3
assert isinstance(variant_full_holder.variant, int)
# Test float
variant_full_holder.variant = 3.14
assert variant_full_holder.variant == 3.14
assert isinstance(variant_full_holder.variant, float)
# Test str
variant_full_holder.variant = "str"
assert variant_full_holder.variant == "str"
assert isinstance(variant_full_holder.variant, str)
# Test complex
variant_full_holder.variant = 1 + 0j
assert variant_full_holder.variant == 1 + 0j
assert isinstance(variant_full_holder.variant, complex)
from __future__ import print_function
import eigenpy import eigenpy
assert eigenpy.checkVersionAtLeast(0,0,0) assert eigenpy.checkVersionAtLeast(0, 0, 0)
assert eigenpy.__version__ != "" assert eigenpy.__version__ != ""
assert eigenpy.__raw_version__ != "" assert eigenpy.__raw_version__ != ""
...@@ -2,55 +2,49 @@ ...@@ -2,55 +2,49 @@
* Copyright 2020 INRIA * Copyright 2020 INRIA
*/ */
#include "eigenpy/eigenpy.hpp"
#include <iostream> #include <iostream>
template<typename Matrix> #include "eigenpy/eigenpy.hpp"
struct Base
{ template <typename Matrix>
Base(const Eigen::DenseIndex rows, struct Base {
const Eigen::DenseIndex cols) Base(const Eigen::DenseIndex rows, const Eigen::DenseIndex cols)
: mat(rows,cols) : mat(rows, cols) {}
{}
void show() { std::cout << mat << std::endl; }
void show()
{ Matrix& ref() { return mat; }
std::cout << mat << std::endl; const Matrix& const_ref() { return mat; }
} Matrix copy() { return mat; }
Matrix & ref() { return mat; } protected:
const Matrix & const_ref() { return mat; }
Matrix copy() { return mat; }
protected:
Matrix mat; Matrix mat;
}; };
template<typename MatrixType> template <typename MatrixType>
void expose_matrix_class(const std::string & name) void expose_matrix_class(const std::string& name) {
{
using namespace Eigen; using namespace Eigen;
namespace bp = boost::python; namespace bp = boost::python;
bp::class_<Base<MatrixType> >(name.c_str(),bp::init<DenseIndex,DenseIndex>()) bp::class_<Base<MatrixType> >(name.c_str(),
.def("show",&Base<MatrixType>::show) bp::init<DenseIndex, DenseIndex>())
.def("ref",&Base<MatrixType>::ref, bp::return_internal_reference<>()) .def("show", &Base<MatrixType>::show)
.def("const_ref",&Base<MatrixType>::const_ref, bp::return_internal_reference<>()) .def("ref", &Base<MatrixType>::ref, bp::return_internal_reference<>())
.def("copy",&Base<MatrixType>::copy); .def("const_ref", &Base<MatrixType>::const_ref,
bp::return_internal_reference<>())
.def("copy", &Base<MatrixType>::copy);
} }
BOOST_PYTHON_MODULE(return_by_ref) BOOST_PYTHON_MODULE(return_by_ref) {
{
using namespace Eigen; using namespace Eigen;
eigenpy::enableEigenPy(); eigenpy::enableEigenPy();
typedef Eigen::Matrix<double,Eigen::Dynamic,1> VectorType; typedef Eigen::Matrix<double, Eigen::Dynamic, 1> VectorType;
typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> MatrixType; typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> MatrixType;
typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> RowMatrixType; typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
RowMatrixType;
expose_matrix_class<VectorType>("Vector"); expose_matrix_class<VectorType>("Vector");
expose_matrix_class<MatrixType>("Matrix"); expose_matrix_class<MatrixType>("Matrix");
expose_matrix_class<RowMatrixType>("RowMatrix"); expose_matrix_class<RowMatrixType>("RowMatrix");
} }
/*
* Copyright 2024 CNRS INRIA
*/
#include <iostream>
#include "eigenpy/eigenpy.hpp"
template <typename Scalar, int Options>
Eigen::SparseMatrix<Scalar, Options> vector1x1(const Scalar& value) {
typedef Eigen::SparseMatrix<Scalar, Options> ReturnType;
ReturnType mat(1, 1);
mat.coeffRef(0, 0) = value;
mat.makeCompressed();
return mat;
}
template <typename Scalar, int Options>
Eigen::SparseMatrix<Scalar, Options> matrix1x1(const Scalar& value) {
typedef Eigen::SparseMatrix<Scalar, Options> ReturnType;
ReturnType mat(1, 1);
mat.coeffRef(0, 0) = value;
mat.makeCompressed();
return mat;
}
template <typename Scalar, int Options>
Eigen::SparseMatrix<Scalar, Options> diagonal(
const Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, 1> >&
diag_values) {
typedef Eigen::SparseMatrix<Scalar, Options> ReturnType;
ReturnType mat(diag_values.size(), diag_values.size());
for (Eigen::Index k = 0; k < diag_values.size(); ++k)
mat.coeffRef(k, k) = diag_values[k];
mat.makeCompressed();
return mat;
}
template <typename Scalar, int Options>
Eigen::SparseMatrix<Scalar, Options> emptyVector() {
return Eigen::SparseMatrix<Scalar, Options>();
}
template <typename Scalar, int Options>
Eigen::SparseMatrix<Scalar, Options> emptyMatrix() {
return Eigen::SparseMatrix<Scalar, Options>();
}
template <typename Scalar, int Options>
void print(const Eigen::SparseMatrix<Scalar, Options>& mat) {
std::cout << mat << std::endl;
}
template <typename Scalar, int Options>
Eigen::SparseMatrix<Scalar, Options> copy(
const Eigen::SparseMatrix<Scalar, Options>& mat) {
return mat;
}
template <typename Scalar, int Options>
void expose_functions() {
namespace bp = boost::python;
bp::def("vector1x1", vector1x1<Scalar, Options>);
bp::def("matrix1x1", matrix1x1<Scalar, Options>);
bp::def("print", print<Scalar, Options>);
bp::def("copy", copy<Scalar, Options>);
bp::def("diagonal", diagonal<Scalar, Options>);
bp::def("emptyVector", emptyVector<Scalar, Options>);
bp::def("emptyMatrix", emptyMatrix<Scalar, Options>);
}
BOOST_PYTHON_MODULE(sparse_matrix) {
namespace bp = boost::python;
eigenpy::enableEigenPy();
expose_functions<double, Eigen::ColMajor>();
expose_functions<double, Eigen::RowMajor>();
}
/// @file
/// @copyright Copyright 2023 CNRS INRIA
#include "eigenpy/std-array.hpp"
using Eigen::VectorXd;
std::array<int, 3> get_arr_3_ints() { return {1, 2, 3}; }
std::array<VectorXd, 3> get_arr_3_vecs() {
std::array<VectorXd, 3> out;
out[0].setOnes(4);
out[1].setZero(2);
out[2].setRandom(10);
return out;
}
struct test_struct {
std::array<int, 3> integs;
std::array<VectorXd, 2> vecs;
test_struct() {
integs = {42, 3, -1};
vecs[0].setRandom(4); // 4 randoms between [-1,1]
vecs[1].setZero(11); // 11 zeroes
}
};
BOOST_PYTHON_MODULE(std_array) {
using namespace eigenpy;
enableEigenPy();
StdArrayPythonVisitor<std::array<int, 3>, true>::expose("StdArr3_int");
StdVectorPythonVisitor<std::vector<int>, true>::expose("StdVec_int");
exposeStdArrayEigenSpecificType<VectorXd, 2>("VectorXd");
exposeStdArrayEigenSpecificType<VectorXd, 3>("VectorXd");
exposeStdVectorEigenSpecificType<VectorXd>("VectorXd");
bp::def("get_arr_3_ints", get_arr_3_ints);
bp::def("get_arr_3_vecs", get_arr_3_vecs);
bp::class_<test_struct>("test_struct", bp::init<>(bp::args("self")))
.def_readwrite("integs", &test_struct::integs)
.def_readwrite("vecs", &test_struct::vecs);
}
/// @file
/// @copyright Copyright 2023 CNRS INRIA
#include <eigenpy/eigenpy.hpp>
#include <eigenpy/std-map.hpp>
#include <boost/unordered_map.hpp>
namespace bp = boost::python;
template <typename T1>
bp::dict std_map_to_dict(const std::map<std::string, T1>& map) {
bp::dict dictionnary;
for (auto const& x : map) {
dictionnary[x.first] = x.second;
}
return dictionnary;
}
template <typename T1>
std::map<std::string, T1> copy(const std::map<std::string, T1>& map) {
std::map<std::string, T1> out = map;
return out;
}
template <typename T1>
boost::unordered_map<std::string, T1> copy_boost(
const boost::unordered_map<std::string, T1>& obj) {
return obj;
}
struct X {
X() = delete;
X(int x) : val(x) {}
int val;
};
BOOST_PYTHON_MODULE(std_map) {
eigenpy::enableEigenPy();
eigenpy::StdMapPythonVisitor<
std::string, double, std::less<std::string>,
std::allocator<std::pair<const std::string, double> >,
true>::expose("StdMap_Double");
eigenpy::GenericMapVisitor<boost::unordered_map<std::string, int> >::expose(
"boost_map_int");
using StdMap_X = std::map<std::string, X>;
bp::class_<X>("X", bp::init<int>()).def_readwrite("val", &X::val);
// this just needs to compile
eigenpy::GenericMapVisitor<StdMap_X>::expose(
"StdMap_X", eigenpy::overload_base_get_item_for_map<StdMap_X>());
bp::def("std_map_to_dict", std_map_to_dict<double>);
bp::def("copy", copy<double>);
bp::def("copy_boost", copy_boost<int>);
bp::def("copy_X", +[](const StdMap_X& m) { return m; });
}
/// @file
/// @copyright Copyright 2023 CNRS INRIA
#include <eigenpy/eigenpy.hpp>
#include <eigenpy/std-pair.hpp>
namespace bp = boost::python;
template <typename T1, typename T2>
bp::tuple std_pair_to_tuple(const std::pair<T1, T2>& pair) {
return bp::make_tuple(pair.first, pair.second);
}
template <typename T1, typename T2>
std::pair<T1, T2> copy(const std::pair<T1, T2>& pair) {
return pair;
}
template <typename T1, typename T2>
const std::pair<T1, T2>& passthrough(const std::pair<T1, T2>& pair) {
return pair;
}
BOOST_PYTHON_MODULE(std_pair) {
eigenpy::enableEigenPy();
typedef std::pair<int, double> PairType;
eigenpy::StdPairConverter<PairType>::registration();
bp::def("std_pair_to_tuple", std_pair_to_tuple<int, double>);
bp::def("copy", copy<int, double>);
bp::def("passthrough", passthrough<int, double>,
bp::return_value_policy<bp::copy_const_reference>());
}
/// @file
/// @copyright Copyright 2023 CNRS INRIA
#include <eigenpy/eigenpy.hpp>
#include <eigenpy/std-unique-ptr.hpp>
#include <memory>
#include <string>
#include <complex>
namespace bp = boost::python;
struct V1 {
V1() = default;
V1(double p_v) : v(p_v) {}
double v = 100;
};
std::unique_ptr<int> make_unique_int() { return std::make_unique<int>(10); }
std::unique_ptr<V1> make_unique_v1() { return std::make_unique<V1>(10); }
std::unique_ptr<V1> make_unique_null() { return nullptr; }
std::unique_ptr<std::string> make_unique_str() {
return std::make_unique<std::string>("str");
}
std::unique_ptr<std::complex<double> > make_unique_complex() {
return std::make_unique<std::complex<double> >(1., 0.);
}
struct UniquePtrHolder {
UniquePtrHolder()
: int_ptr(std::make_unique<int>(20)),
v1_ptr(std::make_unique<V1>(200)),
str_ptr(std::make_unique<std::string>("str")),
complex_ptr(std::make_unique<std::complex<double> >(1., 0.)) {}
std::unique_ptr<int> int_ptr;
std::unique_ptr<V1> v1_ptr;
std::unique_ptr<V1> null_ptr;
std::unique_ptr<std::string> str_ptr;
std::unique_ptr<std::complex<double> > complex_ptr;
};
BOOST_PYTHON_MODULE(std_unique_ptr) {
eigenpy::enableEigenPy();
bp::class_<V1>("V1", bp::init<>()).def_readwrite("v", &V1::v);
bp::def("make_unique_int", make_unique_int);
bp::def("make_unique_v1", make_unique_v1);
bp::def("make_unique_null", make_unique_null,
eigenpy::StdUniquePtrCallPolicies());
bp::def("make_unique_str", make_unique_str);
bp::def("make_unique_complex", make_unique_complex);
boost::python::class_<UniquePtrHolder, boost::noncopyable>("UniquePtrHolder",
bp::init<>())
.add_property("int_ptr",
bp::make_getter(&UniquePtrHolder::int_ptr,
eigenpy::ReturnInternalStdUniquePtr()))
.add_property("v1_ptr",
bp::make_getter(&UniquePtrHolder::v1_ptr,
eigenpy::ReturnInternalStdUniquePtr()))
.add_property("null_ptr",
bp::make_getter(&UniquePtrHolder::null_ptr,
eigenpy::ReturnInternalStdUniquePtr()))
.add_property("str_ptr",
bp::make_getter(&UniquePtrHolder::str_ptr,
eigenpy::ReturnInternalStdUniquePtr()))
.add_property("complex_ptr",
bp::make_getter(&UniquePtrHolder::complex_ptr,
eigenpy::ReturnInternalStdUniquePtr()));
}
/// @file
/// @copyright Copyright 2022, CNRS
/// @copyright Copyright 2022, INRIA
#include <ostream>
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/eigen-from-python.hpp"
#include "eigenpy/std-vector.hpp"
template <typename MatType>
void printVectorOfMatrix(
const std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) {
const std::size_t n = Ms.size();
for (std::size_t i = 0; i < n; i++) {
std::cout << "el[" << i << "] =\n" << Ms[i] << '\n';
}
}
template <typename MatType>
std::vector<MatType, Eigen::aligned_allocator<MatType> > copy(
const std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) {
std::vector<MatType, Eigen::aligned_allocator<MatType> > out = Ms;
return out;
}
template <typename MatType>
void setZero(std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) {
for (std::size_t i = 0; i < Ms.size(); i++) {
Ms[i].setZero();
}
}
struct CustomTestStruct {
bool operator==(const CustomTestStruct &) const { return true; }
};
BOOST_PYTHON_MODULE(std_vector) {
namespace bp = boost::python;
using namespace eigenpy;
enableEigenPy();
bp::def("printVectorOfMatrix", printVectorOfMatrix<Eigen::VectorXd>);
bp::def("printVectorOfMatrix", printVectorOfMatrix<Eigen::MatrixXd>);
bp::def("copyStdVector", copy<Eigen::MatrixXd>);
bp::def("copyStdVector", copy<Eigen::VectorXd>);
exposeStdVectorEigenSpecificType<Eigen::Matrix3d>("Mat3d");
bp::def("printVectorOf3x3", printVectorOfMatrix<Eigen::Matrix3d>);
bp::def("copyStdVec_3x3", copy<Eigen::Matrix3d>, bp::args("mats"));
typedef Eigen::Ref<Eigen::MatrixXd> RefXd;
StdVectorPythonVisitor<std::vector<RefXd>, true>::expose("StdVec_MatRef");
bp::def("setZero", setZero<Eigen::MatrixXd>, "Sets the coeffs to 0.");
// Test matrix modification
// Mat2d don't have tolist, reserve, mutable __getitem__ and from list
// conversion
// exposeStdVectorEigenSpecificType must add those methods to StdVec_Mat2d
bp::class_<std::vector<Eigen::Matrix2d> >("StdVec_Mat2d")
.def(boost::python::vector_indexing_suite<
std::vector<Eigen::Matrix2d> >());
exposeStdVectorEigenSpecificType<Eigen::Matrix2d>("Mat2d");
// Test API regression:
// Exposing a `std::vector` with documentation doesn't clash with
// exposing a `std::vector` with a visitor
StdVectorPythonVisitor<std::vector<CustomTestStruct> >::expose(
"StdVec_CustomTestStruct", "some documentation");
}
/*
* Copyright 2023 INRIA
*/
#include <iostream>
#include "eigenpy/eigenpy.hpp"
namespace bp = boost::python;
template <typename Scalar>
Eigen::Matrix<Scalar, Eigen::Dynamic, 1> vector1x1(const Scalar& value) {
typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1> ReturnType;
return ReturnType::Constant(1, value);
}
template <typename Scalar>
Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> matrix1x1(
const Scalar& value) {
typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> ReturnType;
return ReturnType::Constant(1, 1, value);
}
template <typename Tensor>
Eigen::TensorRef<Tensor> make_ref(Tensor& tensor) {
return Eigen::TensorRef<Tensor>(tensor);
}
template <typename Tensor>
void fill(Eigen::TensorRef<Tensor> tensor, typename Tensor::Scalar value) {
for (Eigen::DenseIndex k = 0; k < tensor.size(); ++k)
tensor.coeffRef(k) = value;
}
template <typename Tensor>
void print(const Tensor& tensor) {
std::cout << tensor << std::endl;
}
template <typename Tensor>
void print_ref(const Eigen::TensorRef<const Tensor> tensor) {
print(tensor);
}
template <typename Tensor>
void print_base(const Eigen::TensorBase<Tensor>& tensor) {
print(tensor);
}
template <typename Tensor>
Tensor copy(const Eigen::TensorBase<Tensor>& tensor) {
return const_cast<Tensor&>(static_cast<const Tensor&>(tensor));
}
template <typename Tensor>
Eigen::TensorRef<Tensor> ref(Eigen::TensorRef<Tensor> tensor) {
return tensor;
}
template <typename Tensor>
const Eigen::TensorRef<const Tensor> const_ref(
const Eigen::TensorRef<const Tensor> tensor) {
return tensor;
}
template <typename Scalar, int Rank>
Eigen::Tensor<Scalar, Rank> emptyTensor() {
return Eigen::Tensor<Scalar, Rank>();
}
template <typename Scalar>
Eigen::Tensor<Scalar, 1> zeroTensor1(const Eigen::DenseIndex r) {
Eigen::Tensor<Scalar, 1> tensor(r);
tensor.setZero();
return tensor;
}
template <typename Scalar>
Eigen::Tensor<Scalar, 2> zeroTensor2(const Eigen::DenseIndex r,
const Eigen::DenseIndex s) {
Eigen::Tensor<Scalar, 2> tensor(r, s);
tensor.setZero();
return tensor;
}
template <typename Scalar>
Eigen::Tensor<Scalar, 3> zeroTensor3(const Eigen::DenseIndex r,
const Eigen::DenseIndex s,
const Eigen::DenseIndex t) {
Eigen::Tensor<Scalar, 3> tensor(r, s, t);
tensor.setZero();
return tensor;
}
template <typename Scalar>
Eigen::Tensor<Scalar, 1> createTensor1(const Eigen::DenseIndex r,
Scalar value) {
Eigen::Tensor<Scalar, 1> tensor(r);
fill(make_ref(tensor), value);
return tensor;
}
template <typename Scalar>
Eigen::Tensor<Scalar, 2> createTensor2(const Eigen::DenseIndex r,
const Eigen::DenseIndex s,
Scalar value) {
Eigen::Tensor<Scalar, 2> tensor(r, s);
fill(make_ref(tensor), value);
return tensor;
}
template <typename Scalar>
Eigen::Tensor<Scalar, 3> createTensor3(const Eigen::DenseIndex r,
const Eigen::DenseIndex s,
const Eigen::DenseIndex t,
Scalar value) {
Eigen::Tensor<Scalar, 3> tensor(r, s, t);
fill(make_ref(tensor), value);
return tensor;
}
template <typename Scalar, int Rank>
struct TensorContainer {
typedef Eigen::Tensor<Scalar, Rank> Tensor;
typedef Eigen::TensorRef<Tensor> TensorRef;
typedef Eigen::Matrix<typename Tensor::Index, Rank, 1> Dimensions;
Tensor m_tensor;
TensorContainer(const Dimensions& dims) {
typedef Eigen::array<typename Tensor::Index, Rank> InternalDimension;
InternalDimension _dims;
for (size_t k = 0; k < Rank; ++k) _dims[k] = dims[Eigen::DenseIndex(k)];
m_tensor = Tensor(_dims);
}
Tensor get_copy() const { return m_tensor; }
TensorRef get_ref() { return TensorRef(m_tensor); }
};
template <typename Scalar, int Rank>
void exposeTensorContainer() {
typedef TensorContainer<Scalar, Rank> T;
const std::string class_name = "TensorContainer" + std::to_string(Rank);
bp::class_<T>(class_name.c_str(), bp::no_init)
.def(bp::init<typename T::Dimensions>())
.def("get_copy", &T::get_copy)
.def("get_ref", &T::get_ref,
bp::with_custodian_and_ward_postcall<0, 1>());
}
BOOST_PYTHON_MODULE(tensor) {
using namespace Eigen;
eigenpy::enableEigenPy();
typedef Eigen::Tensor<double, 1> Tensor1;
typedef Eigen::Tensor<double, 2> Tensor2;
typedef Eigen::Tensor<double, 3> Tensor3;
bp::def("emptyTensor1", emptyTensor<double, 1>);
bp::def("emptyTensor2", emptyTensor<double, 2>);
bp::def("emptyTensor3", emptyTensor<double, 3>);
bp::def("zeroTensor1", zeroTensor1<double>);
bp::def("zeroTensor2", zeroTensor2<double>);
bp::def("zeroTensor3", zeroTensor3<double>);
bp::def("createTensor1", createTensor1<double>);
bp::def("createTensor2", createTensor2<double>);
bp::def("createTensor3", createTensor3<double>);
bp::def("print", print<Tensor1>);
bp::def("print", print<Tensor2>);
bp::def("print", print<Tensor3>);
bp::def("print_ref", print_ref<Tensor1>);
bp::def("print_ref", print_ref<Tensor2>);
bp::def("print_ref", print_ref<Tensor3>);
bp::def("print_base", print_base<Tensor1>);
bp::def("print_base", print_base<Tensor2>);
bp::def("print_base", print_base<Tensor3>);
bp::def("copy", copy<Tensor1>);
bp::def("copy", copy<Tensor2>);
bp::def("copy", copy<Tensor3>);
bp::def("fill", fill<Tensor1>);
bp::def("fill", fill<Tensor2>);
bp::def("fill", fill<Tensor3>);
bp::def("ref", ref<Tensor1>, bp::with_custodian_and_ward_postcall<0, 1>());
bp::def("ref", ref<Tensor2>, bp::with_custodian_and_ward_postcall<0, 1>());
bp::def("ref", ref<Tensor3>, bp::with_custodian_and_ward_postcall<0, 1>());
bp::def("const_ref", const_ref<Tensor1>,
bp::with_custodian_and_ward_postcall<0, 1>());
bp::def("const_ref", const_ref<Tensor2>,
bp::with_custodian_and_ward_postcall<0, 1>());
bp::def("const_ref", const_ref<Tensor3>,
bp::with_custodian_and_ward_postcall<0, 1>());
exposeTensorContainer<double, 1>();
exposeTensorContainer<double, 2>();
exposeTensorContainer<double, 3>();
}
#include <sys/time.h>
#include <iostream>
#include <stack>
#define SMOOTH(s) for(int _smooth=0;_smooth<s;++_smooth)
/* Return the time spent in secs. */
inline double operator- ( const struct timeval & t1,const struct timeval & t0)
{
return (t1.tv_sec - t0.tv_sec)+1e-6*(t1.tv_usec - t0.tv_usec);
}
struct StackTicToc
{
enum Unit { S = 1, MS = 1000, US = 1000000 };
Unit DEFAULT_UNIT;
static std::string unitName(Unit u)
{ switch(u) { case S: return "s"; case MS: return "ms"; case US: return "us"; } return ""; }
std::stack<struct timeval> stack;
mutable struct timeval t0;
StackTicToc( Unit def = MS ) : DEFAULT_UNIT(def) {}
inline void tic() {
stack.push(t0);
gettimeofday(&(stack.top()),NULL);
}
inline double toc(const Unit factor)
{
gettimeofday(&t0,NULL);
double dt = (t0-stack.top())*factor;
stack.pop();
return dt;
}
inline void toc( std::ostream& os, double SMOOTH=1 )
{
os << toc(DEFAULT_UNIT)/SMOOTH << " " << unitName(DEFAULT_UNIT) << std::endl;
}
};
/*
* Copyright 2024 INRIA
*/
#include <iostream>
#include "eigenpy/eigenpy.hpp"
#include "eigenpy/type_info.hpp"
struct Dummy {};
BOOST_PYTHON_MODULE(type_info) {
using namespace Eigen;
namespace bp = boost::python;
eigenpy::enableEigenPy();
eigenpy::expose_boost_type_info<int>();
eigenpy::expose_boost_type_info<std::string>();
bp::class_<Dummy>("Dummy").def(eigenpy::TypeInfoVisitor<Dummy>());
}
#include "eigenpy/eigenpy.hpp"
struct mystruct {
Eigen::Vector3d x_;
Eigen::Vector4d y_;
mystruct(const Eigen::Vector3d& x, const Eigen::Vector4d& y) : x_(x), y_(y) {}
};
BOOST_PYTHON_MODULE(user_struct) {
using namespace Eigen;
namespace bp = boost::python;
eigenpy::enableEigenPy();
bp::class_<mystruct>("MyStruct", bp::init<const Vector3d&, const Vector4d&>())
.add_property(
"x",
bp::make_getter(&mystruct::x_, bp::return_internal_reference<>()),
bp::make_setter(&mystruct::x_))
.add_property(
"y",
bp::make_getter(&mystruct::y_, bp::return_internal_reference<>()),
bp::make_setter(&mystruct::y_));
}
...@@ -2,205 +2,225 @@ ...@@ -2,205 +2,225 @@
* Copyright 2020 INRIA * Copyright 2020 INRIA
*/ */
#include <iostream>
#include <sstream>
#include "eigenpy/eigenpy.hpp" #include "eigenpy/eigenpy.hpp"
#include "eigenpy/user-type.hpp"
#include "eigenpy/ufunc.hpp" #include "eigenpy/ufunc.hpp"
#include "eigenpy/user-type.hpp"
#include <iostream> template <typename Scalar>
#include <sstream> struct CustomType;
template<typename Scalar> struct CustomType; namespace Eigen {
/// @brief Eigen::NumTraits<> specialization for casadi::SX
namespace Eigen ///
{ template <typename Scalar>
/// @brief Eigen::NumTraits<> specialization for casadi::SX struct NumTraits<CustomType<Scalar> > {
/// typedef CustomType<Scalar> Real;
template<typename Scalar> typedef CustomType<Scalar> NonInteger;
struct NumTraits< CustomType<Scalar> > typedef CustomType<Scalar> Literal;
{ typedef CustomType<Scalar> Nested;
typedef CustomType<Scalar> Real;
typedef CustomType<Scalar> NonInteger; enum {
typedef CustomType<Scalar> Literal; // does not support complex Base types
typedef CustomType<Scalar> Nested; IsComplex = 0,
// does not support integer Base types
enum { IsInteger = 0,
// does not support complex Base types // only support signed Base types
IsComplex = 0 , IsSigned = 1,
// does not support integer Base types // must initialize an AD<Base> object
IsInteger = 0 , RequireInitialization = 1,
// only support signed Base types // computational cost of the corresponding operations
IsSigned = 1 , ReadCost = 1,
// must initialize an AD<Base> object AddCost = 2,
RequireInitialization = 1 , MulCost = 2
// computational cost of the corresponding operations
ReadCost = 1 ,
AddCost = 2 ,
MulCost = 2
};
static CustomType<Scalar> epsilon()
{
return CustomType<Scalar>(std::numeric_limits<Scalar>::epsilon());
}
static CustomType<Scalar> dummy_precision()
{
return CustomType<Scalar>(NumTraits<Scalar>::dummy_precision());
}
static CustomType<Scalar> highest()
{
return CustomType<Scalar>(std::numeric_limits<Scalar>::max());
}
static CustomType<Scalar> lowest()
{
return CustomType<Scalar>(std::numeric_limits<Scalar>::min());
}
static int digits10()
{
return std::numeric_limits<Scalar>::digits10;
}
}; };
} // namespace Eigen
static CustomType<Scalar> epsilon() {
return CustomType<Scalar>(std::numeric_limits<Scalar>::epsilon());
}
static CustomType<Scalar> dummy_precision() {
return CustomType<Scalar>(NumTraits<Scalar>::dummy_precision());
}
static CustomType<Scalar> highest() {
return CustomType<Scalar>(std::numeric_limits<Scalar>::max());
}
static CustomType<Scalar> lowest() {
return CustomType<Scalar>(std::numeric_limits<Scalar>::min());
}
template<typename Scalar> static int digits10() { return std::numeric_limits<Scalar>::digits10; }
struct CustomType static int max_digits10() {
{ return std::numeric_limits<Scalar>::max_digits10;
}
};
} // namespace Eigen
template <typename Scalar>
struct CustomType {
CustomType() {} CustomType() {}
explicit CustomType(const Scalar & value) explicit CustomType(const Scalar& value) : m_value(value) {}
: m_value(value)
{} CustomType operator*(const CustomType& other) const {
return CustomType(m_value * other.m_value);
CustomType operator*(const CustomType & other) const { return CustomType(m_value * other.m_value); } }
CustomType operator+(const CustomType & other) const { return CustomType(m_value + other.m_value); } CustomType operator+(const CustomType& other) const {
CustomType operator-(const CustomType & other) const { return CustomType(m_value - other.m_value); } return CustomType(m_value + other.m_value);
CustomType operator/(const CustomType & other) const { return CustomType(m_value / other.m_value); } }
CustomType operator-(const CustomType& other) const {
void operator+=(const CustomType & other) { m_value += other.m_value; } return CustomType(m_value - other.m_value);
void operator-=(const CustomType & other) { m_value -= other.m_value; } }
void operator*=(const CustomType & other) { m_value *= other.m_value; } CustomType operator/(const CustomType& other) const {
void operator/=(const CustomType & other) { m_value /= other.m_value; } return CustomType(m_value / other.m_value);
}
void operator=(const Scalar & value) { m_value = value; }
void operator+=(const CustomType& other) { m_value += other.m_value; }
bool operator==(const CustomType & other) const { return m_value == other.m_value; } void operator-=(const CustomType& other) { m_value -= other.m_value; }
bool operator!=(const CustomType & other) const { return m_value != other.m_value; } void operator*=(const CustomType& other) { m_value *= other.m_value; }
void operator/=(const CustomType& other) { m_value /= other.m_value; }
bool operator<=(const CustomType & other) const { return m_value <= other.m_value; }
bool operator<(const CustomType & other) const { return m_value < other.m_value; } void operator=(const Scalar& value) { m_value = value; }
bool operator>=(const CustomType & other) const { return m_value >= other.m_value; }
bool operator>(const CustomType & other) const { return m_value > other.m_value; } bool operator==(const CustomType& other) const {
return m_value == other.m_value;
}
bool operator!=(const CustomType& other) const {
return m_value != other.m_value;
}
bool operator<=(const CustomType& other) const {
return m_value <= other.m_value;
}
bool operator<(const CustomType& other) const {
return m_value < other.m_value;
}
bool operator>=(const CustomType& other) const {
return m_value >= other.m_value;
}
bool operator>(const CustomType& other) const {
return m_value > other.m_value;
}
CustomType operator-() const { return CustomType(-m_value); } CustomType operator-() const { return CustomType(-m_value); }
operator Scalar () const operator Scalar() const { return m_value; }
{
return m_value; std::string print() const {
}
std::string print() const
{
std::stringstream ss; std::stringstream ss;
ss << "value: " << m_value << std::endl; ss << "value: " << m_value << std::endl;
return ss.str(); return ss.str();
} }
friend std::ostream & operator <<(std::ostream & os, const CustomType & X) friend std::ostream& operator<<(std::ostream& os, const CustomType& X) {
{
os << X.m_value; os << X.m_value;
return os; return os;
} }
//protected: // protected:
Scalar m_value; Scalar m_value;
}; };
template<typename Scalar> template <typename Scalar>
Eigen::Matrix<CustomType<Scalar>,Eigen::Dynamic,Eigen::Dynamic> create(int rows, int cols) Eigen::Matrix<CustomType<Scalar>, Eigen::Dynamic, Eigen::Dynamic> create(
{ int rows, int cols) {
typedef Eigen::Matrix<CustomType<Scalar>,Eigen::Dynamic,Eigen::Dynamic> Matrix; typedef Eigen::Matrix<CustomType<Scalar>, Eigen::Dynamic, Eigen::Dynamic>
return Matrix(rows,cols); Matrix;
return Matrix(rows, cols);
} }
template<typename Scalar> template <typename Scalar>
void print(const Eigen::Matrix<CustomType<Scalar>,Eigen::Dynamic,Eigen::Dynamic> & mat) void print(const Eigen::Matrix<CustomType<Scalar>, Eigen::Dynamic,
{ Eigen::Dynamic>& mat) {
std::cout << mat << std::endl; std::cout << mat << std::endl;
} }
template<typename Scalar> template <typename Scalar>
Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> build_matrix(int rows, int cols) Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> build_matrix(int rows,
{ int cols) {
typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> Matrix; typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> Matrix;
return Matrix(rows,cols); return Matrix(rows, cols);
} }
template<typename Scalar> template <typename Scalar>
void expose_custom_type(const std::string & name) void expose_custom_type(const std::string& name) {
{
using namespace Eigen; using namespace Eigen;
namespace bp = boost::python; namespace bp = boost::python;
typedef CustomType<Scalar> Type; typedef CustomType<Scalar> Type;
bp::class_<Type>(name.c_str(),bp::init<Scalar>(bp::arg("value"))) bp::class_<Type>(name.c_str(), bp::init<Scalar>(bp::arg("value")))
.def(bp::self + bp::self) .def(bp::self + bp::self)
.def(bp::self - bp::self) .def(bp::self - bp::self)
.def(bp::self * bp::self) .def(bp::self * bp::self)
.def(bp::self / bp::self) .def(bp::self / bp::self)
.def(bp::self += bp::self) .def(bp::self += bp::self)
.def(bp::self -= bp::self) .def(bp::self -= bp::self)
.def(bp::self *= bp::self) .def(bp::self *= bp::self)
.def(bp::self /= bp::self) .def(bp::self /= bp::self)
.def("__repr__",&Type::print) .def("__repr__", &Type::print);
;
int code = eigenpy::registerNewType<Type>(); int code = eigenpy::registerNewType<Type>();
std::cout << "code: " << code << std::endl; std::cout << "code: " << code << std::endl;
eigenpy::registerCommonUfunc<Type>(); eigenpy::registerCommonUfunc<Type>();
} }
BOOST_PYTHON_MODULE(user_type) BOOST_PYTHON_MODULE(user_type) {
{
using namespace Eigen; using namespace Eigen;
namespace bp = boost::python; namespace bp = boost::python;
eigenpy::enableEigenPy(); eigenpy::enableEigenPy();
expose_custom_type<double>("CustomDouble"); expose_custom_type<double>("CustomDouble");
typedef CustomType<double> DoubleType; typedef CustomType<double> DoubleType;
typedef Eigen::Matrix<DoubleType,Eigen::Dynamic,Eigen::Dynamic> DoubleMatrix; typedef Eigen::Matrix<DoubleType, Eigen::Dynamic, Eigen::Dynamic>
DoubleMatrix;
eigenpy::EigenToPyConverter<DoubleMatrix>::registration(); eigenpy::EigenToPyConverter<DoubleMatrix>::registration();
eigenpy::EigenFromPyConverter<DoubleMatrix>::registration(); eigenpy::EigenFromPyConverter<DoubleMatrix>::registration();
bp::def("create_double",create<double>); bp::def("create_double", create<double>);
expose_custom_type<float>("CustomFloat"); expose_custom_type<float>("CustomFloat");
typedef CustomType<float> FloatType; typedef CustomType<float> FloatType;
typedef Eigen::Matrix<FloatType,Eigen::Dynamic,Eigen::Dynamic> FloatMatrix; typedef Eigen::Matrix<FloatType, Eigen::Dynamic, Eigen::Dynamic> FloatMatrix;
eigenpy::EigenToPyConverter<FloatMatrix>::registration(); eigenpy::EigenToPyConverter<FloatMatrix>::registration();
eigenpy::EigenFromPyConverter<FloatMatrix>::registration(); eigenpy::EigenFromPyConverter<FloatMatrix>::registration();
bp::def("create_float",create<float>); bp::def("create_float", create<float>);
bp::def("build_matrix",build_matrix<double>); bp::def("build_matrix", build_matrix<double>);
bp::def("print",print<double>); #if EIGEN_VERSION_AT_LEAST(3, 3, 0)
bp::def("print",print<float>); bp::def("print", print<double>);
bp::def("print", print<float>);
eigenpy::registerCast<DoubleType,double>(true); #endif
eigenpy::registerCast<double,DoubleType>(true);
eigenpy::registerCast<DoubleType,int32_t>(false); eigenpy::registerCast<DoubleType, double>(true);
eigenpy::registerCast<int32_t,DoubleType>(true); eigenpy::registerCast<double, DoubleType>(true);
eigenpy::registerCast<DoubleType,int64_t>(false); eigenpy::registerCast<DoubleType, float>(false);
eigenpy::registerCast<int64_t,DoubleType>(true); eigenpy::registerCast<float, DoubleType>(true);
eigenpy::registerCast<FloatType,int64_t>(false); eigenpy::registerCast<DoubleType, int>(false);
eigenpy::registerCast<int64_t,FloatType>(true); eigenpy::registerCast<int, DoubleType>(true);
eigenpy::registerCast<DoubleType, long long>(false);
bp::implicitly_convertible<double,DoubleType>(); eigenpy::registerCast<long long, DoubleType>(true);
bp::implicitly_convertible<DoubleType,double>(); eigenpy::registerCast<DoubleType, long>(false);
eigenpy::registerCast<long, DoubleType>(true);
eigenpy::registerCast<FloatType, double>(true);
eigenpy::registerCast<double, FloatType>(false);
eigenpy::registerCast<FloatType, float>(true);
eigenpy::registerCast<float, FloatType>(true);
eigenpy::registerCast<FloatType, long long>(false);
eigenpy::registerCast<long long, FloatType>(true);
eigenpy::registerCast<FloatType, int>(false);
eigenpy::registerCast<int, FloatType>(true);
eigenpy::registerCast<FloatType, long>(false);
eigenpy::registerCast<long, FloatType>(true);
bp::implicitly_convertible<double, DoubleType>();
bp::implicitly_convertible<DoubleType, double>();
} }
/// @file
/// @copyright Copyright 2024 CNRS INRIA
#include <eigenpy/eigenpy.hpp>
#include <eigenpy/variant.hpp>
#include <string>
#include <complex>
#cmakedefine TEST_TYPE @TEST_TYPE@
#define VARIANT TEST_TYPE
namespace bp = boost::python;
struct V1 {
int v;
};
struct V2 {
char v;
};
typedef VARIANT<V1, V2> MyVariant;
template <typename Variant>
struct MyVariantNoneHelper {};
template <typename... Alternatives>
struct MyVariantNoneHelper<boost::variant<Alternatives...> > {
typedef VARIANT<boost::blank, Alternatives...> type;
};
#ifdef EIGENPY_WITH_CXX17_SUPPORT
template <typename... Alternatives>
struct MyVariantNoneHelper<std::variant<Alternatives...> > {
typedef VARIANT<std::monostate, Alternatives...> type;
};
#endif
typedef typename MyVariantNoneHelper<
VARIANT<V1, bool, int, double, std::string, std::complex<double> > >::type
MyVariantFull;
MyVariant make_variant() { return V1(); }
MyVariantFull make_variant_full_none() { return MyVariantFull(); }
MyVariantFull make_variant_full_float() { return 3.14; }
MyVariantFull make_variant_full_int() { return 3; }
MyVariantFull make_variant_full_bool() { return false; }
MyVariantFull make_variant_full_str() { return std::string("str"); }
MyVariantFull make_variant_full_complex() { return std::complex<double>(1., 0.); }
struct VariantHolder {
MyVariant variant;
};
struct VariantFullHolder {
MyVariantFull variant;
};
BOOST_PYTHON_MODULE(@MODNAME@) {
using namespace eigenpy;
enableEigenPy();
bp::class_<V1>("V1", bp::init<>()).def_readwrite("v", &V1::v);
bp::class_<V2>("V2", bp::init<>()).def_readwrite("v", &V2::v);
typedef eigenpy::VariantConverter<MyVariant> Converter;
Converter::registration();
bp::def("make_variant", make_variant);
boost::python::class_<VariantHolder>("VariantHolder", bp::init<>())
.add_property("variant",
bp::make_getter(&VariantHolder::variant,
Converter::return_internal_reference()),
bp::make_setter(&VariantHolder::variant));
typedef eigenpy::VariantConverter<MyVariantFull> ConverterFull;
ConverterFull::registration();
bp::def("make_variant_full_none", make_variant_full_none);
bp::def("make_variant_full_float", make_variant_full_float);
bp::def("make_variant_full_int", make_variant_full_int);
bp::def("make_variant_full_bool", make_variant_full_bool);
bp::def("make_variant_full_str", make_variant_full_str);
bp::def("make_variant_full_complex", make_variant_full_complex);
boost::python::class_<VariantFullHolder>("VariantFullHolder", bp::init<>())
.add_property("variant",
bp::make_getter(&VariantFullHolder::variant,
ConverterFull::return_internal_reference()),
bp::make_setter(&VariantFullHolder::variant));
}