5
5
// Copyright (C) 2017 Rue Yokaze
6
6
// Distributed under the MIT License.
7
7
//
8
- #include < stdint.h>
9
8
#include < boost/multi_array.hpp>
10
9
#include < boost/python.hpp>
11
10
#include < boost/python/numpy.hpp>
12
11
#include < memory>
12
+ #include < stdint.h>
13
13
14
14
// Using from python is avoided because many definitions conflict with names from std.
15
15
namespace python = boost::python;
@@ -48,24 +48,33 @@ namespace python_multi_array
48
48
49
49
namespace impl
50
50
{
51
- template <class T >
51
+ template <class T >
52
52
python::object make_typed_sized (const size_t * s, size_t ndim)
53
53
{
54
54
switch (ndim)
55
55
{
56
- case 1 : return python::object (std::make_shared<multi_array<T, 1 >>(extents[s[0 ]]));
57
- case 2 : return python::object (std::make_shared<multi_array<T, 2 >>(extents[s[0 ]][s[1 ]]));
58
- case 3 : return python::object (std::make_shared<multi_array<T, 3 >>(extents[s[0 ]][s[1 ]][s[2 ]]));
59
- case 4 : return python::object (std::make_shared<multi_array<T, 4 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]]));
60
- case 5 : return python::object (std::make_shared<multi_array<T, 5 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]][s[4 ]]));
61
- case 6 : return python::object (std::make_shared<multi_array<T, 6 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]][s[4 ]][s[5 ]]));
62
- case 7 : return python::object (std::make_shared<multi_array<T, 7 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]][s[4 ]][s[5 ]][s[6 ]]));
63
- case 8 : return python::object (std::make_shared<multi_array<T, 8 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]][s[4 ]][s[5 ]][s[6 ]][s[7 ]]));
64
- default : throw std::invalid_argument (" shape" );
56
+ case 1 :
57
+ return python::object (std::make_shared<multi_array<T, 1 >>(extents[s[0 ]]));
58
+ case 2 :
59
+ return python::object (std::make_shared<multi_array<T, 2 >>(extents[s[0 ]][s[1 ]]));
60
+ case 3 :
61
+ return python::object (std::make_shared<multi_array<T, 3 >>(extents[s[0 ]][s[1 ]][s[2 ]]));
62
+ case 4 :
63
+ return python::object (std::make_shared<multi_array<T, 4 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]]));
64
+ case 5 :
65
+ return python::object (std::make_shared<multi_array<T, 5 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]][s[4 ]]));
66
+ case 6 :
67
+ return python::object (std::make_shared<multi_array<T, 6 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]][s[4 ]][s[5 ]]));
68
+ case 7 :
69
+ return python::object (std::make_shared<multi_array<T, 7 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]][s[4 ]][s[5 ]][s[6 ]]));
70
+ case 8 :
71
+ return python::object (std::make_shared<multi_array<T, 8 >>(extents[s[0 ]][s[1 ]][s[2 ]][s[3 ]][s[4 ]][s[5 ]][s[6 ]][s[7 ]]));
72
+ default :
73
+ throw std::invalid_argument (" shape" );
65
74
}
66
75
}
67
76
68
- template <class T >
77
+ template <class T >
69
78
python::object make_typed (python::object shape)
70
79
{
71
80
python::extract<size_t > scalar_shape (shape);
@@ -86,18 +95,54 @@ namespace python_multi_array
86
95
87
96
python::object make (python::object shape, python::object dtype)
88
97
{
89
- if (dtype == bool8) { return impl::make_typed<bool >(shape); }
90
- else if (dtype == int8) { return impl::make_typed<int8_t >(shape); }
91
- else if (dtype == int16) { return impl::make_typed<int16_t >(shape); }
92
- else if (dtype == int32) { return impl::make_typed<int32_t >(shape); }
93
- else if (dtype == int64) { return impl::make_typed<int16_t >(shape); }
94
- else if (dtype == uint8) { return impl::make_typed<uint8_t >(shape); }
95
- else if (dtype == uint16) { return impl::make_typed<uint16_t >(shape); }
96
- else if (dtype == uint32) { return impl::make_typed<uint32_t >(shape); }
97
- else if (dtype == uint64) { return impl::make_typed<uint64_t >(shape); }
98
- else if (dtype == float32) { return impl::make_typed<float >(shape); }
99
- else if (dtype == float64) { return impl::make_typed<double >(shape); }
100
- else { throw std::invalid_argument (" dtype" ); }
98
+ if (dtype == bool8)
99
+ {
100
+ return impl::make_typed<bool >(shape);
101
+ }
102
+ else if (dtype == int8)
103
+ {
104
+ return impl::make_typed<int8_t >(shape);
105
+ }
106
+ else if (dtype == int16)
107
+ {
108
+ return impl::make_typed<int16_t >(shape);
109
+ }
110
+ else if (dtype == int32)
111
+ {
112
+ return impl::make_typed<int32_t >(shape);
113
+ }
114
+ else if (dtype == int64)
115
+ {
116
+ return impl::make_typed<int16_t >(shape);
117
+ }
118
+ else if (dtype == uint8)
119
+ {
120
+ return impl::make_typed<uint8_t >(shape);
121
+ }
122
+ else if (dtype == uint16)
123
+ {
124
+ return impl::make_typed<uint16_t >(shape);
125
+ }
126
+ else if (dtype == uint32)
127
+ {
128
+ return impl::make_typed<uint32_t >(shape);
129
+ }
130
+ else if (dtype == uint64)
131
+ {
132
+ return impl::make_typed<uint64_t >(shape);
133
+ }
134
+ else if (dtype == float32)
135
+ {
136
+ return impl::make_typed<float >(shape);
137
+ }
138
+ else if (dtype == float64)
139
+ {
140
+ return impl::make_typed<double >(shape);
141
+ }
142
+ else
143
+ {
144
+ throw std::invalid_argument (" dtype" );
145
+ }
101
146
}
102
147
103
148
//
@@ -109,15 +154,15 @@ namespace python_multi_array
109
154
// Example:
110
155
// x[2, 4] = 2.0
111
156
//
112
- template <class T , size_t N>
157
+ template <class T , size_t N>
113
158
T getitem (shared_ptr<multi_array<T, N>> t, python::object idx);
114
159
115
- template <class T , size_t N>
160
+ template <class T , size_t N>
116
161
void setitem (shared_ptr<multi_array<T, N>> t, python::object idx, T value);
117
162
118
163
namespace impl
119
164
{
120
- template <class T , size_t N>
165
+ template <class T , size_t N>
121
166
T getitem_impl (shared_ptr<multi_array<T, N>> t, const size_t * s)
122
167
{
123
168
T* ptr = t->origin ();
@@ -128,7 +173,7 @@ namespace python_multi_array
128
173
return *ptr;
129
174
}
130
175
131
- template <class T , size_t N>
176
+ template <class T , size_t N>
132
177
void setitem_impl (shared_ptr<multi_array<T, N>> t, const size_t * s, T value)
133
178
{
134
179
T* ptr = t->origin ();
@@ -140,7 +185,7 @@ namespace python_multi_array
140
185
}
141
186
}
142
187
143
- template <class T , size_t N>
188
+ template <class T , size_t N>
144
189
T getitem (shared_ptr<multi_array<T, N>> t, python::object idx)
145
190
{
146
191
if (N == 1 )
@@ -160,7 +205,7 @@ namespace python_multi_array
160
205
return impl::getitem_impl (t, s);
161
206
}
162
207
163
- template <class T , size_t N>
208
+ template <class T , size_t N>
164
209
void setitem (shared_ptr<multi_array<T, N>> t, python::object idx, T value)
165
210
{
166
211
if (N == 1 )
@@ -187,7 +232,7 @@ namespace python_multi_array
187
232
//
188
233
// This function resets every element of x with zero.
189
234
//
190
- template <class T , size_t N>
235
+ template <class T , size_t N>
191
236
void reset (shared_ptr<multi_array<T, N>> t)
192
237
{
193
238
std::fill (t->origin (), t->origin () + t->num_elements (), 0 );
@@ -201,7 +246,7 @@ namespace python_multi_array
201
246
// uint16, uint32, uint64, int8, int16, int32, int64, float32,
202
247
// float64, all defined in numpy.
203
248
//
204
- template <class T , size_t N>
249
+ template <class T , size_t N>
205
250
python::object element (shared_ptr<multi_array<T, N>> t)
206
251
{
207
252
return python::numpy::dtype::get_builtin<T>();
@@ -213,21 +258,30 @@ namespace python_multi_array
213
258
//
214
259
// return: the shape of the array.
215
260
//
216
- template <class T , size_t N>
261
+ template <class T , size_t N>
217
262
python::object shape (shared_ptr<multi_array<T, N>> t)
218
263
{
219
264
const size_t * s = t->shape ();
220
265
switch (N)
221
266
{
222
- case 1 : return python::make_tuple (s[0 ]);
223
- case 2 : return python::make_tuple (s[0 ], s[1 ]);
224
- case 3 : return python::make_tuple (s[0 ], s[1 ], s[2 ]);
225
- case 4 : return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ]);
226
- case 5 : return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ], s[4 ]);
227
- case 6 : return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ], s[4 ], s[5 ]);
228
- case 7 : return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ], s[4 ], s[5 ], s[6 ]);
229
- case 8 : return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ], s[4 ], s[5 ], s[6 ], s[7 ]);
230
- default : throw std::invalid_argument (" this" );
267
+ case 1 :
268
+ return python::make_tuple (s[0 ]);
269
+ case 2 :
270
+ return python::make_tuple (s[0 ], s[1 ]);
271
+ case 3 :
272
+ return python::make_tuple (s[0 ], s[1 ], s[2 ]);
273
+ case 4 :
274
+ return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ]);
275
+ case 5 :
276
+ return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ], s[4 ]);
277
+ case 6 :
278
+ return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ], s[4 ], s[5 ]);
279
+ case 7 :
280
+ return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ], s[4 ], s[5 ], s[6 ]);
281
+ case 8 :
282
+ return python::make_tuple (s[0 ], s[1 ], s[2 ], s[3 ], s[4 ], s[5 ], s[6 ], s[7 ]);
283
+ default :
284
+ throw std::invalid_argument (" this" );
231
285
}
232
286
}
233
287
@@ -237,7 +291,7 @@ namespace python_multi_array
237
291
//
238
292
// return: the number of dimensions of the array.
239
293
//
240
- template <class T , size_t N>
294
+ template <class T , size_t N>
241
295
size_t num_dimensions (shared_ptr<multi_array<T, N>>)
242
296
{
243
297
return N;
@@ -251,7 +305,7 @@ namespace python_multi_array
251
305
// example:
252
306
// It returns 8 for an array with shape (2, 4).
253
307
//
254
- template <class T , size_t N>
308
+ template <class T , size_t N>
255
309
size_t num_elements (shared_ptr<multi_array<T, N>> t)
256
310
{
257
311
size_t n = 1 ;
@@ -268,7 +322,7 @@ namespace python_multi_array
268
322
//
269
323
// return: a copy of the array stored in numpy.ndarray.
270
324
//
271
- template <class T , size_t N>
325
+ template <class T , size_t N>
272
326
python::object get (shared_ptr<multi_array<T, N>> t)
273
327
{
274
328
size_t s[N];
@@ -278,14 +332,22 @@ namespace python_multi_array
278
332
auto make_tuple_from_array = [](const size_t * a) {
279
333
switch (N)
280
334
{
281
- case 1 : return python::make_tuple (a[0 ]);
282
- case 2 : return python::make_tuple (a[0 ], a[1 ]);
283
- case 3 : return python::make_tuple (a[0 ], a[1 ], a[2 ]);
284
- case 4 : return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ]);
285
- case 5 : return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ], a[4 ]);
286
- case 6 : return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ]);
287
- case 7 : return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], a[6 ]);
288
- case 8 : return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], a[6 ], a[7 ]);
335
+ case 1 :
336
+ return python::make_tuple (a[0 ]);
337
+ case 2 :
338
+ return python::make_tuple (a[0 ], a[1 ]);
339
+ case 3 :
340
+ return python::make_tuple (a[0 ], a[1 ], a[2 ]);
341
+ case 4 :
342
+ return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ]);
343
+ case 5 :
344
+ return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ], a[4 ]);
345
+ case 6 :
346
+ return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ]);
347
+ case 7 :
348
+ return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], a[6 ]);
349
+ case 8 :
350
+ return python::make_tuple (a[0 ], a[1 ], a[2 ], a[3 ], a[4 ], a[5 ], a[6 ], a[7 ]);
289
351
}
290
352
throw std::invalid_argument (" this" );
291
353
};
@@ -303,12 +365,12 @@ namespace python_multi_array
303
365
// nd.dtype may be different from x.element() but the values are implicitly
304
366
// converted to x.element().
305
367
//
306
- template <class T , size_t N>
368
+ template <class T , size_t N>
307
369
void set (shared_ptr<multi_array<T, N>> t, python::numpy::ndarray nd);
308
370
309
371
namespace impl
310
372
{
311
- template <class T , size_t N, class S >
373
+ template <class T , size_t N, class S >
312
374
void set_typed (shared_ptr<multi_array<T, N>> t, python::numpy::ndarray nd)
313
375
{
314
376
if (N != nd.get_nd ())
@@ -394,22 +456,58 @@ namespace python_multi_array
394
456
}
395
457
}
396
458
397
- template <class T , size_t N>
459
+ template <class T , size_t N>
398
460
void set (shared_ptr<multi_array<T, N>> t, python::numpy::ndarray nd)
399
461
{
400
462
python::numpy::dtype dt = nd.get_dtype ();
401
- if (dt == bool8) { impl::set_typed<T, N, bool >(t, nd); }
402
- else if (dt == uint8) { impl::set_typed<T, N, uint8_t >(t, nd); }
403
- else if (dt == uint16) { impl::set_typed<T, N, uint16_t >(t, nd); }
404
- else if (dt == uint32) { impl::set_typed<T, N, uint32_t >(t, nd); }
405
- else if (dt == uint64) { impl::set_typed<T, N, uint64_t >(t, nd); }
406
- else if (dt == int8) { impl::set_typed<T, N, int8_t >(t, nd); }
407
- else if (dt == int16) { impl::set_typed<T, N, int16_t >(t, nd); }
408
- else if (dt == int32) { impl::set_typed<T, N, int32_t >(t, nd); }
409
- else if (dt == int64) { impl::set_typed<T, N, int64_t >(t, nd); }
410
- else if (dt == float32) { impl::set_typed<T, N, float >(t, nd); }
411
- else if (dt == float64) { impl::set_typed<T, N, double >(t, nd); }
412
- else { throw std::invalid_argument (" nd" ); }
463
+ if (dt == bool8)
464
+ {
465
+ impl::set_typed<T, N, bool >(t, nd);
466
+ }
467
+ else if (dt == uint8)
468
+ {
469
+ impl::set_typed<T, N, uint8_t >(t, nd);
470
+ }
471
+ else if (dt == uint16)
472
+ {
473
+ impl::set_typed<T, N, uint16_t >(t, nd);
474
+ }
475
+ else if (dt == uint32)
476
+ {
477
+ impl::set_typed<T, N, uint32_t >(t, nd);
478
+ }
479
+ else if (dt == uint64)
480
+ {
481
+ impl::set_typed<T, N, uint64_t >(t, nd);
482
+ }
483
+ else if (dt == int8)
484
+ {
485
+ impl::set_typed<T, N, int8_t >(t, nd);
486
+ }
487
+ else if (dt == int16)
488
+ {
489
+ impl::set_typed<T, N, int16_t >(t, nd);
490
+ }
491
+ else if (dt == int32)
492
+ {
493
+ impl::set_typed<T, N, int32_t >(t, nd);
494
+ }
495
+ else if (dt == int64)
496
+ {
497
+ impl::set_typed<T, N, int64_t >(t, nd);
498
+ }
499
+ else if (dt == float32)
500
+ {
501
+ impl::set_typed<T, N, float >(t, nd);
502
+ }
503
+ else if (dt == float64)
504
+ {
505
+ impl::set_typed<T, N, double >(t, nd);
506
+ }
507
+ else
508
+ {
509
+ throw std::invalid_argument (" nd" );
510
+ }
413
511
}
414
512
415
513
//
@@ -419,7 +517,7 @@ namespace python_multi_array
419
517
class array_template
420
518
{
421
519
public:
422
- template <class T , size_t N>
520
+ template <class T , size_t N>
423
521
static void declare (const char * name)
424
522
{
425
523
python::class_<shared_ptr<multi_array<T, N>>>(name)
0 commit comments