/
num_util.h
executable file
·315 lines (267 loc) · 10.4 KB
/
num_util.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
#ifndef NUM_UTIL_H__
#define NUM_UTIL_H__
// Copyright 2006 Phil Austin (http://www.eos.ubc.ca/personal/paustin)
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// $Id: num_util.h 39 2007-02-01 02:54:54Z phil $
//
#include <boost/python.hpp>
#include <numpy/noprefix.h>
#include <iostream>
#include <sstream>
#include <vector>
#include <numeric>
#include <map>
#include <complex>
namespace num_util{
//!
/**
*A free function that extracts a PyArrayObject from any sequential PyObject.
*@param x a sequential PyObject wrapped in a Boost/Python 'object'.
*@return a PyArrayObject wrapped in Boost/Python numeric array.
*/
boost::python::numeric::array makeNum(boost::python::object x);
/**
*Creates an one-dimensional numpy array of length n and numpy type t.
* The elements of the array are initialized to zero.
*@param n an integer representing the length of the array.
*@param t elements' numpy type. Default is double.
*@return a numeric array of size n with elements initialized to zero.
*/
boost::python::numeric::array makeNum(intp n, PyArray_TYPES t);
/**
*Creates a n-dimensional numpy array with dimensions dimens and numpy
*type t. The elements of the array are initialized to zero.
*@param dimens a vector of interger specifies the dimensions of the array.
*@param t elements' numpy type. Default is double.
*@return a numeric array of shape dimens with elements initialized to zero.
*/
boost::python::numeric::array makeNum(std::vector<npy_intp> dimens,
PyArray_TYPES t);
/**
*Function template returns PyArray_Type for C++ type
*See num_util.cpp for specializations
*@param T C++ type
*@return numpy type enum
*/
template<typename T> PyArray_TYPES getEnum(void)
{
PyErr_SetString(PyExc_ValueError, "no mapping available for this type");
boost::python::throw_error_already_set();
return PyArray_VOID;
}
/**
*Function template creates a one-dimensional numpy array of length n containing
*a copy of data at data*. See num_util.cpp::getEnum<T>() for list of specializations
*@param T C type of data
*@param T* data pointer to start of data
*@param n an integer indicates the size of the array.
*@return a numpy array of size n with elements initialized to data.
*/
template <typename T> boost::python::numeric::array makeNum(T* data, npy_intp n = 0){
boost::python::object obj(boost::python::handle<>((PyArray_SimpleNew(1, &n, getEnum<T>()))));
void *arr_data = PyArray_DATA((PyArrayObject*) obj.ptr());
memcpy(arr_data, data, PyArray_ITEMSIZE((PyArrayObject*) obj.ptr()) * n); // copies the input data to
return boost::python::extract<boost::python::numeric::array>(obj);
}
/**
*Function template creates an n-dimensional numpy array with dimensions dimens containing
*a copy of values starting at data. See num_util.cpp::getEnum<T>() for list of specializations
*@param T C type of data
*@param T* data pointer to start of data
*@param n an integer indicates the size of the array.
*@return a numpy array of size n with elements initialized to data.
*/
template <typename T> boost::python::numeric::array makeNum(T * data, std::vector<npy_intp> dims){
npy_intp total = std::accumulate(dims.begin(),dims.end(),1,std::multiplies<npy_intp>());
boost::python::object obj(boost::python::handle<>(PyArray_SimpleNew(dims.size(),&dims[0], getEnum<T>())));
void *arr_data = PyArray_DATA((PyArrayObject*) obj.ptr());
memcpy(arr_data, data, PyArray_ITEMSIZE((PyArrayObject*) obj.ptr()) * total);
return boost::python::extract<boost::python::numeric::array>(obj);
}
/**
*Creates a numpy array from a numpy array, referencing the data.
*@param arr a Boost/Python numeric array.
*@return a numeric array referencing the input array.
*/
boost::python::numeric::array makeNum(const
boost::python::numeric::array& arr);
/**
*A free function that retrieves the numpy type of a numpy array.
*@param arr a Boost/Python numeric array.
*@return the numpy type of the array's elements
*/
PyArray_TYPES type(boost::python::numeric::array arr);
/**
*Throws an exception if the actual array type is not equal to the expected
*type.
*@param arr a Boost/Python numeric array.
*@param expected_type an expected numpy type.
*@return -----
*/
void check_type(boost::python::numeric::array arr,
PyArray_TYPES expected_type);
/**
*A free function that retrieves the number of dimensions of a numpy array.
*@param arr a Boost/Python numeric array.
*@return an integer that indicates the rank of an array.
*/
int rank(boost::python::numeric::array arr);
/**
*Throws an exception if the actual rank is not equal to the expected rank.
*@param arr a Boost/Python numeric array.
*@param expected_rank an expected rank of the numeric array.
*@return -----
*/
void check_rank(boost::python::numeric::array arr, int expected_rank);
/**
*A free function that returns the total size of the array.
*@param arr a Boost/Python numeric array.
*@return an integer that indicates the total size of the array.
*/
intp size(boost::python::numeric::array arr);
/**
*Throw an exception if the actual total size of the array is not equal to
*the expected size.
*@param arr a Boost/Python numeric array.
*@param expected_size the expected size of an array.
*@return -----
*/
void check_size(boost::python::numeric::array arr, intp expected_size);
/**
*Returns the dimensions in a vector.
*@param arr a Boost/Python numeric array.
*@return a vector with integer values that indicates the shape of the array.
*/
std::vector<intp> shape(boost::python::numeric::array arr);
/**
*Returns the size of a specific dimension.
*@param arr a Boost/Python numeric array.
*@param dimnum an integer that identifies the dimension to retrieve.
*@return the size of the requested dimension.
*/
intp get_dim(boost::python::numeric::array arr, int dimnum);
/**
*Throws an exception if the actual dimensions of the array are not equal to
*the expected dimensions.
*@param arr a Boost/Python numeric array.
*@param expected_dims an integer vector of expected dimension.
*@return -----
*/
void check_shape(boost::python::numeric::array arr,
std::vector<intp> expected_dims);
/**
*Throws an exception if a specific dimension from a numpy array does not
*match the expected size.
*@param arr a Boost/Python numeric array.
*@param dimnum an integer that specifies which dimension of 'arr' to check.
*@param dimsize an expected size of the specified dimension.
*@return -----
*/
void check_dim(boost::python::numeric::array arr, int dimnum, intp dimsize);
/**
*Returns true if the array is contiguous.
*@param arr a Boost/Python numeric array.
*@return true if the array is contiguous, false otherwise.
*/
bool iscontiguous(boost::python::numeric::array arr);
/**
*Throws an exception if the array is not contiguous.
*@param arr a Boost/Python numeric array.
*@return -----
*/
void check_contiguous(boost::python::numeric::array arr);
/**
*Returns a pointer to the data in the array.
*@param arr a Boost/Python numeric array.
*@return a char pointer pointing at the first element of the array.
*/
void* data(boost::python::numeric::array arr);
/**
*Copies data into the array.
*@param arr a Boost/Python numeric array.
*@param new_data a char pointer referencing the new data.
*@return -----
*/
void copy_data(boost::python::numeric::array arr, char* new_data);
/**
*Returns a clone of this array.
*@param arr a Boost/Python numeric array.
*@return a replicate of the Boost/Python numeric array.
*/
boost::python::numeric::array clone(boost::python::numeric::array arr);
/**
*Returns a clone of this array with a new type.
*@param arr a Boost/Python numeric array.
*@param t PyArray_TYPES of the output array.
*@return a replicate of 'arr' with type set to 't'.
*/
boost::python::numeric::array astype(boost::python::numeric::array arr,
PyArray_TYPES t);
/* *Returns the reference count of the array. */
/* *@param arr a Boost/Python numeric array. */
/* *@return the reference count of the array. */
int refcount(boost::python::numeric::array arr);
/**
*Returns the strides array in a vector of integer.
*@param arr a Boost/Python numeric array.
*@return the strides of an array.
*/
std::vector<intp> strides(boost::python::numeric::array arr);
/**
*Throws an exception if the element of a numpy array is type cast to
*PyArray_OBJECT.
*@param newo a Boost/Python object.
*@return -----
*/
void check_PyArrayElementType(boost::python::object newo);
/**
*Mapping from a PyArray_TYPE to its corresponding name in string.
*/
typedef std::map<PyArray_TYPES, std::string> KindStringMap;
/**
*Mapping from a PyArray_TYPE to its corresponding typeID in char.
*/
typedef std::map<PyArray_TYPES, char> KindCharMap;
/**
*Mapping from a typeID to its corresponding PyArray_TYPE.
*/
typedef std::map<char, PyArray_TYPES> KindTypeMap;
/**
*Converts a PyArray_TYPE to its name in string.
*@param t_type a PyArray_TYPES.
*@return the corresponding name in string.
*/
std::string type2string(PyArray_TYPES t_type);
/**
*Converts a PyArray_TYPE to its single character typecode.
*@param t_type a PyArray_TYPES.
*@return the corresponding typecode in char.
*/
char type2char(PyArray_TYPES t_type);
/**
*Coverts a single character typecode to its PyArray_TYPES.
*@param e_type a PyArray_TYPES typecode in char.
*@return its corresponding PyArray_TYPES.
*/
PyArray_TYPES char2type(char e_type);
/**
*Constructs a string which contains a list of elements extracted from the
*input vector.
*@param vec a vector of any type.
*@return a string that lists the elements from the input vector.
*/
template <class T>
inline std::string vector_str(const std::vector<T>& vec);
/**
*Throws an exception if the total size computed from a vector of integer
*does not match with the expected size.
*@param dims an integer vector of dimensions.
*@param n an expected size.
*@return -----
*/
inline void check_size_match(std::vector<intp> dims, intp n);
} // namespace num_util
#endif