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

IVIGIT.

parents
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "DEBUG")
ENDIF()
IF(NOT BOOST_NUMPY_DIR)
SET(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})
SET(Boost_USE_STATIC_LIBS OFF)
SET(Boost_USE_MULTITHREADED ON)
SET(Boost_USE_STATIC_RUNTIME OFF)
FIND_PACKAGE(Boost 1.45.0 COMPONENTS python)
ADD_LIBRARY(simple SHARED src/simple.cpp)
TARGET_LINK_LIBRARIES(simple ${Boost_LIBRARIES})
ADD_LIBRARY(mystring SHARED src/mystring.cpp)
TARGET_LINK_LIBRARIES(mystring ${Boost_LIBRARIES})
ADD_LIBRARY(bnpy SHARED src/bnpy.cpp)
TARGET_LINK_LIBRARIES(bnpy ${Boost_LIBRARIES})
ADD_LIBRARY(eigen SHARED src/eigen.cpp)
TARGET_LINK_LIBRARIES(eigen ${Boost_LIBRARIES} libboost_numpy.so)
ELSEIF(NOT Boost_FOUND)
MESSAGE(FATAL_ERROR "Unable to find correct Boost version. Did you set BOOST_ROOT?")
ENDIF()
IF(CMAKE_COMPILER_IS_GNUCXX)
ADD_DEFINITIONS("-Wall")
ELSE()
MESSAGE(FATAL_ERROR "CMakeLists.txt has not been tested/written for your compiler.")
ENDIF()
#!/usr/bin/python
import numpy as np
import libsimple
print libsimple.char()
print libsimple.str()
try:
a = libsimple.eigenvec()
print a
except:
print "Error when calling simple eigenvec"
import libmystring
print libmystring.hello()
print libmystring.size("toto+5")
import libeigen
print libeigen.test()
a = np.matrix([11,2,3,4,5]).T
b = np.array([11,2,3,4,5])
#b = np.array([[15,],[1,],[1,],[1,],[1,],])
#b = np.array([ [[10,2],[3,4]],[[10,2],[3,4]] ])
print "matrix ===> "
libeigen.test2(a)
print "array ===> "
libeigen.test2(b)
'''
import libbnpy
a=libbnpy.array()
print a.__class__
b=libbnpy.matrix()
print b.__class__
'''
/* Simple test using the boost::numpy interface: return an array and a matrix. */
#include <boost/python.hpp>
#include "boost/numpy.hpp"
namespace bp = boost::python;
namespace bn = boost::numpy;
/* Return an dim-1 array with 5 elements. */
bn::ndarray array() {
std::vector<double> v(5);
v[0] = 56;
Py_intptr_t shape[1] = { v.size() };
bn::ndarray result = bn::zeros(1, shape, bn::dtype::get_builtin<double>());
std::copy(v.begin(), v.end(), reinterpret_cast<double*>(result.get_data()));
return result;
}
/* Return a dim-1 matrix with five elements. */
boost::python::object matrix() {
std::vector<double> v(5);
v[0] = 56;
Py_intptr_t shape[1] = { v.size() };
bn::matrix t(bn::zeros(1, shape, bn::dtype::get_builtin<double>()));
std::copy(v.begin(), v.end(), reinterpret_cast<double*>(t.get_data()));
return t;
}
BOOST_PYTHON_MODULE(libbnpy) {
bn::initialize();
bp::def("array", array);
bp::def("matrix", matrix);
}
#include <Eigen/Core>
#include <boost/python.hpp>
#include <boost/numpy.hpp>
namespace boopy
{
namespace bpn = boost::numpy;
namespace bp = boost::python;
struct Eigenvec_to_python_matrix
{
static PyObject* convert(Eigen::VectorXd const& v)
{
Py_intptr_t shape[1] = { v.size() };
bpn::matrix result(bpn::zeros(1, shape, bpn::dtype::get_builtin<double>()));
std::copy(v.data(), v.data()+v.size(), reinterpret_cast<double*>(result.get_data()));
return bp::incref(result.ptr());
}
};
struct Eigenvec_from_python_array
{
Eigenvec_from_python_array()
{
bp::converter::registry
::push_back(&convertible,
&construct,
bp::type_id<Eigen::VectorXd>());
}
// Determine if obj_ptr can be converted in a Eigenvec
static void* convertible(PyObject* obj_ptr)
{
try {
bp::object obj(bp::handle<>(bp::borrowed(obj_ptr)));
std::auto_ptr<bpn::ndarray>
array(new bpn::ndarray(bpn::from_object(obj,
bpn::dtype::get_builtin<double>(),
bpn::ndarray::V_CONTIGUOUS)));
if( (array->get_nd()==1)
|| ( (array->get_nd()==2) && (array->get_shape()[1]==1) ))
return array.release();
else
return 0;
} catch (bp::error_already_set & err) {
bp::handle_exception();
return 0;
}
}
// Convert obj_ptr into a Eigenvec
static void construct(PyObject* ,
bp::converter::rvalue_from_python_stage1_data* memory)
{
// Recover the pointer created in <convertible>
std::auto_ptr<bpn::ndarray>
array(reinterpret_cast<bpn::ndarray*>(memory->convertible));
const int nrow = array->get_shape()[0];
std::cout << "nrow = " << nrow << std::endl;
// Get the memory where to create the vector
void* storage
= ((bp::converter::rvalue_from_python_storage<Eigen::VectorXd>*)memory)
->storage.bytes;
// Create the vector
Eigen::VectorXd & res = * new (storage) Eigen::VectorXd(nrow);
// Copy the data
double * data = (double*)array->get_data();
for(int i=0;i<nrow;++i)
res[i] = data[i];
// Stash the memory chunk pointer for later use by boost.python
memory->convertible = storage;
}
};
}
Eigen::VectorXd test()
{
Eigen::VectorXd v = Eigen::VectorXd::Random(5);
std::cout << v.transpose() << std::endl;
return v;
}
void test2( Eigen::VectorXd v )
{
std::cout << "test2: dim = " << v.size() << " ||| v[0] = " << v[0] << std::endl;
}
BOOST_PYTHON_MODULE(libeigen)
{
namespace bpn = boost::numpy;
namespace bp = boost::python;
bpn::initialize();
bp::to_python_converter<Eigen::VectorXd,
boopy::Eigenvec_to_python_matrix>();
boopy::Eigenvec_from_python_array();
bp::def("test", test);
bp::def("test2", test2);
}
/* Tutorial with boost::python. Using the converter to access a home-made
* string class and bind it to the python strings. */
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/to_python_converter.hpp>
namespace homemadestring
{
/* This is the home-made string class. */
class custom_string
{
public:
custom_string() {}
custom_string(std::string const& value) : value_(value) {}
std::string const& value() const { return value_; }
private:
std::string value_;
};
/* Two simple functions with this class */
custom_string hello() { return custom_string("Hello world."); }
std::size_t size(custom_string const& s) { return s.value().size(); }
/* From c to python converter */
struct custom_string_to_python_str
{
static PyObject* convert(custom_string const& s)
{
return boost::python::incref(boost::python::object(s.value()).ptr());
}
};
struct custom_string_from_python_str
{
custom_string_from_python_str()
{
boost::python::converter::registry
::push_back(&convertible,
&construct,
boost::python::type_id<custom_string>());
}
static void* convertible(PyObject* obj_ptr)
{
if (!PyString_Check(obj_ptr)) return 0;
return obj_ptr;
}
static void
construct(PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
const char* value = PyString_AsString(obj_ptr);
if (value == 0) boost::python::throw_error_already_set();
void* storage =
((boost::python::converter::rvalue_from_python_storage<custom_string>*)data)
->storage.bytes;
new (storage) custom_string(value);
data->convertible = storage;
}
};
void init_module()
{
using namespace boost::python;
boost::python::to_python_converter<custom_string,
custom_string_to_python_str>();
custom_string_from_python_str();
def("hello", hello);
def("size", size);
}
} // namespace homemagestring
BOOST_PYTHON_MODULE(libmystring)
{
homemadestring::init_module();
}
/* Simple test with boost::python.
* Declare and bind three function, returning char*, string, and Eigen::Vector. The last
* function raises and error at runtime due to inadequate binding.
*/
#include <boost/python.hpp>
#include <string>
#include <Eigen/Core>
char const* testchar()
{
return "Yay char!";
}
std::string teststr()
{
return "Yay str!";
}
Eigen::VectorXd testeigenvec()
{
Eigen::VectorXd v(5);
return v;
}
BOOST_PYTHON_MODULE(libsimple)
{
using namespace boost::python;
def("char", testchar);
def("str", teststr);
def("eigenvec",testeigenvec);
}
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