Dear Krishna!
Dear Pierre,

I installed numpy-0.9.5 and the errors still persist. What is the
architecture of the machine ran the tests on with numpy-0.9.5? Are
these errors due to x86_64? I tried to debug it last friday but
realized it would take me long to do that. What do you suggest?

cheers,
Krishna.




Thanks for your in deep study of the problem. Yes I think that goes back that you are the first who tries to use pygsl and numpy on a 64 bit machine.

Basically that error goes back to some laziyness on my side. And on supporting three different array packages. But I agree, numpy is the one to support for sure.

As you send me in the other mail it goes back that -1 is passed as argument to the function

<snip>
static PyArrayObject *
PyGSL_PyArray_prepare_gsl_vector_view(PyObject *src,
                                      int array_type,
                                      int flag,
                                      long size, int argnum, PyGSL_error_info * 
info)
</snip>
where size is defined long, but then defined as int

<snip>
static int
PyGSL_PyArray_Check(PyArrayObject *a_array, int array_type, int flag,
        int nd,     long *dimensions, int argnum, PyGSL_error_info * info)
</snip>
in the function which checks if the array is of approbriate size.

Passing -1 as a size is used to signal that no one cares about the dimensions.

Then I made an internal error declaring the arguments of the functions in the prototype as long but as int in the pointer cast of the api. And on your machine (in contrast to typical 32 bit machines)
<snip>
>>> "0x%x" % 4294967295
'0xffffffff'
</snip>
int and long are of the same length. So the above is -1 on mine but a huge value on your machine.....

I attached  the files in question
Include/pygsl/block_helpers.h
src/init/block_helpers.c
where these indices are now declared long. I hope that is a fast fix for now. I have to go through the whole code and change that type to the newly defined Py_ssize_t, which was generated exactly for this type of values.


Further I see that eigen crashes so there is still some bug lurcking
somewhere. Perhaps it is just my atlas implementation ....


I will try to get access to a 64 bit machine and see what I get there as well; but I am grateful for any bug report.

Sincerely yours
        Pierre

Krishna Mohan Gundu wrote:
======================================================================
ERROR: testDasum (__main__.BlasTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
 File "/home/krishna/local/inst/pygsl-0.3.numpy_test/tests/blas_test.py",
line 38, in testDasum
   comp = dasum(self.v1_4)
 File "/home/krishna/local/lib/python2.4/site-packages/pygsl/blas.py",
line 93, in dasum
   return _gslwrap.gsl_blas_dasum(x)
 File "src/init/block_helpers_numpy.ic", line 97, in
PyGSL_PyArray_prepare_gsl_vector_view
 File "src/init/block_helpers.c", line 102, in PyGSL_PyArray_Check
gsl_BadLength: matrix/vector sizes are not conformant: The size of
argument   1 did not match the expected size for the 0 dimension. I
got   4 elements but expected  4294967295 elements!

On 5/23/06, Krishna Mohan Gundu <[EMAIL PROTECTED]> wrote:


.
.
.
My arch is x86_64 and compiler is `gcc -v`
==
Reading specs from /usr/lib/gcc-lib/x86_64-redhat-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit
--host=x86_64-redhat-linux
Thread model: posix
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-49)
==

hope that helps,
Krishna


#ifndef PyGSL_BLOCK_HELPERS_H
#define PyGSL_BLOCK_HELPERS_H 1

/*
 * Author:  Pierre Schnizer
 *
 */

/*****************************************************************************
 *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!* 
 *!									    !*
 *! Important: If you want to use this library, you must not include 	    !*
 *! <Numeric/arrayobject.h> into any file you want to link against this     !*
 *! library. Instead include this file. In this file PY_ARRAY_UNIQUE_SYMBOL !*
 *! is defined. This define must be the same in all link files. See the     !*
 *! the numeric documentation for further details.			    !*
 *!									    !*
 *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!* 
 *****************************************************************************/
/*
#ifndef PyGSL_IMPORT_ARRAY
#define NO_IMPORT_ARRAY
#endif
*/
/*
#define PY_ARRAY_UNIQUE_SYMBOL PyGSL_PY_ARRAY_API
*/

