Created
June 1, 2012 06:50
-
-
Save jjlin18/2849675 to your computer and use it in GitHub Desktop.
sample code for get and return numpy in C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// From http://stackoverflow.com/questions/9128519/reading-many-values-from-numpy-c-api | |
/* | |
Make | |
g++ -o matrix_multiply.o -c matrix_multiply.cpp -I{python include file for numpy/noprefix.h} -I{python include} -fPIC -O2 -Wno-deprecated -Wno-write-strings | |
g++ -o matrix_multiply.so -shared matrix_multiply.o -L{boost lib path} -lz -lm -ldl -lpthread -boost_python | |
Python code: | |
import numpy | |
import matrix_multiply | |
a = numpy.arange(1.0, 13.0,1.0) | |
b = a.reshape(3,4) | |
x = matrix_multiply.multiply( b, 4.0) | |
*/ | |
#include <boost/python.hpp> | |
#include <exception> | |
#include <numpy/arrayobject.h> | |
using namespace boost::python; | |
struct WrongSizeError : public std::exception { | |
const char* what() const throw() { return "Unsupported array size."; } | |
}; | |
struct WrongTypeError : public std::exception { | |
const char* what() const throw() { return "Unsupported array type."; } | |
}; | |
// Boost::Python needs the translators | |
void translate_sz(const WrongSizeError& e) | |
{ | |
PyErr_SetString(PyExc_RuntimeError, e.what()); | |
} | |
void translate_ty(const WrongTypeError& e) | |
{ | |
PyErr_SetString(PyExc_RuntimeError, e.what()); | |
} | |
// multiply matrix of double (m) by f | |
object multiply(numeric::array m, double f) | |
{ | |
PyObject* m_obj = PyArray_FROM_OTF(m.ptr(), NPY_DOUBLE, NPY_IN_ARRAY); | |
if (!m_obj) | |
throw WrongTypeError(); | |
// to avoid memory leaks, let a Boost::Python object manage the array | |
object temp(handle<>(m_obj)); | |
// check that m is a matrix of doubles | |
int k = PyArray_NDIM(m_obj); | |
if (k != 2) | |
throw WrongSizeError(); | |
// get direct access to the array data | |
const double* data = static_cast<const double*>(PyArray_DATA(m_obj)); | |
// make the output array, and get access to its data | |
PyObject* res = PyArray_SimpleNew(2, PyArray_DIMS(m_obj), NPY_DOUBLE); | |
double* res_data = static_cast<double*>(PyArray_DATA(res)); | |
const unsigned size = PyArray_SIZE(m_obj); // number of elements in array | |
for (unsigned i = 0; i < size; ++i) | |
res_data[i] = f*data[i]; | |
return object(handle<>(res)); // go back to using Boost::Python constructs | |
} | |
BOOST_PYTHON_MODULE(test) | |
{ | |
// register exception translators | |
register_exception_translator<WrongSizeError>(&translate_sz); | |
register_exception_translator<WrongTypeError>(&translate_ty); | |
// tell Boost::Python under what name the array is known | |
numeric::array::set_module_and_type("numpy", "ndarray"); | |
def("multiply", multiply); | |
// initialize the Numpy C API | |
import_array(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment