30 #if defined(NUMCPP_INCLUDE_BOOST_PYTHON_INTERFACE) && !defined(NUMCPP_NO_USE_BOOST)
42 #include "boost/python.hpp"
43 #include "boost/python/numpy.hpp"
47 namespace boostPythonInterface
51 template<
typename dtype>
52 class BoostNdarrayHelper
57 enum class Order { F, C };
64 explicit BoostNdarrayHelper(
const boost::python::numpy::ndarray& inArray) :
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))
90 explicit BoostNdarrayHelper(boost::python::tuple inShape) :
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
127 boost::python::numpy::matrix getArrayAsMatrix()
129 return boost::python::numpy::matrix(theArray_);
137 uint8 numDimensions() noexcept
139 return numDimensions_;
147 const std::vector<Py_intptr_t>&
shape() noexcept
160 for (
auto dimSize : shape_)
162 theSize *=
static_cast<uint32>(dimSize);
173 const std::vector<uint32>& strides()
195 bool shapeEqual(BoostNdarrayHelper& otherNdarrayHelper)
197 if (shape_.size() != otherNdarrayHelper.shape_.size())
212 dtype& operator()(
uint32 index)
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);
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) noexcept
Definition: StlAlgorithms.hpp:135
std::string num2str(dtype inNumber)
Definition: num2str.hpp:46
Definition: Coordinate.hpp:45
NdArray< dtypeOut > astype(const NdArray< dtype > inArray)
Definition: astype.hpp:47
uint32 size(const NdArray< dtype > &inArray) noexcept
Definition: size.hpp:45
NdArray< dtype > zeros(uint32 inSquareSize)
Definition: zeros.hpp:50
std::int32_t int32
Definition: Types.hpp:36
std::uint8_t uint8
Definition: Types.hpp:42
Shape shape(const NdArray< dtype > &inArray) noexcept
Definition: Functions/Shape.hpp:44
std::uint32_t uint32
Definition: Types.hpp:40