Skip to content
Snippets Groups Projects
Commit cae5ff22 authored by Nicolas Mansard's avatar Nicolas Mansard Committed by nmansard
Browse files

IVIGIT.

parent df670c2b
No related branches found
No related tags found
No related merge requests found
...@@ -8,7 +8,9 @@ IF(NOT BOOST_NUMPY_DIR) ...@@ -8,7 +8,9 @@ IF(NOT BOOST_NUMPY_DIR)
ENDIF() ENDIF()
FIND_PACKAGE(Boost 1.45.0) FIND_PACKAGE(Boost 1.45.0)
IF(Boost_FOUND) IF(Boost_FOUND)
INCLUDE_DIRECTORIES("${Boost_INCLUDE_DIRS}" "/usr/include/python2.7" "/usr/include/eigen3" "Boost.NumPy") INCLUDE_DIRECTORIES("${Boost_INCLUDE_DIRS}" "/usr/include/python2.7" "/usr/include/eigen3" "Boost.NumPy")
LINK_DIRECTORIES(${BOOST_NUMPY_DIR}) LINK_DIRECTORIES(${BOOST_NUMPY_DIR})
...@@ -29,6 +31,12 @@ IF(Boost_FOUND) ...@@ -29,6 +31,12 @@ IF(Boost_FOUND)
ADD_LIBRARY(eigen SHARED src/eigen.cpp) ADD_LIBRARY(eigen SHARED src/eigen.cpp)
TARGET_LINK_LIBRARIES(eigen ${Boost_LIBRARIES} libboost_numpy.so) TARGET_LINK_LIBRARIES(eigen ${Boost_LIBRARIES} libboost_numpy.so)
ADD_LIBRARY(eigenc SHARED src/eigenc.cpp)
TARGET_LINK_LIBRARIES(eigenc ${Boost_LIBRARIES})
ADD_LIBRARY(eigentemplate SHARED src/eigentemplate.cpp)
TARGET_LINK_LIBRARIES(eigentemplate ${Boost_LIBRARIES})
ELSEIF(NOT Boost_FOUND) ELSEIF(NOT Boost_FOUND)
MESSAGE(FATAL_ERROR "Unable to find correct Boost version. Did you set BOOST_ROOT?") MESSAGE(FATAL_ERROR "Unable to find correct Boost version. Did you set BOOST_ROOT?")
ENDIF() ENDIF()
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import numpy as np import numpy as np
'''
import libsimple import libsimple
print libsimple.char() print libsimple.char()
...@@ -28,6 +29,25 @@ print "matrix ===> " ...@@ -28,6 +29,25 @@ print "matrix ===> "
libeigen.test2(a) libeigen.test2(a)
print "array ===> " print "array ===> "
libeigen.test2(b) libeigen.test2(b)
'''
import libeigentemplate
print "===> From C++ to Py"
print libeigentemplate.test()
print "===> From Vec C++ to Py"
print libeigentemplate.testVec()
print "===> From Py to C++"
a = np.random.random([5,5])
for i in range(5):
for j in range(5):
a[i,j] = i*5+j
#a = np.random.random([
print a
libeigentemplate.test2(a)
print "===> From Py::slice to C++"
b=a[1:5,1:3]
print b
libeigentemplate.test2(b)
......
#include <Eigen/Core>
#include <boost/python.hpp>
#include <numpy/arrayobject.h>
namespace boopy
{
namespace bp = boost::python;
template <typename SCALAR> struct NumpyEquivalentType {};
template <> struct NumpyEquivalentType<double> { enum { type_code = NPY_DOUBLE };};
template <> struct NumpyEquivalentType<int> { enum { type_code = NPY_INT };};
template <> struct NumpyEquivalentType<float> { enum { type_code = NPY_FLOAT };};
struct EigenMatrix_to_python_matrix
{
static PyObject* convert(Eigen::MatrixXd const& mat)
{
typedef Eigen::MatrixXd::Scalar T;
npy_intp shape[2] = { mat.rows(), mat.cols() };
PyArrayObject* pyArray = (PyArrayObject*)
PyArray_SimpleNew(2, shape,
NumpyEquivalentType<T>::type_code);
T* pyData = (T*)PyArray_DATA(pyArray);
for(int i=0;i<mat.rows();++i)
for(int j=0;j<mat.cols();++j)
pyData[i*mat.cols()+j] = mat(i,j);
return ((PyObject*)pyArray);
}
};
struct EigenMatrix_from_python_array
{
EigenMatrix_from_python_array()
{
bp::converter::registry
::push_back(&convertible,
&construct,
bp::type_id<Eigen::MatrixXd>());
}
// Determine if obj_ptr can be converted in a Eigenvec
static void* convertible(PyObject* obj_ptr)
{
typedef Eigen::MatrixXd::Scalar T;
if (!PyArray_Check(obj_ptr)) {
return 0;
}
if (PyArray_NDIM(obj_ptr) > 2) {
return 0;
}
if (PyArray_ObjectType(obj_ptr, 0) != NumpyEquivalentType<T>::type_code) {
return 0;
}
int flags = PyArray_FLAGS(obj_ptr);
if (!(flags & NPY_C_CONTIGUOUS)) {
return 0;
}
if (!(flags & NPY_ALIGNED)) {
return 0;
}
return obj_ptr;
}
// Convert obj_ptr into a Eigenvec
static void construct(PyObject* pyObj,
bp::converter::rvalue_from_python_stage1_data* memory)
{
typedef Eigen::MatrixXd::Scalar T;
using namespace Eigen;
PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
int ndims = PyArray_NDIM(pyArray);
assert(ndims == 2);
int dtype_size = (PyArray_DESCR(pyArray))->elsize;
int s1 = PyArray_STRIDE(pyArray, 0);
assert(s1 % dtype_size == 0);
int R = MatrixXd::RowsAtCompileTime;
int C = MatrixXd::ColsAtCompileTime;
if (R == Eigen::Dynamic) R = PyArray_DIMS(pyArray)[0];
else assert(PyArray_DIMS(pyArray)[0]==R);
if (C == Eigen::Dynamic) C = PyArray_DIMS(pyArray)[1];
else assert(PyArray_DIMS(pyArray)[1]==C);
T* pyData = reinterpret_cast<T*>(PyArray_DATA(pyArray));
void* storage = ((bp::converter::rvalue_from_python_storage<MatrixXd>*)
(memory))->storage.bytes;
MatrixXd & mat = * new (storage) MatrixXd(R,C);
for(int i=0;i<R;++i)
for(int j=0;j<C;++j)
mat(i,j) = pyData[i*C+j];
memory->convertible = storage;
}
};
}
Eigen::MatrixXd test()
{
Eigen::MatrixXd mat = Eigen::MatrixXd::Random(5,5);
std::cout << "EigenMAt = " << mat << std::endl;
return mat;
}
void test2( Eigen::MatrixXd mat )
{
std::cout << "test2: dim = " << mat.rows() << " ||| m[0,0] = " << mat(0,0) << std::endl;
}
BOOST_PYTHON_MODULE(libeigenc)
{
import_array();
namespace bp = boost::python;
bp::to_python_converter<Eigen::MatrixXd,
boopy::EigenMatrix_to_python_matrix>();
boopy::EigenMatrix_from_python_array();
bp::def("test", test);
bp::def("test2", test2);
}
#include <Eigen/Core>
#include <boost/python.hpp>
#include <numpy/arrayobject.h>
namespace boopy
{
namespace bp = boost::python;
template <typename SCALAR> struct NumpyEquivalentType {};
template <> struct NumpyEquivalentType<double> { enum { type_code = NPY_DOUBLE };};
template <> struct NumpyEquivalentType<int> { enum { type_code = NPY_INT };};
template <> struct NumpyEquivalentType<float> { enum { type_code = NPY_FLOAT };};
/* --- TO PYTHON -------------------------------------------------------------- */
template< typename MatType >
struct EigenMatrix_to_python_matrix
{
static PyObject* convert(MatType const& mat)
{
typedef typename MatType::Scalar T;
const int R = mat.rows(), C = mat.cols();
npy_intp shape[2] = { R,C };
PyArrayObject* pyArray = (PyArrayObject*)
PyArray_SimpleNew(2, shape,
NumpyEquivalentType<T>::type_code);
T* pyData = (T*)PyArray_DATA(pyArray);
Eigen::Map< Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > pyMatrix(pyData,R,C);
pyMatrix = mat;
return (PyObject*)pyArray;
}
};
/* --- FROM PYTHON ------------------------------------------------------------ */
struct EigenMatrix_from_python_array
{
EigenMatrix_from_python_array()
{
bp::converter::registry
::push_back(&convertible,
&construct,
bp::type_id<Eigen::MatrixXd>());
}
// Determine if obj_ptr can be converted in a Eigenvec
static void* convertible(PyObject* obj_ptr)
{
typedef Eigen::MatrixXd MatType;
typedef MatType::Scalar T;
if (!PyArray_Check(obj_ptr)) return 0;
if (PyArray_NDIM(obj_ptr) != 2)
if ( (PyArray_NDIM(obj_ptr) !=1) || (MatType::IsVectorAtCompileTime) )
return 0;
if (PyArray_ObjectType(obj_ptr, 0) != NumpyEquivalentType<T>::type_code)
return 0;
if (!(PyArray_FLAGS(obj_ptr) & NPY_ALIGNED))
{
std::cerr << "NPY non-aligned matrices are not implemented." << std::endl;
return 0;
}
return obj_ptr;
}
// Convert obj_ptr into a Eigenvec
static void construct(PyObject* pyObj,
bp::converter::rvalue_from_python_stage1_data* memory)
{
typedef Eigen::MatrixXd MatType;
typedef MatType::Scalar T;
using namespace Eigen;
PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
int ndims = PyArray_NDIM(pyArray);
assert(ndims == 2); // TODO: handle vectors
int itemsize = PyArray_ITEMSIZE(pyArray);
int stride1 = PyArray_STRIDE(pyArray, 0) / itemsize;
int stride2 = PyArray_STRIDE(pyArray, 1) / itemsize;
std::cout << "STRIDE = " << stride1 << " x " << stride2 << std::endl;
int R = MatrixXd::RowsAtCompileTime;
int C = MatrixXd::ColsAtCompileTime;
if (R == Eigen::Dynamic) R = PyArray_DIMS(pyArray)[0];
else assert(PyArray_DIMS(pyArray)[0]==R);
if (C == Eigen::Dynamic) C = PyArray_DIMS(pyArray)[1];
else assert(PyArray_DIMS(pyArray)[1]==C);
T* pyData = reinterpret_cast<T*>(PyArray_DATA(pyArray));
void* storage = ((bp::converter::rvalue_from_python_storage<MatrixXd>*)
(memory))->storage.bytes;
MatrixXd & mat = * new (storage) MatrixXd(R,C);
for(int i=0;i<R;++i)
for(int j=0;j<C;++j)
mat(i,j) = pyData[i*C+j];
memory->convertible = storage;
}
};
}
Eigen::MatrixXd test()
{
Eigen::MatrixXd mat = Eigen::MatrixXd::Random(3,6);
std::cout << "EigenMAt = " << mat << std::endl;
return mat;
}
Eigen::VectorXd testVec()
{
Eigen::VectorXd mat = Eigen::VectorXd::Random(6);
std::cout << "EigenVec = " << mat << std::endl;
return mat;
}
void test2( Eigen::MatrixXd mat )
{
std::cout << mat << std::endl;
}
BOOST_PYTHON_MODULE(libeigentemplate)
{
import_array();
namespace bp = boost::python;
bp::to_python_converter<Eigen::MatrixXd,
boopy::EigenMatrix_to_python_matrix<Eigen::MatrixXd> >();
bp::to_python_converter<Eigen::VectorXd,
boopy::EigenMatrix_to_python_matrix<Eigen::VectorXd> >();
boopy::EigenMatrix_from_python_array();
bp::def("test", test);
bp::def("testVec", testVec);
bp::def("test2", test2);
}
...@@ -20,7 +20,7 @@ std::string teststr() ...@@ -20,7 +20,7 @@ std::string teststr()
Eigen::VectorXd testeigenvec() Eigen::VectorXd testeigenvec()
{ {
Eigen::VectorXd v(5); Eigen::VectorXd v(555);
return v; return v;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment