~nipy-developers/nipy/fff2

« back to all changes in this revision

Viewing changes to python/wrapper/fffpy.h

  • Committer: Bertrand THIRION
  • Date: 2008-04-03 17:29:55 UTC
  • mfrom: (13.1.5 fff2)
  • Revision ID: bt206016@is143015-20080403172955-w7v1pdjdriofvzzs
Merged Alexis'changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 
7
7
 
8
8
/*!
9
 
  \file fffPy.h
 
9
  \file fffpy.h
10
10
  \brief Python interface to \a fff 
11
11
  \author Alexis Roche, Benjamin Thyreau, Bertrand Thirion
12
12
  \date 2006
19
19
#define NPY_BEHAVED BEHAVED_FLAGS
20
20
#endif
21
21
 
22
 
 
23
 
 
24
 
/*!  
25
 
  \struct fff_func_iterator 
26
 
  \brief Structure to iterate a vector-based function over arbitrary
27
 
  N-dimensional arrays
28
 
 
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.
35
 
*/ 
36
 
typedef struct {
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 */ 
45
 
} fff_func_iterator; 
46
 
 
47
 
 
48
22
/*!
49
23
   \brief Import numpy C API
50
24
 
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)
55
29
*/
56
 
void fffPy_import_array( void );
 
30
extern void fffpy_import_array(void);
 
31
 
57
32
 
58
33
/*!
59
 
   \brief Convert \c PyArrayObject to \c fff_vector 
60
 
   \param x input numpy array 
61
 
 
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 
 
36
  
 
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.
70
45
*/ 
71
46
fff_vector* fff_vector_fromPyArray( const PyArrayObject* x ); 
72
47
 
116
91
  \param y input matrix
117
92
  
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. 
134
109
*/ 
135
110
PyArrayObject* fff_matrix_const_toPyArray( const fff_matrix* y ); 
136
111
 
137
 
/*!
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
144
 
   
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.
148
 
*/ 
149
 
fff_func_iterator* fff_func_iterator_new( npy_intp nargout, PyArrayObject** argout, 
150
 
                                          npy_intp nargin, PyArrayObject** argin,
151
 
                                          npy_intp axis ); 
152
 
 
153
 
/*! 
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
158
 
   
159
 
   \c func is intended to be a simple gateway function to an existing
160
 
   \a fff function. It should conform with the syntax:
161
 
 
162
 
   \code
163
 
   void func( fff_vector** argout, fff_vector** argin, void* par )
164
 
   \endcode 
165
 
 
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.
173
 
*/ 
174
 
void fff_func_iterator_eval( fff_func_iterator* thisone, 
175
 
                             void (*func)( fff_vector**, fff_vector**, void* ), 
176
 
                             void* par ); 
177
 
 
178
 
/*! 
179
 
   \brief Reset a \c fff_func_iterator before new loop 
180
 
   \param thisone existing iterator structure 
181
 
 
182
 
   This is useful when several loops over arrays are to be performed
183
 
   in the same C function.
184
 
*/ 
185
 
void fff_func_iterator_reset( fff_func_iterator* thisone ); 
186
 
 
187
 
/*! 
188
 
   \brief Destructor for the \c fff_func_iterator structure
189
 
   \param thisone iterator to delete
190
 
 
191
 
   Use after \c fff_func_iterator_new. 
192
 
*/ 
193
 
void fff_func_iterator_delete( fff_func_iterator* thisone ); 
194
112
 
195
113
 
196
114
/*!
203
121
*/
204
122
fff_array* fff_array_fromPyArray( const PyArrayObject* x ); 
205
123
PyArrayObject* fff_array_toPyArray( fff_array* y ); 
 
124
 
 
125
 
 
126
/*!
 
127
  \brief 
 
128
  \param n number of arrays
 
129
  \param axis non-iterated axis for each array 
 
130
  
 
131
  Example: 
 
132
  
 
133
  \code
 
134
 
 
135
  PyArrayObject *X, *Y;
 
136
  fff_vector x, y; 
 
137
  int axis;
 
138
 
 
139
  PyArrayMultiIterObject* multi = (PyArrayMultiIterObject*)PyArray_MultiIterAllButAxis(2, axis, X, Y); 
 
140
  
 
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]);
 
144
     fff_my_func(y, x); 
 
145
     PyArray_MultiIter_NEXT(multi);
 
146
  }
 
147
 
 
148
  Py_DECREF(multi);
 
149
 
 
150
  \endcode
 
151
*/ 
 
152
extern PyObject* PyArray_MultiIterAllButAxis( int n, int axis, ... ); 
 
153
 
 
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);