]>
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_ARRAY_C_CONTIGUOUS
) r
= (r
| ndarray::C_CONTIGUOUS
);
26 if (f
& NPY_ARRAY_F_CONTIGUOUS
) r
= (r
| ndarray::F_CONTIGUOUS
);
27 if (f
& NPY_ARRAY_ALIGNED
) r
= (r
| ndarray::ALIGNED
);
28 if (f
& NPY_ARRAY_WRITEABLE
) r
= (r
| ndarray::WRITEABLE
);
32 int bitflag_to_numpy(ndarray::bitflag f
)
35 if (f
& ndarray::C_CONTIGUOUS
) r
|= NPY_ARRAY_C_CONTIGUOUS
;
36 if (f
& ndarray::F_CONTIGUOUS
) r
|= NPY_ARRAY_F_CONTIGUOUS
;
37 if (f
& ndarray::ALIGNED
) r
|= NPY_ARRAY_ALIGNED
;
38 if (f
& ndarray::WRITEABLE
) r
|= NPY_ARRAY_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_ARRAY_WRITEABLE
;
123 if (is_c_contiguous(shape
, strides
, itemsize
)) flags
|= NPY_ARRAY_C_CONTIGUOUS
;
124 if (is_f_contiguous(shape
, strides
, itemsize
)) flags
|= NPY_ARRAY_F_CONTIGUOUS
;
125 if (is_aligned(strides
, itemsize
)) flags
|= NPY_ARRAY_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
142 int normalize_index(int n
,int nlim
) // wraps [-nlim:nlim) into [0:nlim), throw IndexError otherwise
145 n
+= nlim
; // negative indices work backwards from end
146 if (n
< 0 || n
>= nlim
)
148 PyErr_SetObject(PyExc_IndexError
, Py_None
);
149 throw_error_already_set();
155 Py_intptr_t
ndarray::shape(int n
) const
157 return get_shape()[normalize_index(n
,get_nd())];
160 Py_intptr_t
ndarray::strides(int n
) const
162 return get_strides()[normalize_index(n
,get_nd())];
165 ndarray
ndarray::view(dtype
const & dt
) const
167 return ndarray(python::detail::new_reference
168 (PyObject_CallMethod(this->ptr(), const_cast<char*>("view"), const_cast<char*>("O"), dt
.ptr())));
171 ndarray
ndarray::astype(dtype
const & dt
) const
173 return ndarray(python::detail::new_reference
174 (PyObject_CallMethod(this->ptr(), const_cast<char*>("astype"), const_cast<char*>("O"), dt
.ptr())));
177 ndarray
ndarray::copy() const
179 return ndarray(python::detail::new_reference
180 (PyObject_CallMethod(this->ptr(), const_cast<char*>("copy"), const_cast<char*>(""))));
183 dtype
ndarray::get_dtype() const
185 return dtype(python::detail::borrowed_reference(get_struct()->descr
));
188 python::object
ndarray::get_base() const
190 if (get_struct()->base
== NULL
) return object();
191 return python::object(python::detail::borrowed_reference(get_struct()->base
));
194 void ndarray::set_base(object
const & base
)
196 Py_XDECREF(get_struct()->base
);
199 Py_INCREF(base
.ptr());
200 get_struct()->base
= base
.ptr();
204 get_struct()->base
= NULL
;
208 ndarray::bitflag
ndarray::get_flags() const
210 return numpy::detail::numpy_to_bitflag(get_struct()->flags
);
213 ndarray
ndarray::transpose() const
215 return ndarray(python::detail::new_reference
216 (PyArray_Transpose(reinterpret_cast<PyArrayObject
*>(this->ptr()), NULL
)));
219 ndarray
ndarray::squeeze() const
221 return ndarray(python::detail::new_reference
222 (PyArray_Squeeze(reinterpret_cast<PyArrayObject
*>(this->ptr()))));
225 ndarray
ndarray::reshape(python::tuple
const & shape
) const
227 return ndarray(python::detail::new_reference
228 (PyArray_Reshape(reinterpret_cast<PyArrayObject
*>(this->ptr()), shape
.ptr())));
231 python::object
ndarray::scalarize() const
234 return python::object(python::detail::new_reference(PyArray_Return(reinterpret_cast<PyArrayObject
*>(ptr()))));
237 ndarray
zeros(python::tuple
const & shape
, dtype
const & dt
)
240 boost::scoped_array
<Py_intptr_t
> dims(new Py_intptr_t
[nd
]);
241 for (int n
=0; n
<nd
; ++n
) dims
[n
] = python::extract
<Py_intptr_t
>(shape
[n
]);
242 return ndarray(python::detail::new_reference
243 (PyArray_Zeros(nd
, dims
.get(), detail::incref_dtype(dt
), 0)));
246 ndarray
zeros(int nd
, Py_intptr_t
const * shape
, dtype
const & dt
)
248 return ndarray(python::detail::new_reference
249 (PyArray_Zeros(nd
, const_cast<Py_intptr_t
*>(shape
), detail::incref_dtype(dt
), 0)));
252 ndarray
empty(python::tuple
const & shape
, dtype
const & dt
)
255 boost::scoped_array
<Py_intptr_t
> dims(new Py_intptr_t
[nd
]);
256 for (int n
=0; n
<nd
; ++n
) dims
[n
] = python::extract
<Py_intptr_t
>(shape
[n
]);
257 return ndarray(python::detail::new_reference
258 (PyArray_Empty(nd
, dims
.get(), detail::incref_dtype(dt
), 0)));
261 ndarray
empty(int nd
, Py_intptr_t
const * shape
, dtype
const & dt
)
263 return ndarray(python::detail::new_reference
264 (PyArray_Empty(nd
, const_cast<Py_intptr_t
*>(shape
), detail::incref_dtype(dt
), 0)));
267 ndarray
array(python::object
const & obj
)
269 return ndarray(python::detail::new_reference
270 (PyArray_FromAny(obj
.ptr(), NULL
, 0, 0, NPY_ARRAY_ENSUREARRAY
, NULL
)));
273 ndarray
array(python::object
const & obj
, dtype
const & dt
)
275 return ndarray(python::detail::new_reference
276 (PyArray_FromAny(obj
.ptr(), detail::incref_dtype(dt
), 0, 0, NPY_ARRAY_ENSUREARRAY
, NULL
)));
279 ndarray
from_object(python::object
const & obj
, dtype
const & dt
, int nd_min
, int nd_max
, ndarray::bitflag flags
)
281 int requirements
= detail::bitflag_to_numpy(flags
);
282 return ndarray(python::detail::new_reference
283 (PyArray_FromAny(obj
.ptr(),
284 detail::incref_dtype(dt
),
290 ndarray
from_object(python::object
const & obj
, int nd_min
, int nd_max
, ndarray::bitflag flags
)
292 int requirements
= detail::bitflag_to_numpy(flags
);
293 return ndarray(python::detail::new_reference
294 (PyArray_FromAny(obj
.ptr(),
301 }}} // namespace boost::python::numpy