30 #if defined(INCLUDE_BOOST_PYTHON_INTERFACE) && !defined(NO_USE_BOOST)
42 #include "boost/python.hpp"
43 #include "boost/python/numpy.hpp"
47 namespace boostPythonInterface
51 template<
typename dtype>
65 theArray_(inArray.
astype(boost::python::numpy::dtype::get_builtin<dtype>())),
66 numDimensions_(static_cast<
uint8>(inArray.get_nd())),
67 shape_(numDimensions_),
68 strides_(numDimensions_),
72 Py_intptr_t
const * shapePtr = inArray.get_shape();
73 for (
uint8 i = 0; i < numDimensions_; ++i)
75 strides_[i] =
static_cast<uint32>(theArray_.strides(i));
76 shape_[i] = shapePtr[i];
79 if (numDimensions_ > 1 && inArray.strides(0) < inArray.strides(1))
91 theArray_(boost::python::numpy::
zeros(inShape, boost::python::numpy::dtype::get_builtin<dtype>())),
92 numDimensions_(static_cast<
uint8>(theArray_.get_nd())),
93 shape_(numDimensions_),
94 strides_(numDimensions_),
97 Py_intptr_t
const * shapePtr = theArray_.get_shape();
98 for (
uint8 i = 0; i < numDimensions_; ++i)
100 strides_[i] =
static_cast<uint32>(theArray_.strides(i));
101 shape_[i] = shapePtr[i];
104 if (numDimensions_ > 1 && theArray_.strides(0) < theArray_.strides(1))
117 const boost::python::numpy::ndarray&
getArray() noexcept
129 return boost::python::numpy::matrix(theArray_);
139 return numDimensions_;
147 const std::vector<Py_intptr_t>&
shape() noexcept
160 for (
auto dimSize : shape_)
162 theSize *=
static_cast<uint32>(dimSize);
197 if (shape_.size() != otherNdarrayHelper.shape_.size())
214 checkIndices1D(index);
216 return *
reinterpret_cast<dtype*
>(theArray_.get_data() + strides_.front() * index);
229 checkIndices2D(index1, index2);
231 return *
reinterpret_cast<dtype*
>(theArray_.get_data() + strides_.front() * index1 + strides_[1] * index2);
239 printf(
"array = \n");
240 if (numDimensions_ != 1)
242 std::cout <<
"printArray1D can only be used on a 1D array." << std::endl;
246 for (
int32 i = 0; i < shape_.front(); ++i)
248 printf(
"\t%f\n",
operator()(i));
257 printf(
"array = \n");
258 if (numDimensions_ != 2)
260 std::cout <<
"printArray2D can only be used on a 2D array." << std::endl;
264 for (
int32 index1 = 0; index1 < shape_.front(); ++index1)
266 for (
int32 index2 = 0; index2 < shape_.back(); ++index2)
268 printf(
"\t%f",
operator()(index1, index2));
276 boost::python::numpy::ndarray theArray_;
277 uint8 numDimensions_;
278 std::vector<Py_intptr_t> shape_;
279 std::vector<uint32> strides_;
287 void checkIndicesGeneric(boost::python::tuple indices)
289 if (boost::python::len(indices) != numDimensions_)
291 std::string errStr =
"Error: BoostNdarrayHelper::checkIndicesGeneric: Array has " +
utils::num2str(numDimensions_);
292 errStr +=
" dimensions, you asked for " +
utils::num2str(
static_cast<int>(boost::python::len(indices))) +
"!";
293 PyErr_SetString(PyExc_RuntimeError, errStr.c_str());
296 for (
int i = 0; i < numDimensions_; ++i)
298 int index = boost::python::extract<int>(indices[i]);
299 if (index > shape_[i])
301 std::string errStr =
"Error: BoostNdarrayHelper::checkIndicesGeneric: Input index [" +
utils::num2str(index);
302 errStr +=
"] is larger than the size of the array [" +
utils::num2str(shape_[i]) +
"].";
303 PyErr_SetString(PyExc_RuntimeError, errStr.c_str());
313 void checkIndices1D(
uint32 index)
315 boost::python::tuple indices = boost::python::make_tuple(index);
316 checkIndicesGeneric(indices);
327 boost::python::tuple indices = boost::python::make_tuple(index1, index2);
328 checkIndicesGeneric(indices);
334 #endif // #if defined(INCLUDE_BOOST_PYTHON_INTERFACE) && !defined(NO_USE_BOOST)