summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorArink Verma <arinkverma@gmail.com>2013-08-03 04:25:46 +0530
committerArink Verma <arinkverma@gmail.com>2013-08-30 02:14:29 +0530
commit70de8aa2b3a3b300c6a858cbdbb9226ce46591e1 (patch)
treebfc4da6fbae624f953d5893823a086ce01a54a47 /numpy/core
parentbec793a28a46fce9a4212e058645f017adfa9f74 (diff)
downloadnumpy-70de8aa2b3a3b300c6a858cbdbb9226ce46591e1.tar.gz
ENH: Avoiding conversion of integer to NumPy Scalar.
There is a bottleneck in scalar operations, when trying to extract the underlying C value from a Python integer/float. I have avoid conversion for know integer type but extracting its value.
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/src/scalarmathmodule.c.src136
-rw-r--r--numpy/core/tests/test_scalarmath.py28
2 files changed, 151 insertions, 13 deletions
diff --git a/numpy/core/src/scalarmathmodule.c.src b/numpy/core/src/scalarmathmodule.c.src
index d789a3dd4..5233d33c8 100644
--- a/numpy/core/src/scalarmathmodule.c.src
+++ b/numpy/core/src/scalarmathmodule.c.src
@@ -661,21 +661,13 @@ static void
*/
/**begin repeat
- * #name = byte, ubyte, short, ushort, int, uint,
- * long, ulong, longlong, ulonglong,
- * half, float, longdouble,
+ * #name = longlong, ulonglong, half, float, longdouble,
* cfloat, cdouble, clongdouble#
- * #type = npy_byte, npy_ubyte, npy_short, npy_ushort, npy_int, npy_uint,
- * npy_long, npy_ulong, npy_longlong, npy_ulonglong,
- * npy_half, npy_float, npy_longdouble,
+ * #type = npy_longlong, npy_ulonglong, npy_half, npy_float, npy_longdouble,
* npy_cfloat, npy_cdouble, npy_clongdouble#
- * #Name = Byte, UByte, Short, UShort, Int, UInt,
- * Long, ULong, LongLong, ULongLong,
- * Half, Float, LongDouble,
+ * #Name = LongLong, ULongLong, Half, Float, LongDouble,
* CFloat, CDouble, CLongDouble#
- * #TYPE = NPY_BYTE, NPY_UBYTE, NPY_SHORT, NPY_USHORT, NPY_INT, NPY_UINT,
- * NPY_LONG, NPY_ULONG, NPY_LONGLONG, NPY_ULONGLONG,
- * NPY_HALF, NPY_FLOAT, NPY_LONGDOUBLE,
+ * #TYPE = NPY_LONGLONG, NPY_ULONGLONG, NPY_HALF, NPY_FLOAT, NPY_LONGDOUBLE,
* NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE#
*/
@@ -719,7 +711,6 @@ _@name@_convert_to_ctype(PyObject *a, @type@ *arg1)
/**end repeat**/
-
/* Same as above but added exact checks against known python types for speed */
/**begin repeat
@@ -778,6 +769,125 @@ _@name@_convert_to_ctype(PyObject *a, @type@ *arg1)
/**begin repeat
+ * #name = ubyte, ushort, uint, ulong#
+ * #type = npy_ubyte, npy_ushort, npy_uint, npy_ulong#
+ * #Name = UByte, UShort, UInt, ULong#
+ * #TYPE = NPY_UBYTE, NPY_USHORT, NPY_UINT, NPY_ULONG#
+ */
+
+static int
+_@name@_convert_to_ctype(PyObject *a, @type@ *arg1)
+{
+ PyObject *temp;
+
+#if PY_VERSION_HEX >= 0x03000000
+ if(PyLong_CheckExact(a)){
+ *arg1 = PyLong_AsUnsignedLong(a);
+ return 0;
+ }
+#else
+ if (PyInt_CheckExact(a)){
+ *arg1 = PyInt_AS_LONG(a);
+ return 0;
+ }
+#endif
+
+ if (PyArray_IsScalar(a, @Name@)) {
+ *arg1 = PyArrayScalar_VAL(a, @Name@);
+ return 0;
+ }
+ else if (PyArray_IsScalar(a, Generic)) {
+ PyArray_Descr *descr1;
+
+ if (!PyArray_IsScalar(a, Number)) {
+ return -1;
+ }
+ descr1 = PyArray_DescrFromTypeObject((PyObject *)Py_TYPE(a));
+ if (PyArray_CanCastSafely(descr1->type_num, @TYPE@)) {
+ PyArray_CastScalarDirect(a, descr1, arg1, @TYPE@);
+ Py_DECREF(descr1);
+ return 0;
+ }
+ else {
+ Py_DECREF(descr1);
+ return -1;
+ }
+ }
+ else if (PyArray_GetPriority(a, NPY_PRIORITY) > NPY_PRIORITY) {
+ return -2;
+ }
+ else if ((temp = PyArray_ScalarFromObject(a)) != NULL) {
+ int retval = _@name@_convert_to_ctype(temp, arg1);
+
+ Py_DECREF(temp);
+ return retval;
+ }
+ return -2;
+}
+
+/**end repeat**/
+
+
+/**begin repeat
+ * #name = byte, short, int, long#
+ * #type = npy_byte, npy_short, npy_int, npy_long#
+ * #Name = Byte, Short, Int, Long#
+ * #TYPE = NPY_BYTE, NPY_SHORT, NPY_INT, NPY_LONG#
+ */
+
+static int
+_@name@_convert_to_ctype(PyObject *a, @type@ *arg1)
+{
+ PyObject *temp;
+
+#if PY_VERSION_HEX >= 0x03000000
+ if(PyLong_CheckExact(a)){
+ *arg1 = PyLong_AsLong(a);
+ return 0;
+ }
+#else
+ if (PyInt_CheckExact(a)){
+ *arg1 = PyInt_AS_LONG(a);
+ return 0;
+ }
+#endif
+
+ if (PyArray_IsScalar(a, @Name@)) {
+ *arg1 = PyArrayScalar_VAL(a, @Name@);
+ return 0;
+ }
+ else if (PyArray_IsScalar(a, Generic)) {
+ PyArray_Descr *descr1;
+
+ if (!PyArray_IsScalar(a, Number)) {
+ return -1;
+ }
+ descr1 = PyArray_DescrFromTypeObject((PyObject *)Py_TYPE(a));
+ if (PyArray_CanCastSafely(descr1->type_num, @TYPE@)) {
+ PyArray_CastScalarDirect(a, descr1, arg1, @TYPE@);
+ Py_DECREF(descr1);
+ return 0;
+ }
+ else {
+ Py_DECREF(descr1);
+ return -1;
+ }
+ }
+ else if (PyArray_GetPriority(a, NPY_PRIORITY) > NPY_PRIORITY) {
+ return -2;
+ }
+ else if ((temp = PyArray_ScalarFromObject(a)) != NULL) {
+ int retval = _@name@_convert_to_ctype(temp, arg1);
+
+ Py_DECREF(temp);
+ return retval;
+ }
+ return -2;
+}
+
+/**end repeat**/
+
+/**begin repeat
* #name = byte, ubyte, short, ushort, int, uint,
* long, ulong, longlong, ulonglong,
* half, float, double, cfloat, cdouble#
diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py
index a4cc5e711..ba1a45a85 100644
--- a/numpy/core/tests/test_scalarmath.py
+++ b/numpy/core/tests/test_scalarmath.py
@@ -139,6 +139,34 @@ class TestConversion(TestCase):
a = np.array(l[:3], dtype=np.uint64)
assert_equal([int(_m) for _m in a], li[:3])
+ def test_int_value_behaviour(self):
+ l = [0, 2**7-1, 2**15-1, 2**31-1, 2**63-1]
+ li = [-1, -2**7, -2**15, -2**31, -2**63]
+ x = 1
+ for T in [np.int8, np.int16, np.int32, np.int64]:
+ a1 = np.array([l[:x]],dtype=T)
+ b1= np.array([li[:x]], dtype=T)
+ assert_equal(-a1-1,b1)
+
+ a2 = np.array([l[x]],dtype=T)
+ b2= np.array([li[x]], dtype=T)
+ assert_equal(a2,b2-1)
+ x = x+1
+
+
+ l = [0, 2**8-1, 2**16-1, 2**32-1, 2**64-1]
+ li = [1, 2**8, 2**16, 2**32, 2**64]
+ x = 1
+ for T in [np.uint8, np.uint16, np.uint32, np.uint64]:
+ a1 = np.array([l[:x]],dtype=T)
+ b1= np.array([li[:x]], dtype=T)
+ assert_equal(a1+1,b1)
+
+ a2 = np.array([l[x]],dtype=T)
+ b2= np.array([0], dtype=T)
+ assert_equal(a2+1,b2)
+ x = x+1
+
def test_iinfo_long_values(self):
for code in 'bBhH':