[Numpy-svn] r2763 - in trunk/numpy/core: . src

numpy-svn at scipy.org numpy-svn at scipy.org
Thu Jul 6 17:42:13 EDT 2006


Author: oliphant
Date: 2006-07-06 16:41:57 -0500 (Thu, 06 Jul 2006)
New Revision: 2763

Modified:
   trunk/numpy/core/__init__.py
   trunk/numpy/core/src/scalarmathmodule.c.src
   trunk/numpy/core/src/umathmodule.c.src
Log:
Speed up mod function using fmod and add use_pythonmath and use_scalarmath functions to alter the tables of the appropriate array scalars.

Modified: trunk/numpy/core/__init__.py
===================================================================
--- trunk/numpy/core/__init__.py	2006-07-06 20:32:49 UTC (rev 2762)
+++ trunk/numpy/core/__init__.py	2006-07-06 21:41:57 UTC (rev 2763)
@@ -17,7 +17,6 @@
 from memmap import *
 from defchararray import *
 import scalarmath
-del scalarmath
 del nt
 
 __all__ = ['char','rec','memmap','ma']
@@ -27,6 +26,8 @@
 __all__ += rec.__all__
 __all__ += char.__all__
 
+
+
 def test(level=1, verbosity=1):
     from numpy.testing import NumpyTest
     return NumpyTest().test(level, verbosity)

Modified: trunk/numpy/core/src/scalarmathmodule.c.src
===================================================================
--- trunk/numpy/core/src/scalarmathmodule.c.src	2006-07-06 20:32:49 UTC (rev 2762)
+++ trunk/numpy/core/src/scalarmathmodule.c.src	2006-07-06 21:41:57 UTC (rev 2763)
@@ -223,6 +223,7 @@
     if (a == 0 || b == 0) {
 	if (b == 0) generate_divbyzero_error();
 	*out = 0;
+        return;
     }
 #if @neg@
     else if ((a > 0) == (b > 0)) {
@@ -291,6 +292,7 @@
 **/
 static @name@ (*_basic_ at name@_floor)(@name@);
 static @name@ (*_basic_ at name@_sqrt)(@name@);
+static @name@ (*_basic_ at name@_fmod)(@name@, @name@);
 #define @name at _ctype_add(a, b, outp) *(outp) = a + b
 #define @name at _ctype_subtract(a, b, outp) *(outp) = a - b
 #define @name at _ctype_multiply(a, b, outp) *(outp) = a * b
@@ -336,7 +338,10 @@
 **/
 static void 
 @name at _ctype_remainder(@name@ a, @name@ b, @name@ *out) { 
-    *out = a - _basic_ at name@_floor(a/b)*b;
+    @name@ mod;
+    mod = _basic_ at name@_fmod(a, b);
+    if (mod && ((b < 0 != (mod < 0)))) mod += b;
+    *out = mod;
 } 
 /**end repeat**/ 
 
@@ -937,6 +942,8 @@
 };
 /**end repeat**/
 
+static void *saved_tables_arrtype[9];
+
 static void
 add_scalarmath(void)
 {
@@ -947,6 +954,16 @@
     Py at NAME@ArrType_Type.tp_as_number = &(@name at _as_number);
     Py at NAME@ArrType_Type.tp_richcompare = @name at _richcompare;
     /**end repeat**/
+
+    saved_tables_arrtype[0] = PyLongArrType_Type.tp_as_number;
+    saved_tables_arrtype[1] = PyLongArrType_Type.tp_compare;
+    saved_tables_arrtype[2] = PyLongArrType_Type.tp_richcompare;
+    saved_tables_arrtype[3] = PyDoubleArrType_Type.tp_as_number;
+    saved_tables_arrtype[4] = PyDoubleArrType_Type.tp_compare;
+    saved_tables_arrtype[5] = PyDoubleArrType_Type.tp_richcompare;
+    saved_tables_arrtype[6] = PyCDoubleArrType_Type.tp_as_number;
+    saved_tables_arrtype[7] = PyCDoubleArrType_Type.tp_compare;
+    saved_tables_arrtype[8] = PyCDoubleArrType_Type.tp_richcompare;
 }
 
 static int
@@ -1005,6 +1022,20 @@
     _basic_longdouble_sqrt = funcdata[j+2];
     Py_DECREF(obj);
 
+    /* Get the fmod functions */
+    obj = PyObject_GetAttrString(mm, "fmod");
+    if (obj == NULL) goto fail;
+    funcdata = ((PyUFuncObject *)obj)->data;
+    signatures = ((PyUFuncObject *)obj)->types;
+    i = 0;
+    j = 0;
+    while(signatures[i] != PyArray_FLOAT) {i+=3; j++;}
+    _basic_float_fmod = funcdata[j];
+    _basic_double_fmod = funcdata[j+1];
+    _basic_longdouble_fmod = funcdata[j+2];
+    Py_DECREF(obj);
+    return
+
     ret = 0;
  fail:
     Py_DECREF(mm);
