19
19
#define NPY_BEHAVED BEHAVED_FLAGS
25
\struct fff_func_iterator
26
\brief Structure to iterate a vector-based function over arbitrary
29
This structure, which is close in spirit to numpy's universal
30
functions, makes it easy to implement a C function that iterates
31
over several numpy arrays simultaneously and calls a lower-level
32
function whose arguments (in and out) are lists of fff_vectors. Both
33
input and output numpy arrays must have the same dimension, except
34
in the direction defining the orientation of the fff_vectors.
37
npy_intp nargout; /*!< number of output numpy arrays */
38
npy_intp nargin; /*!< number of input numpy arrays */
39
npy_intp axis; /*!< fff_vector direction */
40
npy_intp nitems; /*!< number of iterations required */
41
PyArrayIterObject** PyIter_argout; /*!< list of output PyArrays */
42
PyArrayIterObject** PyIter_argin; /*!< list of input PyArrays */
43
fff_vector** fff_argout; /*!< list of output fff_vectors */
44
fff_vector** fff_argin; /*!< list of input fff_vectors */
49
23
\brief Import numpy C API
51
Any Python module written in C, and using the fffPy interface, must
25
Any Python module written in C, and using the fffpy interface, must
52
26
call this function to work, because \c PyArray_API is defined
53
27
static, in order not to share that symbol within the
54
28
dso. (import_array() asks the pointer value to the python process)
56
void fffPy_import_array( void );
30
extern void fffpy_import_array(void);
59
\brief Convert \c PyArrayObject to \c fff_vector
60
\param x input numpy array
62
This function may be seen as a \c fff_vector constructor compatible
63
with \c fff_vector_delete. If the input has type \c PyArray_DOUBLE,
64
whether or not it is contiguous, the new \c fff_vector is not
65
self-owned and borrows a reference to the PyArrayObject's
66
data. Otherwise, data are copied and the \c fff_vector is
67
self-owned (hence contiguous) just like when created from
68
scratch. Notice, the function returns \c NULL if the input array
69
has more than one dimension.
34
\brief Convert \c PyArrayObject to \c fff_vector
35
\param x input numpy array
37
This function may be seen as a \c fff_vector constructor compatible
38
with \c fff_vector_delete. If the input has type \c PyArray_DOUBLE,
39
whether or not it is contiguous, the new \c fff_vector is not
40
self-owned and borrows a reference to the PyArrayObject's
41
data. Otherwise, data are copied and the \c fff_vector is
42
self-owned (hence contiguous) just like when created from
43
scratch. Notice, the function returns \c NULL if the input array
44
has more than one dimension.
71
46
fff_vector* fff_vector_fromPyArray( const PyArrayObject* x );
116
91
\param y input matrix
118
93
Conversely to \c fff_matrix_fromPyArray, this function acts as a \c
119
fff_matrix destructor compatible with \c fff_matrix_alloc, returning
94
fff_matrix destructor compatible with \c fff_matrix_new, returning
120
95
a new PyArrayObject reference. If the input matrix is contiguous and
121
96
self-owned, array ownership is simply transferred to Python;
122
97
otherwise, the data array is copied.
135
110
PyArrayObject* fff_matrix_const_toPyArray( const fff_matrix* y );
138
\brief Constructor for the \c fff_func_iterator structure
139
\param nargout number of output numpy arrays
140
\param argout list of output numpy arrays
141
\param nargin number of input numpy arrays
142
\param argin list of input numpy arrays
143
\param axis vector orientation
145
This constructor assumes that all PyArrays involved are already
146
allocated, including output arrays. Moreover, they must have the
147
same dimensions except in the direction given by \c axis.
149
fff_func_iterator* fff_func_iterator_new( npy_intp nargout, PyArrayObject** argout,
150
npy_intp nargin, PyArrayObject** argin,
154
\brief Iterate a C function over several PyArrays
155
\param thisone existing iterator structure
156
\param func pointer to the vector-based function to iterate
157
\param par auxiliary function parameters
159
\c func is intended to be a simple gateway function to an existing
160
\a fff function. It should conform with the syntax:
163
void func( fff_vector** argout, fff_vector** argin, void* par )
166
where \c argout is the list of output fff_vectors, \c argin is the
167
list of input fff_vectors, and \c par is typically a reference to a
168
pre-allocated structure in order to avoid memory allocations on
169
each iteration. It is left to the developer to determine whether \c
170
func assumes the correct number of input and output
171
arguments. Hence, it is strongly recommended that such a gateway
172
function be defined static in a Python module C file.
174
void fff_func_iterator_eval( fff_func_iterator* thisone,
175
void (*func)( fff_vector**, fff_vector**, void* ),
179
\brief Reset a \c fff_func_iterator before new loop
180
\param thisone existing iterator structure
182
This is useful when several loops over arrays are to be performed
183
in the same C function.
185
void fff_func_iterator_reset( fff_func_iterator* thisone );
188
\brief Destructor for the \c fff_func_iterator structure
189
\param thisone iterator to delete
191
Use after \c fff_func_iterator_new.
193
void fff_func_iterator_delete( fff_func_iterator* thisone );
204
122
fff_array* fff_array_fromPyArray( const PyArrayObject* x );
205
123
PyArrayObject* fff_array_toPyArray( fff_array* y );
128
\param n number of arrays
129
\param axis non-iterated axis for each array
135
PyArrayObject *X, *Y;
139
PyArrayMultiIterObject* multi = (PyArrayMultiIterObject*)PyArray_MultiIterAllButAxis(2, axis, X, Y);
141
while(multi->index < multi->size) {
142
x = fff_vector_view(multi->iters[0]->dataptr, dim_axisX, multi->iters[0]->strides[axis]);
143
y = fff_vector_view(multi->iters[1]->dataptr, dim_axisY, multi->iters[1]->strides[axis]);
145
PyArray_MultiIter_NEXT(multi);
152
extern PyObject* PyArray_MultiIterAllButAxis( int n, int axis, ... );
154
extern fff_vector* fff_vector_fromPyArrayIter(const PyArrayIterObject* it, npy_intp axis);
155
extern void fff_vector_get_fromPyArrayIter(fff_vector* y, const PyArrayIterObject* it, npy_intp axis);
156
extern void fff_vector_const_toPyArrayIter(const fff_vector* y, PyArrayIterObject* it, npy_intp axis);