1 #ifndef PyGSL_BLOCK_HELPERS_H 2 #define PyGSL_BLOCK_HELPERS_H 1 3 /***************************************************************************** 4 * The functions in this file are implemented in src/init/block_helpers* * 5 * These functions try to simplify the conversion between the PyArrayObjects * 6 * and the gsl_vector and gsl_matrix types. Further they try to provide a * 7 * compatibility layer for the different implementations of the * 8 * PyArrayObjects (Numeric, numarray, numpy). All code using the functions * 9 * must: * 10 * Use these functions here :-) * 11 * Declare all varibales referencing dimensions and indexing arrays * 12 * "PyGSL_array_index_t" * 13 * Expect these variables to be either of type int or long. This most * 14 * probable is only noticable on 64bit architectures. * 15 *****************************************************************************/ 16 /* 17 * Author: Pierre Schnizer 18 * 19 * $Id: 20 */ 21 #undef __BEGIN_DECLS 22 #undef __END_DECLS 23 #ifdef __cplusplus 24 # define __BEGIN_DECLS extern "C" { 25 # define __END_DECLS } 26 #else 27 # define __BEGIN_DECLS /* empty */ 28 # define __END_DECLS /* empty */ 29 #endif 30 31 32 /* 33 #define PY_ARRAY_UNIQUE_SYMBOL PyGSL_PY_ARRAY_API 34 */ 35 36 #ifndef _PyGSL_API_MODULE 37 /* 38 * Not possible to just import the declaration of the PyArrayObject struct. The 39 * pointer comes along as well ... 40 * 41 */ 42 #ifndef PyGSL_IMPORT_ARRAY 43 #define NO_IMPORT_ARRAY 44 #endif 45 #endif /* _PyGSL_API_MODULE */ 46 47 #include <limits.h> 48 #include <pygsl/intern.h> 49 #include <pygsl/utils.h> 50 #include <pygsl/general_helpers.h> 51 52 __BEGIN_DECLS 53 54 /* 55 * Build array info out of various parts. 56 * 57 * array_flag 58 */ 59 60 #if ULONG_MAX < 0xffffff 61 #error "unsigned long not big enough for array info" 62 #else 63 typedef unsigned long PyGSL_array_info_t; 64 #endif 65 66 67 68 /* typedef Py_ssize_t PyGSL_array_index_t; */ 69 /* 70 #if PY_VERSION_HEX < 0x02050000 71 typedef int Py_ssize_t; 72 #endif 73 */ 74 #include <pygsl/arrayobject.h> 75 #ifndef PyGSL_NUMPY 76 #error "Only numpy interface supported any longer" 77 #endif 78 #ifdef PyGSL_NUMPY 79 #include <numpy/arrayobject.h> 80 #endif 81 #ifdef PyGSL_NUMERIC 82 #include <Numeric/arrayobject.h> 83 #endif 84 #ifdef PyGSL_NUMARRAY 85 #include <numarray/libnumarray.h> 86 #endif 87 #if (!defined PyGSL_NUMPY) && (!defined PyGSL_NUMERIC) && (!defined PyGSL_NUMARRAY) 88 #error "Neither numpy nor numarray nor Numeric is defined!" 89 #endif 90 /* 91 * required for 64 bit machines; backward compability. I rather perfer 92 * to declare it as a long as its just my functions. 93 * 94 * For now I keep it as the same type as the underlaying array package 95 * uses for its conversions. 96 */ 97 #ifdef PyGSL_NUMERIC 98 typedef int PyGSL_array_index_t; 99 #endif 100 #ifdef PyGSL_NUMARRAY 101 typedef maybelong PyGSL_array_index_t; 102 #endif 103 #ifdef PyGSL_NUMPY 104 /* typedef intp PyGSL_array_index_t; */ 105 typedef npy_intp PyGSL_array_index_t; 106 #endif 107 108 109 110 #include <gsl/gsl_vector.h> 111 #include <gsl/gsl_matrix.h> 112 113 enum PyGSL_Array_Flags { 114 PyGSL_NON_CONTIGUOUS = 0, 115 PyGSL_CONTIGUOUS = 1, 116 /* Additional flags needed for numarray and numpy */ 117 PyGSL_INPUT_ARRAY = 2, 118 PyGSL_OUTPUT_ARRAY = 4, 119 PyGSL_IO_ARRAY = 8 120 }; 121 122 /* 123 * Convienience functions for handling the flags 124 */ 125 #define PyGSL_GET_ARRAYFLAG(flag) (( (flag) >> 0) & 0x000000ff) 126 #define PyGSL_GET_ARRAYTYPE(flag) (( (flag) >> 8) & 0x000000ff) 127 #define PyGSL_GET_TYPESIZE(flag) (( (flag) >> 16) & 0x000000ff) 128 #define PyGSL_GET_ARGNUM(flag) (( (flag) >> 24) & 0x000000ff) 129 130 #define PyGSL_BUILD_ARRAY_INFO(array_flag, array_type, type_size, argnum) \ 131 (\ 132 ( ((array_flag) & 0x000000ff) << 0) + \ 133 ( ((array_type) & 0x000000ff) << 8) + \ 134 ( ((type_size) & 0x000000ff) << 16) + \ 135 ( ((argnum) & 0x000000ff) << 24) \ 136 ) 137 138 139 #define PyGSL_DARRAY_INFO(array_flag, argnum) \ 140 PyGSL_BUILD_ARRAY_INFO(array_flag, NPY_DOUBLE, sizeof(double), argnum) 141 #define PyGSL_DARRAY_CINPUT(argnum) PyGSL_DARRAY_INFO(PyGSL_CONTIGUOUS | PyGSL_INPUT_ARRAY, argnum) 142 #define PyGSL_DARRAY_INPUT(argnum) PyGSL_DARRAY_INFO(PyGSL_NON_CONTIGUOUS | PyGSL_INPUT_ARRAY, argnum) 143 #define PyGSL_DARRAY_CIO(argnum) PyGSL_DARRAY_INFO(PyGSL_CONTIGUOUS | PyGSL_IO_ARRAY, argnum) 144 145 146 #define PyGSL_CARRAY_INFO(array_flag, argnum) \ 147 PyGSL_BUILD_ARRAY_INFO(array_flag, NPY_CDOUBLE, 2 * sizeof(double), argnum) 148 #define PyGSL_CARRAY_CINPUT(argnum) PyGSL_CARRAY_INFO(PyGSL_CONTIGUOUS | PyGSL_INPUT_ARRAY, argnum) 149 #define PyGSL_CARRAY_CIO(argnum) PyGSL_CARRAY_INFO(PyGSL_CONTIGUOUS | PyGSL_IO_ARRAY, argnum) 150 151 /* 152 * PyGSL_New_Array: 153 * Generate an new array with the specified dimensions. 154 * 155 * The numpy backend expects an array of int, whereas 156 * the numarray backend expects an array of long 157 */ 158 PyGSL_API_EXTERN PyArrayObject * 159 PyGSL_New_Array(int nd, PyGSL_array_index_t *dimensions, int type); 160 161 /* 162 * PyGSL_Copy_Array: 163 * 164 * Copy an array. The output array will have the same 165 * size as the input array. 166 */ 167 PyGSL_API_EXTERN PyArrayObject * 168 PyGSL_Copy_Array(PyArrayObject *, int type); 169 170 /* 171 * PyGSL_STRIDE_RECALC: 172 * Recalc a stride and check if it is okay 173 * 174 * Numpy calculates strides in bytes, gsl as multiple of the basis type size 175 * 176 * Return value: 177 * -1: Conversion Failed 178 * pos : recalculated stride 179 */ 180 PyGSL_API_EXTERN int 181 PyGSL_stride_recalc(PyGSL_array_index_t strides, int basis_type_size, 182 PyGSL_array_index_t * stride_recalc); 183 184 185 186 187 /* 188 * PyGSL_PyArray_generate_gsl_vector_view : 189 * Generate an new array of given dimensions . 190 * 191 * This function will try to convert the object, to a Python integer and 192 * generate an apropriate one dimensional numpy array. 193 * 194 * Input : 195 * object : a general python object 196 * array_type : the required C type for the array 197 * argument number : The argument number. Used for error reporting 198 * 199 * Output: 200 * : a pointer to a PyArrayObject or NULL in case 201 * of error. This object must be dereferenced. 202 */ 203 PyGSL_API_EXTERN PyArrayObject * 204 PyGSL_PyArray_generate_gsl_vector_view(PyObject *src, 205 int array_type, 206 int argnum); 207 208 /* 209 * PyGSL_PyArray_generate_gsl_matrix_view : 210 * Generate an new array of given dimensions . 211 * 212 * This function will try to convert the object, to a sequence of two Python 213 * integer and generate an apropriate two dimensional numpy array. 214 * 215 * Input : 216 * object : a general python object 217 * array_type : the required C type for the array 218 * argument number : The argument number. Used for error reporting 219 * 220 * Output: 221 * : a pointer to a PyArrayObject or NULL in case 222 * of error. This object must be dereferenced. 223 */ 224 PyGSL_API_EXTERN PyArrayObject * 225 PyGSL_PyArray_generate_gsl_matrix_view(PyObject *src, 226 int array_type, 227 int argnum); 228 229 230 231 /* 232 * Check if a python object can be used as a vector. If so return an 233 * approbriate python array object. 234 * 235 * 236 * Input: 237 * src ... the python object 238 * size ... the required size. Pass -1 if it should not be checked. 239 * 240 * array_type ... the required type. 241 * flag ... shall be an input or output or inout array? 242 * ... shall it be contiguous? 243 * argnum ... the positional argument number. Used when reporting an 244 * error 245 * 246 * Information if the stride of the vector should be 247 * recalulated to the native C type. 248 * type_size ... the size of the native C type (typically sizeof(type)). 249 * If stride is NULL this value is without meaning. 250 * 251 * *stride ... the recalculated stride. If NULL stride will not be 252 * recalulated, and the following items can be of any value 253 * 254 * info ... info structure passed by callbacks for reporting an error 255 * 256 * Convienience macros: 257 * PyGSL_DVECTOR_CHECK(src, size, flag, argnum, stride, info) 258 */ 259 PyGSL_API_EXTERN PyArrayObject * 260 PyGSL_vector_check(PyObject *src, PyGSL_array_index_t size, PyGSL_array_info_t ainfo, 261 PyGSL_array_index_t *stride, PyGSL_error_info * info); 262 263 264 /* 265 * Check if a python object can be used as a vector. If so return an 266 * approbriate python array object. 267 * 268 * 269 * Input: 270 * src ... the python object 271 * 272 * size1 ... the required size of the first dimension. Pass -1 if it 273 * should not be checked. 274 * size2 ... the required size of the second dimension. Pass -1 if it 275 * should not be checked. 276 * 277 * array_type ... the required type. 278 * flag ... shall be an input or output or inout array? 279 * shall it be contiguous? 280 * argnum ... the positional argument number. Used when reporting an 281 * error 282 * 283 * Information if the stride of the vector should be 284 * recalulated to the native C type. 285 * type_size ... the size of the native C type (typically sizeof(type)). 286 * If stride is NULL this value is without meaning. 287 * 288 * *stride1 ... the recalculated stride. If NULL stride will not be 289 * recalulated, and the following items can be of any value 290 * *stride2 ... the recalculated stride. If NULL stride will not be 291 * recalulated, and the following items can be of any value 292 * 293 * info ... info structure passed by callbacks for reporting an error 294 * 295 * Convienience macros: 296 * PyGSL_DMATRIX_CHECK(src, size1, size2, flag, argnum, stride1, stride2, info) 297 */ 298 PyGSL_API_EXTERN PyArrayObject * 299 PyGSL_matrix_check(PyObject *src, PyGSL_array_index_t size1, PyGSL_array_index_t size2, 300 PyGSL_array_info_t ainfo, 301 PyGSL_array_index_t *stride1, PyGSL_array_index_t *stride2, 302 PyGSL_error_info * info); 303 304 /* 305 * PyGSL_copy_pyarray_to_gslvector 306 * Copy the contents of a pyarray to a gsl_vector. 307 * 308 * 309 * Input : 310 * f : a pointer to the target vector 311 * object : a general python object 312 * n : number of elements 313 * info : a PyGSL_Error_info struct. Used for error 314 * reporting during callback evaluation. Pass 315 * NULL if not needed. 316 * 317 * Output: 318 * : GSL_SUCCESS | GSL_FAILURE 319 * 320 */ 321 PyGSL_API_EXTERN int 322 PyGSL_copy_pyarray_to_gslvector(gsl_vector *f, PyObject *object, PyGSL_array_index_t n, 323 PyGSL_error_info * info); 324 325 /* 326 * PyGSL_copy_pyarray_to_gslmatrix 327 * Copy the contents of a pyarray to a gsl_matrix. 328 * 329 * 330 * Input : 331 * f : a pointer to the target gsl_vector 332 * object : a general python object referring to a numpy 333 * array 334 * n : number of elements in the first dimension 335 * p : number of elements in the second dimension 336 * info : a PyGSL_error_info struct. Used for error 337 * reporting during callback evaluation. Pass 338 * NULL if not needed. 339 * 340 * Output: 341 * : GSL_SUCCESS | GSL_FAILURE 342 * 343 */ 344 PyGSL_API_EXTERN int 345 PyGSL_copy_pyarray_to_gslmatrix(gsl_matrix *f, PyObject *object, PyGSL_array_index_t n, 346 PyGSL_array_index_t p, PyGSL_error_info * info); 347 348 PyGSL_API_EXTERN PyArrayObject * 349 PyGSL_vector_or_double(PyObject *src, PyGSL_array_info_t ainfo, PyGSL_array_index_t size, 350 PyGSL_error_info * info); 351 352 353 /* 354 * PyGSL_copy_gslvector_to_pyarrary : 355 * Generate a new numpy array of approbriate size and copy the 356 * data of the vector to it. 357 * 358 * 359 * Input : 360 * x : a gsl_vector 361 * Output: 362 * : a pointer to a PyArrayObject or NULL in case 363 * of error. This object must be dereferenced. 364 */ 365 PyGSL_API_EXTERN PyArrayObject * 366 PyGSL_copy_gslvector_to_pyarray(const gsl_vector *x); 367 368 /* 369 * PyGSL_copy_gslmatrix_to_pyarrary : 370 * Generate a new numpy array of approbriate size and copy the 371 * data of the matrix to it. 372 * 373 * 374 * Input : 375 * x : a gsl_matrix 376 * Output: 377 * : a pointer to a PyArrayObject or NULL in case 378 * of error. This object must be dereferenced. 379 */ 380 PyGSL_API_EXTERN PyArrayObject * 381 PyGSL_copy_gslmatrix_to_pyarray(const gsl_matrix *x); 382 #ifndef _PyGSL_API_MODULE 383 #define PyGSL_stride_recalc \ 384 (*(int (*)(PyGSL_array_index_t, int, PyGSL_array_index_t * )) PyGSL_API[PyGSL_stride_recalc_NUM]) 385 #define PyGSL_New_Array \ 386 (*(PyArrayObject * (*)(int, PyGSL_array_index_t *, int)) PyGSL_API[PyGSL_PyArray_new_NUM]) 387 #define PyGSL_Copy_Array \ 388 (*(PyArrayObject * (*)(PyArrayObject *)) PyGSL_API[PyGSL_PyArray_copy_NUM]) 389 #ifdef NO_PyGSL_LEGACY 390 #define PyGSL_PyArray_prepare_gsl_vector_view \ 391 (*(PyArrayObject * (*)(PyObject *, int, int, PyGSL_array_index_t, int, PyGSL_error_info *)) \ 392 PyGSL_API[PyGSL_PyArray_prepare_gsl_vector_view_NUM]) 393 #define PyGSL_PyArray_prepare_gsl_matrix_view \ 394 (*(PyArrayObject * (*)(PyObject *, int, int, PyGSL_array_index_t, PyGSL_array_index_t, int, PyGSL_error_info *)) \ 395 PyGSL_API[PyGSL_PyArray_prepare_gsl_matrix_view_NUM]) 396 #endif /* NO_PyGSL_LEGACY */ 397 #define PyGSL_PyArray_generate_gsl_vector_view \ 398 (*(PyArrayObject *(*)(PyObject *, int, int)) PyGSL_API[PyGSL_PyArray_generate_gsl_vector_view_NUM]) 399 400 #define PyGSL_PyArray_generate_gsl_matrix_view \ 401 (*(PyArrayObject *(*)(PyObject *, int, int)) PyGSL_API[PyGSL_PyArray_generate_gsl_matrix_view_NUM]) 402 403 #define PyGSL_copy_pyarray_to_gslvector \ 404 (*(int (*) (gsl_vector *, PyObject *, PyGSL_array_index_t, PyGSL_error_info *)) PyGSL_API[PyGSL_copy_pyarray_to_gslvector_NUM]) 405 #define PyGSL_copy_pyarray_to_gslmatrix \ 406 (*(int (*) (gsl_matrix *, PyObject *, PyGSL_array_index_t, PyGSL_array_index_t, PyGSL_error_info *)) PyGSL_API[PyGSL_copy_pyarray_to_gslmatrix_NUM]) 407 408 #define PyGSL_copy_gslvector_to_pyarray \ 409 (*(PyArrayObject * (*)(const gsl_vector *)) PyGSL_API[ PyGSL_copy_gslvector_to_pyarray_NUM]) 410 411 #define PyGSL_copy_gslmatrix_to_pyarray \ 412 (*(PyArrayObject * (*)(const gsl_matrix *)) PyGSL_API[ PyGSL_copy_gslmatrix_to_pyarray_NUM]) 413 414 415 #define PyGSL_vector_or_double \ 416 (*(PyArrayObject * (*)(PyObject *, PyGSL_array_info_t , PyGSL_array_index_t, PyGSL_error_info *)) \ 417 PyGSL_API[PyGSL_vector_or_double_NUM]) 418 419 #define PyGSL_vector_check \ 420 (*(PyArrayObject * (*) (PyObject *, PyGSL_array_index_t, \ 421 PyGSL_array_info_t, PyGSL_array_index_t *, PyGSL_error_info *)) \ 422 PyGSL_API[PyGSL_vector_check_NUM]) 423 424 #define PyGSL_matrix_check \ 425 (*(PyArrayObject * (*) (PyObject *, PyGSL_array_index_t, PyGSL_array_index_t, \ 426 PyGSL_array_info_t, PyGSL_array_index_t *, PyGSL_array_index_t *, PyGSL_error_info *)) \ 427 PyGSL_API[PyGSL_matrix_check_NUM]) 428 429 #define PyGSL_array_check (*(int (*)(PyObject *)) PyGSL_API[PyGSL_array_check_NUM]) 430 #define PyGSL_array_return(ob) ((PyObject *) ob) 431 #endif /* _PyGSL_API_MODULE */ 432 433 #define PyGSL_STRIDE_RECALC(strides, basis_type_size, stride_recalc) \ 434 ( \ 435 (((strides) % (basis_type_size)) == 0) \ 436 ? \ 437 ( ((*(stride_recalc)) = (strides) / (basis_type_size)), GSL_SUCCESS ) \ 438 : \ 439 PyGSL_stride_recalc(strides, basis_type_size, stride_recalc) \ 440 ) 441 /* 442 #define PyGSL_DVECTOR_CHECK(src, size, info, stride, info) \ 443 PyGSL_vector_check(src, size, PyArray_DOUBLE, sizeof(double), flag, argnum, stride, info) 444 445 #define PyGSL_DMATRIX_CHECK(src, size1, size2, flag, argnum, stride1, stride2, info) \ 446 PyGSL_vector_check(src, size1, size2, PyArray_DOUBLE, sizeof(double), flag, argnum, stride1, stride2, info) 447 */ 448 449 #ifdef PyGSL_NUMPY 450 #include <pygsl/block_helpers_numpy.h> 451 #endif 452 453 #ifdef PyGSL_NUMERIC 454 #include <pygsl/block_helpers_numeric.h> 455 #endif 456 457 #ifdef PyGSL_NUMARRAY 458 #include <pygsl/block_helpers_numarray.h> 459 #endif 460 461 __END_DECLS 462 #endif /* PyGSL_BLOCK_HELPERS_H */ 463