@@ -1083,11 +1114,83 @@
     return Py_None;
 }
 
+char doc_usepythonmath[] = "";
+static PyObject *
+use_pythonmath(PyObject *dummy, PyObject *args)
+{
+    int n;
+    PyObject *obj;
+    n = PyTuple_GET_SIZE(args);
+    while(n--) {
+	obj = PyTuple_GET_ITEM(args, n);
+	if (obj == (PyObject *)(&PyInt_Type)) {
+	    PyLongArrType_Type.tp_as_number = saved_tables[0];
+	    PyLongArrType_Type.tp_compare = saved_tables[1];
+	    PyLongArrType_Type.tp_richcompare = saved_tables[2];
+	}
+	else if (obj == (PyObject *)(&PyFloat_Type)) {
+	    PyDoubleArrType_Type.tp_as_number = saved_tables[3];
+	    PyDoubleArrType_Type.tp_compare = saved_tables[4];
+	    PyDoubleArrType_Type.tp_richcompare = saved_tables[5];
+	}
+	else if (obj == (PyObject *)(&PyComplex_Type)) {
+	    PyCDoubleArrType_Type.tp_as_number = saved_tables[6];
+	    PyCDoubleArrType_Type.tp_compare = saved_tables[7];
+	    PyCDoubleArrType_Type.tp_richcompare = saved_tables[8];
+	} 
+	else {
+	    PyErr_SetString(PyExc_ValueError, 
+			    "arguments must be int, float, or complex");
+	    return NULL;
+	}
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+char doc_usescalarmath[] = "";
+static PyObject *
+use_scalarmath(PyObject *dummy, PyObject *args)
+{
+    int n;
+    PyObject *obj;
+    n = PyTuple_GET_SIZE(args);
+    while(n--) {
+	obj = PyTuple_GET_ITEM(args, n);
+	if (obj == (PyObject *)(&PyInt_Type)) {
+	    PyLongArrType_Type.tp_as_number = saved_tables_arrtype[0];
+	    PyLongArrType_Type.tp_compare = saved_tables_arrtype[1];
+	    PyLongArrType_Type.tp_richcompare = saved_tables_arrtype[2];
+	}
+	else if (obj == (PyObject *)(&PyFloat_Type)) {
+	    PyDoubleArrType_Type.tp_as_number = saved_tables_arrtype[3];
+	    PyDoubleArrType_Type.tp_compare = saved_tables_arrtype[4];
+	    PyDoubleArrType_Type.tp_richcompare = saved_tables_arrtype[5];
+	}
+	else if (obj == (PyObject *)(&PyComplex_Type)) {
+	    PyCDoubleArrType_Type.tp_as_number = saved_tables_arrtype[6];
+	    PyCDoubleArrType_Type.tp_compare = saved_tables_arrtype[7];
+	    PyCDoubleArrType_Type.tp_richcompare = saved_tables_arrtype[8];
+	} 
+	else {
+	    PyErr_SetString(PyExc_ValueError, 
+			    "arguments must be int, float, or complex");
+	    return NULL;
+	}
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
 static struct PyMethodDef methods[] = {
-    {"alter_scalars", (PyCFunction) alter_pyscalars,
+    {"alter_pythonmath", (PyCFunction) alter_pyscalars,
      METH_VARARGS, doc_alterpyscalars},
-    {"restore_scalars", (PyCFunction) restore_pyscalars,
+    {"restore_pythonmath", (PyCFunction) restore_pyscalars,
      METH_VARARGS, doc_restorepyscalars},
+    {"use_pythonmath", (PyCFunction) use_pythonmath,
+     METH_VARARGS, doc_usepythonmath},
+    {"use_scalarmath", (PyCFunction) use_scalarmath,
+     METH_VARARGS, doc_usescalarmath},
     {NULL, NULL, 0}
 };
 

Modified: trunk/numpy/core/src/umathmodule.c.src
===================================================================
--- trunk/numpy/core/src/umathmodule.c.src	2006-07-06 20:32:49 UTC (rev 2762)
+++ trunk/numpy/core/src/umathmodule.c.src	2006-07-06 21:41:57 UTC (rev 2763)
@@ -1633,8 +1633,11 @@
 	for(i=0; i<n; i++, i1+=is1, i2+=is2, op+=os) {
 		x = *((@typ@ *)i1);
 		y = *((@typ@ *)i2);
-		res = x - floor at c@(x/y)*y;
-		*((@typ@ *)op)= res;
+                res = fmod at c@(x, y);
+                if (res && ((y < 0) != (res < 0))) {
+                        res += y;
+                }
+                *((@typ@ *)op)= res;
 	}
 }
 /**end repeat**/




More information about the Numpy-svn mailing list