#include <pygsl/intern.h>
#include <pygsl/utils.h>
#include <pygsl/general_helpers.h>

#include <pygsl/arrayobject.h>
#ifdef PyGSL_NUMPY
#include <numpy/arrayobject.h>
#endif
#ifdef PyGSL_NUMERIC
#include <Numeric/arrayobject.h>
#endif
#ifdef PyGSL_NUMARRAY
#include <numarray/libnumarray.h>
#endif
#if (!defined PyGSL_NUMPY) && (!defined  PyGSL_NUMERIC) && (!defined PyGSL_NUMARRAY)
#error "Neither numpy nor numarray nor Numeric is defined!"
#endif



#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>

enum PyGSL_Array_Flags {
     PyGSL_NON_CONTIGUOUS = 0,
     PyGSL_CONTIGUOUS = 1,
     /* Additional flags needed for numarray */
     PyGSL_INPUT_ARRAY = 2,
     PyGSL_OUTPUT_ARRAY = 4,
     PyGSL_IO_ARRAY = 8,
};

/*
 * PyGSL_New_Array:
 *                Generate an new array with the specified dimensions.
 *
 *                The numpy backend expects an array of int, whereas 
 *                the numarray backend expects  an array of long
 */
PyGSL_API_EXTERN PyArrayObject *
PyGSL_New_Array(int nd, int *dimensions, int type);

/*
 * PyGSL_Copy_Array:
 *
 *                 Copy an array. The output array will have the same
 *                 size as the input array.
 */
PyGSL_API_EXTERN PyArrayObject *
PyGSL_Copy_Array(PyArrayObject *, int type);

/*
 * PyGSL_STRIDE_RECALC:
 *                                Recalc a stride and check if it is okay
 *
 * Numpy calculates strides in bytes, gsl as multiple of the basis type size
 *
 * Return value:
 *         -1: Conversion Failed
 *         pos : recalculated stride
 */
PyGSL_API_EXTERN int 
PyGSL_stride_recalc(int strides, int basis_type_size, int * stride_recalc);


/*
 * PyGSL_PyArray_PREPARE_gsl_vector_view :
 *                                 Check if an array can be treated as vector.
 *
 * It is provided using a macro / function pair. The macro will accept a
 * numpy array and return the pointer to the numpy object if the array is one
 * dimensional and has the required number of elements. Further its 
 * contiguousity is checked. If the object did not fulfill the requirements the
 * function PyGSL_PyArray_prepare_gsl_vector_view is called. This function will
 * try to convert the object, or generate an approbriate error message. If the 
 * conversion is successful it will increase the profile counter 
 * pygsl_profile_vector_transform_counter via the macro 
 * PyGSL_INCREASE_vector_transform_counter().
 *
 * Input : 
 *         object              : a general python object
 *         array_type          : the required C type for the array
 *         contiguous          : 2 copy the original array
 *                               1 the array must be contigous,
 *                               0 discontigous ones are acceptable.
 *         size                : length of the vector, or -1 if no check 
 *                               needed.
 *         argument number     : The argument number. Used for error reporting
 *         info                : a PyGSL_Error_info struct. Used for error 
 *                               reporting during callback evaluation. Pass 
 *                               NULL if not needed.
 *
 * Output: 
 *                             : a pointer to a PyArrayObject or NULL in case 
 *                              of error. This object must be dereferenced.
 */
PyGSL_API_EXTERN PyArrayObject * 
PyGSL_PyArray_prepare_gsl_vector_view(PyObject *src,
				      int array_type,
				      int flag, 
				      long size, int argnum, PyGSL_error_info * info);

