26 py::module_
np = py::module_::import(
"numpy");
28 check.numpy = np.attr(
"dtype")(np.attr(name));
29 check.pybind11 = py::dtype::of<T>();
35 get_dtype_check<std::int8_t>(
"int8"),
36 get_dtype_check<std::uint8_t>(
"uint8"),
37 get_dtype_check<std::int16_t>(
"int16"),
38 get_dtype_check<std::uint16_t>(
"uint16"),
39 get_dtype_check<std::int32_t>(
"int32"),
40 get_dtype_check<std::uint32_t>(
"uint32"),
41 get_dtype_check<std::int64_t>(
"int64"),
42 get_dtype_check<std::uint64_t>(
"uint64")};
56 check.name = py::type_id<T>();
57 check.size_cpp =
sizeof(
T);
58 check.dtype = py::dtype::of<T>();
59 check.size_numpy =
check.dtype.attr(
"itemsize").template cast<int>();
65 get_dtype_size_check<short>(),
66 get_dtype_size_check<unsigned short>(),
67 get_dtype_size_check<int>(),
68 get_dtype_size_check<unsigned int>(),
69 get_dtype_size_check<long>(),
70 get_dtype_size_check<unsigned long>(),
71 get_dtype_size_check<long long>(),
72 get_dtype_size_check<unsigned long long>(),
78 using arr_t = py::array_t<uint16_t, 0>;
81 template <
typename... Ix>
83 return arr(a.nbytes() - a.offset_at(index...), (
const uint8_t *) a.data(index...));
86 template <
typename... Ix>
88 return arr(a.size() - a.index_at(index...), a.data(index...));
91 template <
typename... Ix>
93 auto *ptr = (
uint8_t *) a.mutable_data(index...);
94 for (
py::ssize_t i = 0;
i < a.nbytes() - a.offset_at(index...);
i++) {
100 template <
typename... Ix>
102 auto ptr = a.mutable_data(index...);
103 for (
py::ssize_t i = 0;
i < a.size() - a.index_at(index...);
i++) {
109 template <
typename... Ix>
111 return a.index_at(idx...);
113 template <
typename... Ix>
115 return a.index_at(idx...);
117 template <
typename... Ix>
119 return a.offset_at(idx...);
121 template <
typename... Ix>
123 return a.offset_at(idx...);
125 template <
typename... Ix>
129 template <
typename... Ix>
131 a.mutable_at(idx...)++;
135 #define def_index_fn(name, type) \ 136 sm.def(#name, [](type a) { return name(a); }); \ 137 sm.def(#name, [](type a, int i) { return name(a, i); }); \ 138 sm.def(#name, [](type a, int i, int j) { return name(a, i, j); }); \ 139 sm.def(#name, [](type a, int i, int j, int k) { return name(a, i, j, k); }); 141 template <
typename T,
typename T2>
144 throw std::domain_error(
"error: ndim != 2");
147 l.append(*r.data(0, 0));
148 l.append(*
r2.mutable_data(0, 0));
149 l.append(r.data(0, 1) ==
r2.mutable_data(0, 1));
151 l.append(r.itemsize());
152 l.append(r.shape(0));
153 l.append(r.shape(1));
155 l.append(r.nbytes());
164 py::module_::import(
"numpy");
165 }
catch (
const py::error_already_set &) {
170 py::class_<DtypeCheck>(sm,
"DtypeCheck")
178 py::class_<DtypeSizeCheck>(sm,
"DtypeSizeCheck")
183 return py::str(
"<DtypeSizeCheck name='{}' size_cpp={} size_numpy={} dtype={}>")
184 .format(
self.
name,
self.size_cpp,
self.size_numpy,
self.
dtype);
189 sm.def(
"ndim", [](
const arr &
a) {
return a.ndim(); });
190 sm.def(
"shape", [](
const arr &a) {
return arr(a.ndim(), a.shape()); });
191 sm.def(
"shape", [](
const arr &a,
py::ssize_t dim) {
return a.shape(dim); });
192 sm.def(
"strides", [](
const arr &a) {
return arr(a.ndim(), a.strides()); });
193 sm.def(
"strides", [](
const arr &a,
py::ssize_t dim) {
return a.strides(dim); });
194 sm.def(
"writeable", [](
const arr &a) {
return a.writeable(); });
195 sm.def(
"size", [](
const arr &a) {
return a.size(); });
196 sm.def(
"itemsize", [](
const arr &a) {
return a.itemsize(); });
197 sm.def(
"nbytes", [](
const arr &a) {
return a.nbytes(); });
198 sm.def(
"owndata", [](
const arr &a) {
return a.owndata(); });
215 sm.def(
"make_f_array", [] {
return py::array_t<float>({2, 2}, {4, 8}); });
216 sm.def(
"make_c_array", [] {
return py::array_t<float>({2, 2}, {8, 4}); });
219 sm.def(
"make_empty_shaped_array", [] {
return py::array(py::dtype(
"f"), {}, {}); });
221 sm.def(
"scalar_int", []() {
return py::array(py::dtype(
"i"), {}, {}, &
data_i); });
226 {a.shape(), a.shape() + a.ndim()},
227 {a.strides(), a.strides() + a.ndim()},
234 int data[2] = {1, 2};
235 ArrayClass() {
py::print(
"ArrayClass()"); }
236 ~ArrayClass() {
py::print(
"~ArrayClass()"); }
238 py::class_<ArrayClass>(sm,
"ArrayClass")
240 .def(
"numpy_view", [](py::object &obj) {
242 auto &a = obj.cast<ArrayClass &>();
243 return py::array_t<int>({2}, {4}, a.data, obj);
247 sm.def(
"function_taking_uint64", [](
uint64_t) {});
250 sm.def(
"isinstance_untyped", [](py::object yes, py::object no) {
251 return py::isinstance<py::array>(std::move(yes))
252 && !py::isinstance<py::array>(std::move(no));
254 sm.def(
"isinstance_typed", [](
const py::object &o) {
255 return py::isinstance<py::array_t<double>>(o) && !
py::isinstance<py::array_t<int>>(o);
259 sm.def(
"default_constructors", []() {
261 "array_t<int32>"_a = py::array_t<std::int32_t>(),
262 "array_t<double>"_a = py::array_t<double>());
264 sm.def(
"converting_constructors", [](
const py::object &o) {
265 return py::dict(
"array"_a =
py::array(o),
266 "array_t<int32>"_a = py::array_t<std::int32_t>(o),
267 "array_t<double>"_a = py::array_t<double>(o));
271 sm.def(
"overloaded", [](
const py::array_t<double> &) {
return "double"; });
272 sm.def(
"overloaded", [](
const py::array_t<float> &) {
return "float"; });
273 sm.def(
"overloaded", [](
const py::array_t<int> &) {
return "int"; });
274 sm.def(
"overloaded", [](
const py::array_t<unsigned short> &) {
return "unsigned short"; });
275 sm.def(
"overloaded", [](
const py::array_t<long long> &) {
return "long long"; });
277 [](
const py::array_t<std::complex<double>> &) {
return "double complex"; });
278 sm.def(
"overloaded", [](
const py::array_t<std::complex<float>> &) {
return "float complex"; });
280 sm.def(
"overloaded2",
281 [](
const py::array_t<std::complex<double>> &) {
return "double complex"; });
282 sm.def(
"overloaded2", [](
const py::array_t<double> &) {
return "double"; });
283 sm.def(
"overloaded2",
284 [](
const py::array_t<std::complex<float>> &) {
return "float complex"; });
285 sm.def(
"overloaded2", [](
const py::array_t<float> &) {
return "float"; });
291 "overloaded3", [](
const py::array_t<int> &) {
return "int"; },
py::arg{}.noconvert());
294 [](
const py::array_t<double> &) {
return "double"; },
299 sm.def(
"overloaded4", [](
const py::array_t<long long, 0> &) {
return "long long"; });
300 sm.def(
"overloaded4", [](
const py::array_t<double, 0> &) {
return "double"; });
304 sm.def(
"overloaded5", [](
const py::array_t<unsigned int> &) {
return "unsigned int"; });
305 sm.def(
"overloaded5", [](
const py::array_t<double> &) {
return "double"; });
309 sm.def(
"issue685", [](
const std::string &) {
return "string"; });
310 sm.def(
"issue685", [](
const py::array &) {
return "array"; });
311 sm.def(
"issue685", [](
const py::object &) {
return "other"; });
316 [](py::array_t<double> a,
double v) {
317 auto r = a.mutable_unchecked<2>();
327 sm.def(
"proxy_init3", [](
double start) {
328 py::array_t<double, py::array::c_style>
a({3, 3, 3});
329 auto r = a.mutable_unchecked<3>();
333 r(
i,
j, k) = start++;
339 sm.def(
"proxy_init3F", [](
double start) {
340 py::array_t<double, py::array::f_style>
a({3, 3, 3});
341 auto r = a.mutable_unchecked<3>();
345 r(
i,
j, k) = start++;
351 sm.def(
"proxy_squared_L2_norm", [](
const py::array_t<double> &a) {
352 auto r = a.unchecked<1>();
355 sumsq += r[
i] * r(
i);
360 sm.def(
"proxy_auxiliaries2", [](py::array_t<double> a) {
361 auto r = a.unchecked<2>();
362 auto r2 = a.mutable_unchecked<2>();
366 sm.def(
"proxy_auxiliaries1_const_ref", [](py::array_t<double> a) {
367 const auto &r = a.unchecked<1>();
368 const auto &
r2 = a.mutable_unchecked<1>();
369 return r(0) ==
r2(0) && r[0] ==
r2[0];
372 sm.def(
"proxy_auxiliaries2_const_ref", [](py::array_t<double> a) {
373 const auto &r = a.unchecked<2>();
374 const auto &
r2 = a.mutable_unchecked<2>();
375 return r(0, 0) ==
r2(0, 0);
382 [](py::array_t<double> a,
double v) {
383 auto r = a.mutable_unchecked();
385 throw std::domain_error(
"error: ndim != 2");
395 sm.def(
"proxy_init3_dyn", [](
double start) {
396 py::array_t<double, py::array::c_style>
a({3, 3, 3});
397 auto r = a.mutable_unchecked();
399 throw std::domain_error(
"error: ndim != 3");
404 r(
i,
j, k) = start++;
410 sm.def(
"proxy_auxiliaries2_dyn", [](py::array_t<double> a) {
411 return auxiliaries(a.unchecked(), a.mutable_unchecked());
414 sm.def(
"array_auxiliaries2", [](py::array_t<double> a) {
return auxiliaries(a, a); });
419 sm.def(
"array_fail_test", []() {
return py::array(py::object()); });
420 sm.def(
"array_t_fail_test", []() {
return py::array_t<double>(py::object()); });
422 sm.def(
"array_fail_test_negative_size", []() {
429 sm.def(
"array_initializer_list1", []() {
return py::array_t<float>(1); });
431 sm.def(
"array_initializer_list2", []() {
return py::array_t<float>({1, 2}); });
432 sm.def(
"array_initializer_list3", []() {
return py::array_t<float>({1, 2, 3}); });
433 sm.def(
"array_initializer_list4", []() {
return py::array_t<float>({1, 2, 3, 4}); });
437 sm.def(
"array_reshape2", [](py::array_t<double> a) {
439 if (dim_sz * dim_sz != a.size()) {
440 throw std::domain_error(
441 "array_reshape2: input array total size is not a squared integer");
443 a.resize({dim_sz, dim_sz});
447 sm.def(
"array_resize3", [](py::array_t<double> a,
size_t N,
bool refcheck) {
448 a.resize({
N,
N, N}, refcheck);
453 sm.def(
"create_and_resize", [](
size_t N) {
454 py::array_t<double>
a;
456 std::fill(a.mutable_data(), a.mutable_data() + a.size(), 42.);
461 [](py::array_t<uint8_t> a,
const std::string &
dtype) {
return a.view(dtype); });
463 sm.def(
"reshape_initializer_list", [](py::array_t<int> a,
size_t N,
size_t M,
size_t O) {
464 return a.reshape({
N,
M, O});
466 sm.def(
"reshape_tuple", [](py::array_t<int> a,
const std::vector<int> &new_shape) {
467 return a.reshape(new_shape);
470 sm.def(
"index_using_ellipsis",
475 "accept_double", [](
const py::array_t<double, 0> &) {},
py::arg(
"a"));
477 "accept_double_forcecast",
478 [](
const py::array_t<double, py::array::forcecast> &) {},
481 "accept_double_c_style",
482 [](
const py::array_t<double, py::array::c_style> &) {},
485 "accept_double_c_style_forcecast",
486 [](
const py::array_t<double, py::array::forcecast | py::array::c_style> &) {},
489 "accept_double_f_style",
490 [](
const py::array_t<double, py::array::f_style> &) {},
493 "accept_double_f_style_forcecast",
494 [](
const py::array_t<double, py::array::forcecast | py::array::f_style> &) {},
497 "accept_double_noconvert", [](
const py::array_t<double, 0> &) {},
"a"_a.noconvert());
499 "accept_double_forcecast_noconvert",
500 [](
const py::array_t<double, py::array::forcecast> &) {},
503 "accept_double_c_style_noconvert",
504 [](
const py::array_t<double, py::array::c_style> &) {},
507 "accept_double_c_style_forcecast_noconvert",
508 [](
const py::array_t<double, py::array::forcecast | py::array::c_style> &) {},
511 "accept_double_f_style_noconvert",
512 [](
const py::array_t<double, py::array::f_style> &) {},
515 "accept_double_f_style_forcecast_noconvert",
516 [](
const py::array_t<double, py::array::forcecast | py::array::f_style> &) {},
520 sm.def(
"test_fmt_desc_float", [](
const py::array_t<float> &) {});
521 sm.def(
"test_fmt_desc_double", [](
const py::array_t<double> &) {});
522 sm.def(
"test_fmt_desc_const_float", [](
const py::array_t<const float> &) {});
523 sm.def(
"test_fmt_desc_const_double", [](
const py::array_t<const double> &) {});
TEST_SUBMODULE(numpy_array, sm)
Matrix< RealScalar, Dynamic, Dynamic > M
DtypeSizeCheck get_dtype_size_check()
py::array_t< uint16_t, 0 > arr_t
arr_t & mutate_at_t(arr_t &a, Ix... idx)
arr_t & mutate_data_t(arr_t &a, Ix... index)
static const Pose3 T2(Rot3::Rodrigues(0.3, 0.2, 0.1), P2)
EIGEN_STRONG_INLINE Packet4f print(const Packet4f &a)
bool isinstance(handle obj)
arr data(const arr &a, Ix... index)
static const Line3 l(Rot3(), 1, 1)
py::handle auxiliaries(T &&r, T2 &&r2)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArgReturnType arg() const
Array< int, Dynamic, 1 > v
unsigned __int64 uint64_t
Eigen::Triplet< double > T
#define def_index_fn(name, type)
py::ssize_t index_at_t(const arr_t &a, Ix... idx)
std::vector< DtypeCheck > get_concrete_dtype_checks()
void check(bool b, bool ref)
arr & mutate_data(arr &a, Ix... index)
py::ssize_t index_at(const arr &a, Ix... idx)
py::ssize_t offset_at_t(const arr_t &a, Ix... idx)
std::vector< DtypeSizeCheck > get_platform_dtype_size_checks()
Jet< T, N > sqrt(const Jet< T, N > &f)
Annotation for function names.
py::ssize_t offset_at(const arr &a, Ix... idx)
py::ssize_t at_t(const arr_t &a, Ix... idx)
DtypeCheck get_dtype_check(const char *name)
arr data_t(const arr_t &a, Ix... index)