31 #ifdef INCLUDE_BOOST_PYTHON_INTERFACE
43 #include "boost/python.hpp"
44 #include "boost/python/numpy.hpp"
48 namespace boostPythonInterface
52 template<
typename dtype>
66 theArray_(inArray.
astype(boost::python::numpy::dtype::get_builtin<dtype>())),
67 numDimensions_(static_cast<
uint8>(inArray.get_nd())),
68 shape_(numDimensions_),
69 strides_(numDimensions_),
73 Py_intptr_t
const * shapePtr = inArray.get_shape();
74 for (
uint8 i = 0; i < numDimensions_; ++i)
76 strides_[i] =
static_cast<uint32>(theArray_.strides(i));
77 shape_[i] = shapePtr[i];
80 if (numDimensions_ > 1 && inArray.strides(0) < inArray.strides(1))
92 theArray_(boost::python::numpy::
zeros(inShape, boost::python::numpy::dtype::get_builtin<dtype>())),
93 numDimensions_(static_cast<
uint8>(theArray_.get_nd())),
94 shape_(numDimensions_),
95 strides_(numDimensions_),
98 Py_intptr_t
const * shapePtr = theArray_.get_shape();
99 for (
uint8 i = 0; i < numDimensions_; ++i)
101 strides_[i] =
static_cast<uint32>(theArray_.strides(i));
102 shape_[i] = shapePtr[i];
105 if (numDimensions_ > 1 && theArray_.strides(0) < theArray_.strides(1))
118 const boost::python::numpy::ndarray&
getArray() noexcept
130 return boost::python::numpy::matrix(theArray_);
140 return numDimensions_;
148 const std::vector<Py_intptr_t>&
shape() noexcept
161 for (
auto dimSize : shape_)
163 theSize *=
static_cast<uint32>(dimSize);
198 if (shape_.size() != otherNdarrayHelper.shape_.size())
215 checkIndices1D(index);
217 return *
reinterpret_cast<dtype*
>(theArray_.get_data() + strides_.front() * index);
230 checkIndices2D(index1, index2);
232 return *
reinterpret_cast<dtype*
>(theArray_.get_data() + strides_.front() * index1 + strides_[1] * index2);
240 printf(
"array = \n");
241 if (numDimensions_ != 1)
243 std::cout <<
"printArray1D can only be used on a 1D array." << std::endl;
247 for (
int32 i = 0; i < shape_.front(); ++i)
249 printf(
"\t%f\n",
operator()(i));
258 printf(
"array = \n");
259 if (numDimensions_ != 2)
261 std::cout <<
"printArray2D can only be used on a 2D array." << std::endl;
265 for (
int32 index1 = 0; index1 < shape_.front(); ++index1)
267 for (
int32 index2 = 0; index2 < shape_.back(); ++index2)
269 printf(
"\t%f",
operator()(index1, index2));
277 boost::python::numpy::ndarray theArray_;
278 uint8 numDimensions_;
279 std::vector<Py_intptr_t> shape_;
280 std::vector<uint32> strides_;
288 void checkIndicesGeneric(boost::python::tuple indices)
290 if (boost::python::len(indices) != numDimensions_)
292 std::string errStr =
"Error: BoostNdarrayHelper::checkIndicesGeneric: Array has " +
utils::num2str(numDimensions_);
293 errStr +=
" dimensions, you asked for " +
utils::num2str(
static_cast<int>(boost::python::len(indices))) +
"!";
294 PyErr_SetString(PyExc_RuntimeError, errStr.c_str());
297 for (
int i = 0; i < numDimensions_; ++i)
299 int index = boost::python::extract<int>(indices[i]);
300 if (index > shape_[i])
302 std::string errStr =
"Error: BoostNdarrayHelper::checkIndicesGeneric: Input index [" +
utils::num2str(index);
303 errStr +=
"] is larger than the size of the array [" +
utils::num2str(shape_[i]) +
"].";
304 PyErr_SetString(PyExc_RuntimeError, errStr.c_str());
314 void checkIndices1D(
uint32 index)
316 boost::python::tuple indices = boost::python::make_tuple(index);
317 checkIndicesGeneric(indices);
328 boost::python::tuple indices = boost::python::make_tuple(index1, index2);
329 checkIndicesGeneric(indices);