/*
 * PyGSL_PyArray_PREPARE_gsl_matrix_view
 *                           Check if an array can be treated as matrix. 
 *
 * It is provided using a macro / function pair. The macro will accept a
 * numpy array and return the pointer to the numpy object if the array is two
 * dimensional and has the required number of elements in both dimensions. 
 * Further its contiguousity is checked. If the object did not fulfill the 
 * requirements the function PyGSL_PyArray_prepare_gsl_matrix_view is called. 
 * This function will try to convert the object or generate an approbriate 
 * error message. If the conversion is successful it will increase the profile
 * counter pygsl_profile_matrix_transform_counter via the macro 
 * PyGSL_INCREASE_matrix_transform_counter().
 *
 * Input : 
 *         PyObject            : a general python object
 *         array_type          : the required C type for the array
 *         contiguous          : 2 make a copy of that array!
 *                               1 the array must be contigous,
 *                               0 discontigous ones are acceptable.
 *         size1               : number of elements in the first dimension, or
 *                                -1 if no check needed.
 *         size2               : number of elements in the second dimension, or
 *                                -1 if no check needed.
 *         argument number     : The argument number. Used for error reporting
 *         info struct         : a PyGSL_Error_info struct. Used for error
 *                               reporting during callback evaluation. Pass
 *                               NULL if not needed.
 *
 * Output: 
 *                             : a pointer to a PyArrayObject or NULL in case 
 *                              of error. This object must be dereferenced.
 *
 * Important: When the data will be passed to gsl via gsl_matrix_view_array, 
 *            then  you must enforce an contiguous array.
 */


PyGSL_API_EXTERN PyArrayObject *
PyGSL_PyArray_prepare_gsl_matrix_view(PyObject *src,
				      int array_type,
				      int flag, 
				      long size1, long size2, int argnum, 
				      PyGSL_error_info * info);


/*
 * PyGSL_PyArray_generate_gsl_vector_view :
 *                                 Generate an new array of given dimensions .
 *
 *  This function will try to convert the object, to a Python integer and 
 *  generate an apropriate one dimensional numpy array.
 *
 * Input : 
 *         object              : a general python object
 *         array_type          : the required C type for the array
 *         argument number     : The argument number. Used for error reporting
 *
 * Output: 
 *                             : a pointer to a PyArrayObject or NULL in case 
 *                              of error. This object must be dereferenced.
 */
PyGSL_API_EXTERN PyArrayObject * 
PyGSL_PyArray_generate_gsl_vector_view(PyObject *src,
				       int array_type,
				       int argnum);

/*
 * PyGSL_PyArray_generate_gsl_matrix_view :
 *                                 Generate an new array of given dimensions .
 *
 *  This function will try to convert the object, to a sequence of two Python 
 *  integer and generate an apropriate two dimensional numpy array.
 *
 * Input : 
 *         object              : a general python object
 *         array_type          : the required C type for the array
 *         argument number     : The argument number. Used for error reporting
 *
 * Output: 
 *                             : a pointer to a PyArrayObject or NULL in case 
 *                              of error. This object must be dereferenced.
 */
PyGSL_API_EXTERN PyArrayObject * 
PyGSL_PyArray_generate_gsl_matrix_view(PyObject *src,
				       int array_type,
				       int argnum);

/*
 * PyGSL_copy_pyarray_to_gslvector
 *                           Copy the contents of a pyarray to a gsl_vector.
 *
 *
 * Input :
 *         f                   : a pointer to the target vector
 *         object              : a general python object
 *         n                   : number of elements
 *         info                : a PyGSL_Error_info struct. Used for error
 *                               reporting during callback evaluation. Pass
 *                               NULL if not needed.
 *
 * Output: 
 *                             : GSL_SUCCESS | GSL_FAILURE
 *
 */
PyGSL_API_EXTERN int
PyGSL_copy_pyarray_to_gslvector(gsl_vector *f, PyObject *object, long n, 
				PyGSL_error_info * info);

/*
 * PyGSL_copy_pyarray_to_gslmatrix
 *                           Copy the contents of a pyarray to a gsl_matrix.
 *
 *
 * Input :
 *         f                   : a pointer to the target gsl_vector
 *         object              : a general python object referring to a numpy 
 *                               array
 *         n                   : number of elements in the first dimension
 *         p                   : number of elements in the second dimension
 *         info                : a PyGSL_error_info struct. Used for error
 *                               reporting during callback evaluation. Pass
 *                               NULL if not needed.
 *
 * Output: 
 *                             : GSL_SUCCESS | GSL_FAILURE
 *
 */
