From: Bill S. <wf...@sa...> - 2006-09-28 16:43:52
|
I am wrapping code using swig and extending it to use numpy. One class method I wrap (let's call it myElements()) returns an array of ints, and I convert it to a numpy array with PyArray_SimpleNew(1,n,'i'); I obtain the data pointer, fill in the values and return it as the method return argument. In python, it is common to want to loop over this array and treat its elements as integers: for row in map.myElements(): matrix.setElements(row, [row-1,row,row+1], [-1.0,2.0,-1.0]) On a 32-bit machine, this has worked fine, but on a 64-bit machine, I get a type error: TypeError: in method 'setElements', argument 2 of type 'int' because row is a <type 'int32scalar'>. It would be nice if I could get the integer conversion to work automatically under the covers, but I'm not exactly sure how to make that work. ** Bill Spotz ** ** Sandia National Laboratories Voice: (505)845-0170 ** ** P.O. Box 5800 Fax: (505)284-5451 ** ** Albuquerque, NM 87185-0370 Email: wf...@sa... ** |
From: Travis O. <oli...@ie...> - 2006-09-28 18:03:33
|
Bill Spotz wrote: > I am wrapping code using swig and extending it to use numpy. > > One class method I wrap (let's call it myElements()) returns an array > of ints, and I convert it to a numpy array with > > PyArray_SimpleNew(1,n,'i'); > You should probably use NPY_INT instead of 'i' for the type-code. > I obtain the data pointer, fill in the values and return it as the > method return argument. > > In python, it is common to want to loop over this array and treat its > elements as integers: > > for row in map.myElements(): > matrix.setElements(row, [row-1,row,row+1], [-1.0,2.0,-1.0]) > > On a 32-bit machine, this has worked fine, but on a 64-bit machine, I > get a type error: > > TypeError: in method 'setElements', argument 2 of type 'int' > > because row is a <type 'int32scalar'>. > > It would be nice if I could get the integer conversion to work > automatically under the covers, but I'm not exactly sure how to make > that work. > Yeah, It can be confusing, at first. You just have to make sure you are matching the right c-data-types. I'm not quite sure what the problem here is given your description, because I don't know what setElements expects. My best guess, is that it is related to the fact that a Python int uses the 'long' c-type. Thus, you should very likely be using PyArray_SimpleNew(1, n, NPY_LONG) instead of int so that your integer array always matches what Python is using as integers. The other option is to improve your converter in setElements so that it can understand any of the array scalar integers and not just the default Python integer. The reason this all worked on 32-bit systems is probably the array scalar corresponding to NPY_INT is a sub-class of the Python integer. It can't be on a 64-bit platform because of binary incompatibility of the layout. Hope that helps. -Travis |
From: Bill S. <wf...@sa...> - 2006-09-29 00:12:22
|
On Sep 28, 2006, at 12:03 PM, Travis Oliphant wrote: > The other option is to improve your converter in setElements so > that it > can understand any of the array scalar integers and not just the > default > Python integer. I think this may be the best approach. This may be something worthwhile to put in the numpy.i interface file: a set of typemaps that handle a set of basic conversions for those array scalar types for which it makes sense. I'll look into it. ** Bill Spotz ** ** Sandia National Laboratories Voice: (505)845-0170 ** ** P.O. Box 5800 Fax: (505)284-5451 ** ** Albuquerque, NM 87185-0370 Email: wf...@sa... ** |
From: Travis O. <oli...@ee...> - 2006-09-29 01:22:38
|
Bill Spotz wrote: >On Sep 28, 2006, at 12:03 PM, Travis Oliphant wrote: > > > >>The other option is to improve your converter in setElements so >>that it >>can understand any of the array scalar integers and not just the >>default >>Python integer. >> >> > >I think this may be the best approach. > >This may be something worthwhile to put in the numpy.i interface >file: a set of typemaps that handle a set of basic conversions for >those array scalar types for which it makes sense. I'll look into it. > > That's a good idea. Notice that there are some routines for making your life easier here. You should look at the tp_int function for the gentype array (it converts scalars to arrays). You call the "__int__" special method of the scalar to convert it to a Python integer. You should first check to see that it is an integer scalar PyArray_IsScalar(obj, Integer) because the "__int__" method coerces to an integer if it is a float (but maybe you want that behavior). There are other functions in the C-API that return the data directly from the scalar --- check them out. The macros in arrayscalar.h are useful. -Travis |