Revision: 365 http://rpy.svn.sourceforge.net/rpy/?rev=365&view=rev Author: warnes Date: 2007-11-12 22:26:05 -0800 (Mon, 12 Nov 2007)
Log Message: ----------- More work on handling Numeric/NumPy array and scalar objects. Only NumPy string/unicode/char objects are still unhandled, AFAIK. Modified Paths: -------------- trunk/rpy/src/rpymodule.c Modified: trunk/rpy/src/rpymodule.c =================================================================== --- trunk/rpy/src/rpymodule.c 2007-11-13 06:13:22 UTC (rev 364) +++ trunk/rpy/src/rpymodule.c 2007-11-13 06:26:05 UTC (rev 365) @@ -363,84 +363,99 @@ /*******************/ /* String Variants */ /*******************/ -#ifdef PyArray_UNICODE /* NumPy */ - case PyArray_UNICODE: - case PyArray_STRING: - case PyArray_CHAR: - obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, + /* TODO: Add proper handling of NumPy character arrays. + The following code DOES NOT WORK: + + #if WITH_NUMERIC==3 + case PyArray_UNICODE: + case PyArray_STRING: + case PyArray_CHAR: + obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, PyArray_STRING, 0, 0); -#endif + #endif + The problem is that the PyArray call throws an exception, + presumably because we haven't given a width specifier. + + NumPy strings are fixed-width, and may not be null terminated. R only handles + null terminated (varying width) strings. We need a separate + code path to handle this, as it requires quite different + handling than the numeric arrays dealt with below. + */ + + /******************************************/ - /* All complex to (double,double) complex */ + /* All complex to (double,double) complex */ /******************************************/ -#ifdef PyArray_COMPLEX64 + +#if WITH_NUMERIC==1 /* Numeric */ + case PyArray_CFLOAT: + case PyArray_CDOUBLE: +#else /* NumPy */ case PyArray_COMPLEX64: case PyArray_COMPLEX128: #endif - case PyArray_CFLOAT: - case PyArray_CDOUBLE: obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, PyArray_CDOUBLE, 0, 0); break; -#ifdef PyArray_BOOL - /************************/ - /* Booleans to booleans */ - /************************/ - case PyArray_BOOL: - obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, - PyArray_BOOL, 0, 0); - break; -#endif - /********************************************************************************/ - /* All integers (except perhaps 64 bit integers on 32 bit platforms) to integer */ - /********************************************************************************/ + /**********************************************************************************/ + /* Convert all integers to platform integer (except 64 bit int on 32 bit platforms) */ + /************************************************************************************/ + +#if WITH_NUMERIC==1 /* Numeric */ case PyArray_UBYTE: case PyArray_SBYTE: case PyArray_SHORT: case PyArray_INT: case PyArray_LONG: -#ifdef PyArray_INT8 + obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, + PyArray_INT, 0, 0); + break; +#else /* NumPy */ + case PyArray_BOOL: case PyArray_INT8: - case PyArray_UINT8: + case PyArray_UINT8: case PyArray_INT16: case PyArray_UINT16: case PyArray_INT32: case PyArray_UINT32: -#endif -#if SIZEOF_INT == 8 && defined(PyArray_INT64) /* NumPy on 64 bit platform */ +#if PyArray_INT==PyArray_INT64 /* 64 bit platform */ case PyArray_INT64: case PyArray_UINT64: -#endif +#else obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, PyArray_INT, 0, 0); break; +#endif +#endif /**************************************************/ /* All floats (and over-sized integers) to double */ /**************************************************/ +#if WITH_NUMERIC==1 /* Numeric */ case PyArray_FLOAT: case PyArray_DOUBLE: -#ifdef PyArray_FLOAT32 +#else /* NumPy */ case PyArray_FLOAT32: case PyArray_FLOAT64: -#endif -#if SIZEOF_INT == 4 && defined(PyArray_INT64) /* NumPy on 32 bit platform */ +#if PyArray_INT!=PyArray_INT64 /* 32 bit platform */ case PyArray_INT64: case PyArray_UINT64: #endif +#endif obj = (PyArrayObject *)PyArray_ContiguousFromObject((PyObject *)obj, PyArray_DOUBLE, 0, 0); break; default: UNPROTECT(2); - PyErr_SetString(RPy_TypeConversionException, "Unhandled type in array, unable to convert to R object"); + PyErr_Format(RPy_TypeConversionException, + "Numeric/NumPy arrays containing %s are not supported.", + obj->ob_type->tp_name); return R_NilValue; break; - } @@ -487,6 +502,7 @@ SEXP robj; Py_complex c; PyObject *to_r_meth; + PyObject *tempObj; int do_decref = 0; if (obj==NULL) @@ -570,9 +586,20 @@ { PROTECT(robj = dict_to_R(obj)); } - else + else if (PyNumber_Check(obj)) /* generic number interface */ { - PyErr_Format(RPy_TypeConversionException, "cannot convert from type '%s'", + tempObj = PyNumber_Float(obj); + if(!tempObj) goto error; + + PROTECT(robj = NEW_NUMERIC(1)); + NUMERIC_DATA(robj)[0] = PyFloat_AsDouble(tempObj); + Py_DECREF(tempObj); + } + else + { + error: + PyErr_Format(RPy_TypeConversionException, + "cannot convert from type '%s'", obj->ob_type->tp_name); PROTECT(robj = NULL); /* Protected to avoid stack inbalance */ } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ rpy-list mailing list rpy-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rpy-list