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

Reply via email to