PyGSL_API_EXTERN int
PyGSL_copy_pyarray_to_gslmatrix(gsl_matrix *f, PyObject *object, long n, long p,
				PyGSL_error_info * info);

PyGSL_API_EXTERN PyArrayObject * 
PyGSL_vector_or_double(PyObject *src, int flag, long size, int argnum,
		       PyGSL_error_info * info);

/*
 * PyGSL_copy_gslvector_to_pyarrary :
 *                Generate a new numpy array of approbriate size and copy the
 *                data of the vector to it.
 *
 *
 * Input : 
 *              x              : a gsl_vector
 * Output: 
 *                             : a pointer to a PyArrayObject or NULL in case 
 *                              of error. This object must be dereferenced.
 */
PyGSL_API_EXTERN PyArrayObject *
PyGSL_copy_gslvector_to_pyarray(const gsl_vector *x);

/*
 * PyGSL_copy_gslmatrix_to_pyarrary :
 *                Generate a new numpy array of approbriate size and copy the
 *                data of the matrix to it.
 *
 *
 * Input : 
 *              x              : a gsl_matrix
 * Output: 
 *                             : a pointer to a PyArrayObject or NULL in case 
 *                              of error. This object must be dereferenced.
 */
PyGSL_API_EXTERN PyArrayObject *
PyGSL_copy_gslmatrix_to_pyarray(const gsl_matrix *x);
#ifndef _PyGSL_API_MODULE
#define PyGSL_stride_recalc \
(*(int (*)(int, int, int * ))                                        PyGSL_API[PyGSL_stride_recalc_NUM])
#define  PyGSL_New_Array  \
(*(PyArrayObject * (*)(int, int *, int))                              PyGSL_API[PyGSL_PyArray_new_NUM])
#define  PyGSL_Copy_Array  \
(*(PyArrayObject * (*)(PyArrayObject *))                               PyGSL_API[PyGSL_PyArray_copy_NUM])
#define  PyGSL_PyArray_prepare_gsl_vector_view  \
(*(PyArrayObject * (*)(PyObject *, enum PyArray_TYPES, int,  long, long, PyGSL_error_info *)) \
                                                                     PyGSL_API[PyGSL_PyArray_prepare_gsl_vector_view_NUM])
#define  PyGSL_PyArray_prepare_gsl_matrix_view  \
(*(PyArrayObject * (*)(PyObject *, enum PyArray_TYPES, int,  long, long, int, PyGSL_error_info *)) \
                                                                     PyGSL_API[PyGSL_PyArray_prepare_gsl_matrix_view_NUM])
#define PyGSL_PyArray_generate_gsl_vector_view \
(*(PyArrayObject *(*)(PyObject *, enum PyArray_TYPES, int))          PyGSL_API[PyGSL_PyArray_generate_gsl_vector_view_NUM]) 

#define PyGSL_PyArray_generate_gsl_matrix_view \
(*(PyArrayObject *(*)(PyObject *, enum PyArray_TYPES, int))          PyGSL_API[PyGSL_PyArray_generate_gsl_matrix_view_NUM]) 

#define PyGSL_copy_pyarray_to_gslvector \
(*(int (*) (gsl_vector *, PyObject *, long, PyGSL_error_info *))      PyGSL_API[PyGSL_copy_pyarray_to_gslvector_NUM])
#define PyGSL_copy_pyarray_to_gslmatrix \
(*(int (*) (gsl_matrix *, PyObject *, long, long, PyGSL_error_info *)) PyGSL_API[PyGSL_copy_pyarray_to_gslmatrix_NUM])

#define PyGSL_copy_gslvector_to_pyarray \
 (*(PyArrayObject * (*)(const gsl_vector *))                         PyGSL_API[ PyGSL_copy_gslvector_to_pyarray_NUM])

#define PyGSL_copy_gslmatrix_to_pyarray \
 (*(PyArrayObject * (*)(const gsl_matrix *))                         PyGSL_API[ PyGSL_copy_gslmatrix_to_pyarray_NUM])         

#define  PyGSL_vector_or_double  \
(*(PyArrayObject * (*)(PyObject *, int,  long, int, PyGSL_error_info *)) \
                                                                     PyGSL_API[PyGSL_vector_or_double_NUM])

#endif /* _PyGSL_API_MODULE */

#define PyGSL_STRIDE_RECALC(strides, basis_type_size, stride_recalc) \
           (((strides) % (basis_type_size)) == 0) \
         ? \
           ((*(stride_recalc)) = (strides) / (basis_type_size)), GSL_SUCCESS \
         : \
           PyGSL_stride_recalc(strides, basis_type_size, stride_recalc)

#ifdef PyGSL_NUMPY
#include <pygsl/block_helpers_numpy.h>
#endif

#ifdef PyGSL_NUMERIC
#include <pygsl/block_helpers_numeric.h>
#endif

#ifdef PyGSL_NUMARRAY
#include <pygsl/block_helpers_numarray.h>
#endif

#endif /* PyGSL_BLOCK_HELPERS_H */
/* -*- C -*- */
/*
 * Author : Pierre Schnizer
 * Date   : January 2003
 * 
 *  Changes for better error reporting from 
 *  17. 01. 2003
 *  Adding a info struct. This struct contains additional information used for 
 *  error Reporting.
 *
 *  Changed to support Numeric and nummarray.
 */

#define PyGSL_IMPORT_ARRAY 1
#include <pygsl/block_helpers.h>
#include <pygsl/error_helpers.h>
#include <stdlib.h>
#include <stdio.h>
#include <pygsl/profile.h>
#include <pygsl/general_helpers.h>
#include <pygsl/utils.h>

static const char filename[] = __FILE__;

static int 
PyGSL_stride_recalc(int strides, int basic_type_size, int * stride_recalc)
{
     int line;

     FUNC_MESS_BEGIN();
     line = __LINE__ + 1;
     if((strides % basic_type_size) == 0) {
	  *stride_recalc = strides / basic_type_size; 
	  DEBUG_MESS(2, "\tRecalculated strides to %d", *stride_recalc);
	  FUNC_MESS_END();
	  return GSL_SUCCESS;
     }

     DEBUG_MESS(2, "Failed to convert stride. %d/%d != 0", 
		strides, basic_type_size);
     gsl_error("Can not convert the stride to a GSL stride", 
	       filename, __LINE__, PyGSL_ESTRIDE);
     PyGSL_add_traceback(NULL, filename, __FUNCTION__, line);     
     return PyGSL_ESTRIDE;
}
/* ========================================================================= */
/*
 * Implementation of the above routines.
 */

static int
PyGSL_PyArray_Check(PyArrayObject *a_array, int array_type, int flag,  int nd,
		    long *dimensions, int argnum, PyGSL_error_info * info)
{

     int i;
     int error_flag = GSL_ESANITY, line = -1;

     FUNC_MESS_BEGIN();
     if(!PyArray_Check((PyObject *) a_array)){
	  gsl_error("Did not recieve an array!", filename, __LINE__, GSL_ESANITY);
	  line = __LINE__ - 2;
	  error_flag =  GSL_ESANITY;
	  goto fail;
     }
     if(nd <  1 || nd > 2){	  
	  DEBUG_MESS(2, "Got an nd of %d", nd);          
	  line = __LINE__ - 2;
	  gsl_error("nd must either 1 or 2!", filename, __LINE__, GSL_ESANITY);
	  error_flag =  GSL_ESANITY;
	  goto fail;
     }

     if (a_array->nd !=  nd){
	  DEBUG_MESS(3, "array->nd = %d\t nd = %d", a_array->nd, nd);
	  line = __LINE__ - 1;
	  sprintf(pygsl_error_str, "I could not convert argument number % 3d."
		  " I expected a %s, but got an array of % 3d dimensions!\n", argnum, 
		  (nd == 1) ? "vector" : "matrix", a_array->nd);

	  if (info){
	       info->error_description = pygsl_error_str;
	       PyGSL_set_error_string_for_callback(info);
	  } else {
	       gsl_error(pygsl_error_str, filename, __LINE__, GSL_EBADLEN);
	  }
	  error_flag = GSL_EBADLEN;
	  goto fail;
     }
     

     
     for(i=0; i<nd; ++i){
	  if(dimensions[i] == -1 ){
	       switch(i){
	       case 0: DEBUG_MESS(2, "\t\t No one cares about its first dimension! %d", 0);  break;
	       case 1: DEBUG_MESS(2, "\t\t No one cares about its second dimension! %d", 0); break;
	       default: error_flag = GSL_ESANITY; line = __LINE__ - 3; goto fail; break;
	       }
	       continue;
	  } 
	  /* Check to be performed ... */
	  if( ((PyArrayObject *) (a_array))->dimensions[i] != (dimensions[i])){
	       sprintf(pygsl_error_str, "The size of argument % 3d did not match the expected size for the %d dimension." 
		       " I got % 3ld elements but expected % 3ld elements!\n", argnum, i, (long)a_array->dimensions[0], dimensions[0]);
	       if (info){
		    info->error_description = pygsl_error_str;
		    PyGSL_set_error_string_for_callback(info);
	       } else {
		    gsl_error(pygsl_error_str, filename, __LINE__, GSL_EBADLEN);
	       }	       
	       error_flag = GSL_EBADLEN;
	       line = __LINE__ - 11;
	       goto fail;
	  }
     }

     if(  ((PyArrayObject *) (a_array))->data == NULL){
	  gsl_error("Got an array object were the data was NULL!", filename, __LINE__, GSL_ESANITY);
	  error_flag = GSL_ESANITY;	  
	  line = __LINE__ - 4;
	  goto fail;
     }
     if(  ((PyArrayObject *) (a_array))->descr->type_num == (array_type) )
	  DEBUG_MESS(4, "\t\tArray type matched! %d", 0);
     else{
	  gsl_error("The array type did not match the spezified one!", filename, __LINE__, GSL_ESANITY);
	  error_flag = GSL_ESANITY;
	  line = __LINE__ - 6;
	  goto fail;
     }
     if ((flag &  PyGSL_CONTIGUOUS) == 0){
	  DEBUG_MESS(2, "\t\t Can deal with discontiguous arrays! %d", 0);
     } else {
	  if(!(((PyArrayObject *) (a_array))->flags & CONTIGUOUS)){
	       DEBUG_MESS(3, "array->flags %d requested flags %d", ((PyArrayObject *) (a_array))->flags, flag);
	       gsl_error("The array is not contiguous as requested!", filename, __LINE__, GSL_ESANITY);
	       error_flag = GSL_ESANITY;
	       line = __LINE__ - 3;
	       goto fail;
	  }
     }
     FUNC_MESS_END();
     return GSL_SUCCESS;    

 fail:
     PyGSL_add_traceback(NULL, filename, __FUNCTION__, line);
     return error_flag;
}

static PyArrayObject * 
PyGSL_PyArray_generate_gsl_vector_view(PyObject *src,
				       int array_type,
				       int argnum)
{
     int dimension;
     PyObject *tmp;
     PyArrayObject *a_array = NULL;

     FUNC_MESS_BEGIN();
     tmp = PyNumber_Int(src);
     if(!tmp){
	  sprintf(pygsl_error_str, "I could not convert argument number % 3d. to an integer.",
		  argnum);
	 PyErr_SetString(PyExc_TypeError, pygsl_error_str);
	 return NULL;
     }
     dimension = PyInt_AS_LONG(src);
     Py_DECREF(tmp);
     if(dimension <= 0){
	  sprintf(pygsl_error_str, "Argument number % 3d is % 10d< 0. Its the size of the vector and thus must be positive!",
		  argnum, dimension);
	 PyErr_SetString(PyExc_TypeError, pygsl_error_str);
	 return NULL;
     }
     
     a_array = (PyArrayObject *) PyGSL_New_Array(1, &dimension, array_type);
     if(NULL == a_array){
	  return NULL;
     }
     FUNC_MESS_END();
     return a_array;
}

static PyArrayObject * 
PyGSL_PyArray_generate_gsl_matrix_view(PyObject *src,
				      int array_type,
				      int argnum)
{
     PyObject *tmp;
     PyArrayObject *a_array = NULL;

     int dimensions[2], i;

     FUNC_MESS_BEGIN();     
     if(!PySequence_Check(src) || PySequence_Size(src) != 2){
	  sprintf(pygsl_error_str, "I need a sequence of two elements as argument number % 3d",
		  argnum);
	 PyErr_SetString(PyExc_TypeError, pygsl_error_str);
	 return NULL;

     }

     for(i = 0; i<2; i++){
	  tmp = PyNumber_Int(PySequence_GetItem(src, i));
	  if(!tmp){
	       sprintf(pygsl_error_str, "I could not convert argument number % 3d. for dimension %3d to an integer.",
		       argnum, i);
	       PyErr_SetString(PyExc_TypeError, pygsl_error_str);
	       return NULL;
	  }
	  dimensions[i] = PyInt_AS_LONG(tmp);
	  Py_DECREF(tmp);
	  if(dimensions[i] <= 0){
	       sprintf(pygsl_error_str, "Argument number % 3d is % 10d< 0. Its the size of the vector and thus must be positive!",
		       argnum, dimensions[i]);
	       PyErr_SetString(PyExc_TypeError, pygsl_error_str);
	       return NULL;
	  }

     }     
     a_array = (PyArrayObject *) PyGSL_New_Array(2, dimensions, array_type);
     if(NULL == a_array){
	  return NULL;
     }
     return a_array;
}

static PyArrayObject *
PyGSL_copy_gslvector_to_pyarray(const gsl_vector *x)
{     
     int dimension = -1, i;
     PyArrayObject *a_array = NULL;
     double tmp;

     FUNC_MESS_BEGIN();
     dimension = x->size;
     a_array = (PyArrayObject *) PyGSL_New_Array(1, &dimension, PyArray_DOUBLE);
     if (a_array == NULL) return NULL;
     for (i=0;i<dimension;i++){
       tmp = gsl_vector_get(x, i);
       ((double *) a_array->data)[i] = tmp;
       DEBUG_MESS(3, "\t\ta_array_%d = %f\n", i, tmp);
     }
     FUNC_MESS_END();
     return a_array;
}

static PyArrayObject *
PyGSL_copy_gslmatrix_to_pyarray(const gsl_matrix *x)
{     
     int dimensions[2], i, j;
     PyArrayObject *a_array = NULL;
     double tmp;
     char *myptr;

     FUNC_MESS_BEGIN();
     dimensions[0] = x->size1;
     dimensions[1] = x->size2;
     a_array = (PyArrayObject *) PyGSL_New_Array(2, dimensions, PyArray_DOUBLE);
     if (a_array == NULL) return NULL;
     for (i=0;i<dimensions[1];i++){
	  for (j=0;j<dimensions[0];j++){
	      myptr =  a_array->data + a_array->strides[0] * i  
		                     + a_array->strides[1] * j;
	       tmp = gsl_matrix_get(x, j, i);
	       *((double *) myptr) = tmp;
	       DEBUG_MESS(3, "\t\ta_array_%d = %f\n", i, tmp);
	  }
     }
     FUNC_MESS_END();
     return a_array;
}


/*
 * Set a descriptive error. The callback name is listed together with the "GSL Object"
 * that called it, and a error description.
 */
static int
PyGSL_copy_pyarray_to_gslvector(gsl_vector *f, PyObject *object, long n, PyGSL_error_info * info)
{
     PyArrayObject *a_array = NULL;
     double tmp;
     int i, argnum = -1;
     

     FUNC_MESS_BEGIN();
     if (info)
	  argnum = info->argnum;
     a_array = PyGSL_PyArray_PREPARE_gsl_vector_view(object, PyArray_DOUBLE, PyGSL_NON_CONTIGUOUS | PyGSL_INPUT_ARRAY, n, argnum, info);
     if(a_array == NULL){
          FUNC_MESS("PyArray_FromObject failed");
	  goto fail;
     }
    if(DEBUG>2){
      fprintf(stderr, "\t\ta_array->dimensions[0] = %d\n", a_array->dimensions[0]);
      fprintf(stderr, "\t\ta_array->strides[0] = %d\n", a_array->strides[0]);
    }

    for (i=0;i<n;i++){
	 tmp = *((double *) (a_array->data + a_array->strides[0] * i));
	 gsl_vector_set(f, i, tmp);
	 DEBUG_MESS(3, "\t\ta_array_%d = %f\n", i, tmp);

     }
    FUNC_MESS_END();
    Py_DECREF(a_array);
    return GSL_SUCCESS;
 fail:
    PyGSL_add_traceback(NULL, filename, __FUNCTION__, __LINE__);
    FUNC_MESS("Failure");
    Py_XDECREF(a_array);
    return GSL_FAILURE;
}

    


static int
PyGSL_copy_pyarray_to_gslmatrix(gsl_matrix *f, PyObject *object, long n, long p,  PyGSL_error_info * info)
{
     PyArrayObject *a_array = NULL;
     double tmp;
     char *myptr;
     int argnum=-1;
     long i, j;


     FUNC_MESS_BEGIN();


     
     if (info)
	  argnum = info->argnum;
     a_array = PyGSL_PyArray_PREPARE_gsl_matrix_view(object, PyArray_DOUBLE, PyGSL_NON_CONTIGUOUS | PyGSL_INPUT_ARRAY, n, p, info->argnum, info);
     if(a_array == NULL){
	  FUNC_MESS(" PyGSL_PyArray_PREPARE_gsl_matrix_view failed!");
	  goto fail;
     }

    assert(f->size1 == (size_t) n);
    assert(f->size2 == (size_t) p);


    for (i=0;i<n;i++){
	 for (j=0;j<p;j++){
	      myptr =  a_array->data + a_array->strides[0] * i  
		                     + a_array->strides[1] * j;
	      tmp = *((double *)(myptr));
	      DEBUG_MESS(3, "\t\ta_array[%ld,%ld] = %f\n", i, j, tmp);
	      gsl_matrix_set(f, i, j, tmp);
	 }
    }
    FUNC_MESS_END();
    Py_DECREF(a_array);
    return GSL_SUCCESS;
 fail:
    PyGSL_add_traceback(NULL, filename, __FUNCTION__, __LINE__);
    FUNC_MESS("  Failure");
    Py_XDECREF(a_array);
    return GSL_FAILURE;
}

static PyArrayObject * 
PyGSL_vector_or_double(PyObject *src, int flag, long size, int argnum, PyGSL_error_info * info)
{
     int line = -1;
     PyArrayObject * r = NULL;

     FUNC_MESS_BEGIN();
     r = PyGSL_PyArray_PREPARE_gsl_vector_view(src, PyArray_DOUBLE, PyGSL_CONTIGUOUS | PyGSL_INPUT_ARRAY, -1, argnum, NULL);
     if(r == NULL){
	  /* so try if it is a float ... */
	  double v;
	  /* was not an array, but lets see if it is a float, so lets clear the error .... */
	  PyErr_Clear();
	  FUNC_MESS("PyErr_Clear END");
	  if(PyGSL_PYFLOAT_TO_DOUBLE(src, &v, NULL) != GSL_SUCCESS){
	       FUNC_MESS("=> NOT FLOAT");
	       line = __LINE__ - 1;
	       goto fail;	    
	  }	 
	  FUNC_MESS("=> FLOAT");
	  int dim = 1;
	  r = (PyArrayObject *) PyGSL_New_Array(1, &dim, PyArray_DOUBLE);
	  if(r == NULL) {
	       line = __LINE__ - 2;
	       goto fail;
	  }
	  (*(double *)(r->data)) = v;
     }
     FUNC_MESS_END();
     return r;
 fail:
     Py_XDECREF(r);
     FUNC_MESS("Fail");
     return NULL;
}

#ifdef PyGSL_NUMPY
#include "block_helpers_numpy.ic"
#endif
#ifdef PyGSL_NUMERIC
#include "block_helpers_numeric.ic"
#endif
#ifdef PyGSL_NUMARRAY
#include "block_helpers_numarray.ic"
#endif
#if (!defined PyGSL_NUMPY) && (!defined  PyGSL_NUMERIC) && (! defined PyGSL_NUMARRAY)
#error "Neither numpy nor numarray nor numeric is defined!"
#endif

Reply via email to