]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/python/src/numpy/ndarray.cpp
1 // Copyright Jim Bosch 2010-2012.
2 // Copyright Stefan Seefeld 2016.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 #define BOOST_PYTHON_NUMPY_INTERNAL
8 #include <boost/python/numpy/internal.hpp>
9 #include <boost/scoped_array.hpp>
11 namespace boost
{ namespace python
{
14 NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArray_Type
, numpy::ndarray
)
15 } // namespace boost::python::converter
22 ndarray::bitflag
numpy_to_bitflag(int const f
)
24 ndarray::bitflag r
= ndarray::NONE
;
25 if (f
& NPY_C_CONTIGUOUS
) r
= (r
| ndarray::C_CONTIGUOUS
);
26 if (f
& NPY_F_CONTIGUOUS
) r
= (r
| ndarray::F_CONTIGUOUS
);
27 if (f
& NPY_ALIGNED
) r
= (r
| ndarray::ALIGNED
);
28 if (f
& NPY_WRITEABLE
) r
= (r
| ndarray::WRITEABLE
);
32 int bitflag_to_numpy(ndarray::bitflag f
)
35 if (f
& ndarray::C_CONTIGUOUS
) r
|= NPY_C_CONTIGUOUS
;
36 if (f
& ndarray::F_CONTIGUOUS
) r
|= NPY_F_CONTIGUOUS
;
37 if (f
& ndarray::ALIGNED
) r
|= NPY_ALIGNED
;
38 if (f
& ndarray::WRITEABLE
) r
|= NPY_WRITEABLE
;
42 bool is_c_contiguous(std::vector
<Py_intptr_t
> const & shape
,
43 std::vector
<Py_intptr_t
> const & strides
,
46 std::vector
<Py_intptr_t
>::const_reverse_iterator j
= strides
.rbegin();
48 for (std::vector
<Py_intptr_t
>::const_reverse_iterator i
= shape
.rbegin(); i
!= shape
.rend(); ++i
, ++j
)
50 if (total
!= *j
) return false;
56 bool is_f_contiguous(std::vector
<Py_intptr_t
> const & shape
,
57 std::vector
<Py_intptr_t
> const & strides
,
60 std::vector
<Py_intptr_t
>::const_iterator j
= strides
.begin();
62 for (std::vector
<Py_intptr_t
>::const_iterator i
= shape
.begin(); i
!= shape
.end(); ++i
, ++j
)
64 if (total
!= *j
) return false;
70 bool is_aligned(std::vector
<Py_intptr_t
> const & strides
,
73 for (std::vector
<Py_intptr_t
>::const_iterator i
= strides
.begin(); i
!= strides
.end(); ++i
)
75 if (*i
% itemsize
) return false;
80 inline PyArray_Descr
* incref_dtype(dtype
const & dt
)
83 return reinterpret_cast<PyArray_Descr
*>(dt
.ptr());
86 ndarray
from_data_impl(void * data
,
88 python::object
const & shape
,
89 python::object
const & strides
,
90 python::object
const & owner
,
93 std::vector
<Py_intptr_t
> shape_(len(shape
));
94 std::vector
<Py_intptr_t
> strides_(len(strides
));
95 if (shape_
.size() != strides_
.size())
97 PyErr_SetString(PyExc_ValueError
, "Length of shape and strides arrays do not match.");
98 python::throw_error_already_set();
100 for (std::size_t i
= 0; i
< shape_
.size(); ++i
)
102 shape_
[i
] = python::extract
<Py_intptr_t
>(shape
[i
]);
103 strides_
[i
] = python::extract
<Py_intptr_t
>(strides
[i
]);
105 return from_data_impl(data
, dt
, shape_
, strides_
, owner
, writeable
);
108 ndarray
from_data_impl(void * data
,
110 std::vector
<Py_intptr_t
> const & shape
,
111 std::vector
<Py_intptr_t
> const & strides
,
112 python::object
const & owner
,
115 if (shape
.size() != strides
.size())
117 PyErr_SetString(PyExc_ValueError
, "Length of shape and strides arrays do not match.");
118 python::throw_error_already_set();
120 int itemsize
= dt
.get_itemsize();
122 if (writeable
) flags
|= NPY_WRITEABLE
;
123 if (is_c_contiguous(shape
, strides
, itemsize
)) flags
|= NPY_C_CONTIGUOUS
;
124 if (is_f_contiguous(shape
, strides
, itemsize
)) flags
|= NPY_F_CONTIGUOUS
;
125 if (is_aligned(strides
, itemsize
)) flags
|= NPY_ALIGNED
;
126 ndarray
r(python::detail::new_reference
127 (PyArray_NewFromDescr(&PyArray_Type
,
130 const_cast<Py_intptr_t
*>(&shape
.front()),
131 const_cast<Py_intptr_t
*>(&strides
.front()),
139 } // namespace detail
141 ndarray
ndarray::view(dtype
const & dt
) const
143 return ndarray(python::detail::new_reference
144 (PyObject_CallMethod(this->ptr(), const_cast<char*>("view"), const_cast<char*>("O"), dt
.ptr())));
147 ndarray
ndarray::astype(dtype
const & dt
) const
149 return ndarray(python::detail::new_reference
150 (PyObject_CallMethod(this->ptr(), const_cast<char*>("astype"), const_cast<char*>("O"), dt
.ptr())));
153 ndarray
ndarray::copy() const
155 return ndarray(python::detail::new_reference
156 (PyObject_CallMethod(this->ptr(), const_cast<char*>("copy"), const_cast<char*>(""))));
159 dtype
ndarray::get_dtype() const
161 return dtype(python::detail::borrowed_reference(get_struct()->descr
));
164 python::object
ndarray::get_base() const
166 if (get_struct()->base
== NULL
) return object();
167 return python::object(python::detail::borrowed_reference(get_struct()->base
));
170 void ndarray::set_base(object
const & base
)
172 Py_XDECREF(get_struct()->base
);
173 if (base
!= object())
175 Py_INCREF(base
.ptr());
176 get_struct()->base
= base
.ptr();
180 get_struct()->base
= NULL
;
184 ndarray::bitflag
ndarray::get_flags() const
186 return numpy::detail::numpy_to_bitflag(get_struct()->flags
);
189 ndarray
ndarray::transpose() const
191 return ndarray(python::detail::new_reference
192 (PyArray_Transpose(reinterpret_cast<PyArrayObject
*>(this->ptr()), NULL
)));
195 ndarray
ndarray::squeeze() const
197 return ndarray(python::detail::new_reference
198 (PyArray_Squeeze(reinterpret_cast<PyArrayObject
*>(this->ptr()))));
201 ndarray
ndarray::reshape(python::tuple
const & shape
) const
203 return ndarray(python::detail::new_reference
204 (PyArray_Reshape(reinterpret_cast<PyArrayObject
*>(this->ptr()), shape
.ptr())));
207 python::object
ndarray::scalarize() const
210 return python::object(python::detail::new_reference(PyArray_Return(reinterpret_cast<PyArrayObject
*>(ptr()))));
213 ndarray
zeros(python::tuple
const & shape
, dtype
const & dt
)
216 boost::scoped_array
<Py_intptr_t
> dims(new Py_intptr_t
[nd
]);
217 for (int n
=0; n
<nd
; ++n
) dims
[n
] = python::extract
<Py_intptr_t
>(shape
[n
]);
218 return ndarray(python::detail::new_reference
219 (PyArray_Zeros(nd
, dims
.get(), detail::incref_dtype(dt
), 0)));
222 ndarray
zeros(int nd
, Py_intptr_t
const * shape
, dtype
const & dt
)
224 return ndarray(python::detail::new_reference
225 (PyArray_Zeros(nd
, const_cast<Py_intptr_t
*>(shape
), detail::incref_dtype(dt
), 0)));
228 ndarray
empty(python::tuple
const & shape
, dtype
const & dt
)
231 boost::scoped_array
<Py_intptr_t
> dims(new Py_intptr_t
[nd
]);
232 for (int n
=0; n
<nd
; ++n
) dims
[n
] = python::extract
<Py_intptr_t
>(shape
[n
]);
233 return ndarray(python::detail::new_reference
234 (PyArray_Empty(nd
, dims
.get(), detail::incref_dtype(dt
), 0)));
237 ndarray
empty(int nd
, Py_intptr_t
const * shape
, dtype
const & dt
)
239 return ndarray(python::detail::new_reference
240 (PyArray_Empty(nd
, const_cast<Py_intptr_t
*>(shape
), detail::incref_dtype(dt
), 0)));
243 ndarray
array(python::object
const & obj
)
245 return ndarray(python::detail::new_reference
246 (PyArray_FromAny(obj
.ptr(), NULL
, 0, 0, NPY_ENSUREARRAY
, NULL
)));
249 ndarray
array(python::object
const & obj
, dtype
const & dt
)
251 return ndarray(python::detail::new_reference
252 (PyArray_FromAny(obj
.ptr(), detail::incref_dtype(dt
), 0, 0, NPY_ENSUREARRAY
, NULL
)));
255 ndarray
from_object(python::object
const & obj
, dtype
const & dt
, int nd_min
, int nd_max
, ndarray::bitflag flags
)
257 int requirements
= detail::bitflag_to_numpy(flags
);
258 return ndarray(python::detail::new_reference
259 (PyArray_FromAny(obj
.ptr(),
260 detail::incref_dtype(dt
),
266 ndarray
from_object(python::object
const & obj
, int nd_min
, int nd_max
, ndarray::bitflag flags
)
268 int requirements
= detail::bitflag_to_numpy(flags
);
269 return ndarray(python::detail::new_reference
270 (PyArray_FromAny(obj
.ptr(),
277 }}} // namespace boost::python::numpy