Commit cae5ff22 authored by Nicolas Mansard's avatar Nicolas Mansard Committed by nmansard
Browse files

IVIGIT.

parent df670c2b
......@@ -8,7 +8,9 @@ IF(NOT BOOST_NUMPY_DIR)
ENDIF()
FIND_PACKAGE(Boost 1.45.0)
IF(Boost_FOUND)
INCLUDE_DIRECTORIES("${Boost_INCLUDE_DIRS}" "/usr/include/python2.7" "/usr/include/eigen3" "Boost.NumPy")
LINK_DIRECTORIES(${BOOST_NUMPY_DIR})
......@@ -29,6 +31,12 @@ IF(Boost_FOUND)
ADD_LIBRARY(eigen SHARED src/eigen.cpp)
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)
MESSAGE(FATAL_ERROR "Unable to find correct Boost version. Did you set BOOST_ROOT?")
ENDIF()
......
......@@ -2,6 +2,7 @@
import numpy as np
'''
import libsimple
print libsimple.char()
......@@ -28,6 +29,25 @@ print "matrix ===> "
libeigen.test2(a)
print "array ===> "
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()
Eigen::VectorXd testeigenvec()
{
Eigen::VectorXd v(5);
Eigen::VectorXd v(555);
return v;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment