[Numpy-discussion] Type of 1st argument in Numexpr where()

Ivan Vilata i Balaguer ivilata at carabos.com
Wed Dec 20 07:02:26 EST 2006


Hi all,

I noticed that the set of ``where()`` functions defined by Numexpr all
have a signature like ``xfxx``, i.e. the first argument is a float and
the return, second and third arguments are of the same type (whatever it
is).

Since the first argument effectively represents a condition, wouldn't it
make more sense for it to be a boolean?  Booleans are already supported
by Numexpr, maybe the old signatures are just a legacy from the time
when Numexpr didn't support them.

I have attached a patch to the latest version of Numexpr which
implements this.

Cheers,

PS: It seems that http://numpy.scipy.org/ still points to the old
SourceForge list address.

::

	Ivan Vilata i Balaguer   >qo<   http://www.carabos.com/
	       Cárabos Coop. V.  V  V   Enjoy Data
	                          ""
-------------- next part --------------
Index: interp_body.c
===================================================================
--- interp_body.c	(revisión: 2439)
+++ interp_body.c	(copia de trabajo)
@@ -155,7 +155,7 @@
         case OP_POW_III: VEC_ARG2(i_dest = (i2 < 0) ? (1 / i1) : (long)pow(i1, i2));
         case OP_MOD_III: VEC_ARG2(i_dest = i1 % i2);
 
-        case OP_WHERE_IFII: VEC_ARG3(i_dest = f1 ? i2 : i3);
+        case OP_WHERE_IBII: VEC_ARG3(i_dest = b1 ? i2 : i3);
 
         case OP_CAST_FB: VEC_ARG1(f_dest = (long)b1);
         case OP_CAST_FI: VEC_ARG1(f_dest = (double)(i1));
@@ -175,7 +175,7 @@
         case OP_SQRT_FF: VEC_ARG1(f_dest = sqrt(f1));
         case OP_ARCTAN2_FFF: VEC_ARG2(f_dest = atan2(f1, f2));
 
-        case OP_WHERE_FFFF: VEC_ARG3(f_dest = f1 ? f2 : f3);
+        case OP_WHERE_FBFF: VEC_ARG3(f_dest = b1 ? f2 : f3);
 
         case OP_FUNC_FF: VEC_ARG1(f_dest = functions_f[arg2](f1));
         case OP_FUNC_FFF: VEC_ARG2(f_dest = functions_ff[arg3](f1, f2));
@@ -206,8 +206,8 @@
         case OP_EQ_BCC: VEC_ARG2(b_dest = (c1r == c2r && c1i == c2i) ? 1 : 0);
         case OP_NE_BCC: VEC_ARG2(b_dest = (c1r != c2r || c1i != c2i) ? 1 : 0);
 
-        case OP_WHERE_CFCC: VEC_ARG3(cr_dest = f1 ? c2r : c3r;
-                                     ci_dest = f1 ? c2i : c3i);
+        case OP_WHERE_CBCC: VEC_ARG3(cr_dest = b1 ? c2r : c3r;
+                                     ci_dest = b1 ? c2i : c3i);
         case OP_FUNC_CC: VEC_ARG1(ca.real = c1r;
                                   ca.imag = c1i;
                                   functions_cc[arg2](&ca, &ca);
Index: tests/test_numexpr.py
===================================================================
--- tests/test_numexpr.py	(revisión: 2439)
+++ tests/test_numexpr.py	(copia de trabajo)
@@ -186,8 +186,8 @@
           'sinh(a)',
           '2*a + (cos(3)+5)*sinh(cos(b))',
           '2*a + arctan2(a, b)',
-          'where(a, 2, b)',
-          'where((a-10).real, a, 2)',
+          'where(a != 0.0, 2, b)',
+          'where((a-10).real != 0.0, a, 2)',
           'cos(1+1)',
           '1+1',
           '1',
Index: interpreter.c
===================================================================
--- interpreter.c	(revisión: 2439)
+++ interpreter.c	(copia de trabajo)
@@ -45,7 +45,7 @@
     OP_DIV_III,
     OP_POW_III,
     OP_MOD_III,
-    OP_WHERE_IFII,
+    OP_WHERE_IBII,
 
     OP_CAST_FB,
     OP_CAST_FI,
@@ -63,7 +63,7 @@
     OP_TAN_FF,
     OP_SQRT_FF,
     OP_ARCTAN2_FFF,
-    OP_WHERE_FFFF,
+    OP_WHERE_FBFF,
     OP_FUNC_FF,
     OP_FUNC_FFF,
 
@@ -80,7 +80,7 @@
     OP_SUB_CCC,
     OP_MUL_CCC,
     OP_DIV_CCC,
-    OP_WHERE_CFCC,
+    OP_WHERE_CBCC,
     OP_FUNC_CC,
     OP_FUNC_CCC,
 
@@ -148,9 +148,9 @@
         case OP_POW_III:
             if (n == 0 || n == 1 || n == 2) return 'i';
             break;
-        case OP_WHERE_IFII:
+        case OP_WHERE_IBII:
             if (n == 0 || n == 2 || n == 3) return 'i';
-            if (n == 1) return 'f';
+            if (n == 1) return 'b';
             break;
         case OP_CAST_FB:
             if (n == 0) return 'f';
@@ -178,8 +178,9 @@
         case OP_ARCTAN2_FFF:
             if (n == 0 || n == 1 || n == 2) return 'f';
             break;
-        case OP_WHERE_FFFF:
-            if (n == 0 || n == 1 || n == 2 || n == 3) return 'f';
+        case OP_WHERE_FBFF:
+            if (n == 0 || n == 2 || n == 3) return 'f';
+            if (n == 1) return 'b';
             break;
         case OP_FUNC_FF:
             if (n == 0 || n == 1) return 'f';
@@ -217,9 +218,9 @@
         case OP_DIV_CCC:
             if (n == 0 || n == 1 || n == 2) return 'c';
             break;
-        case OP_WHERE_CFCC:
+        case OP_WHERE_CBCC:
             if (n == 0 || n == 2 || n == 3) return 'c';
-            if (n == 1) return 'f';
+            if (n == 1) return 'b';
             break;
         case OP_FUNC_CC:
             if (n == 0 || n == 1) return 'c';
@@ -1320,7 +1321,7 @@
     add_op("div_iii", OP_DIV_III);
     add_op("pow_iii", OP_POW_III);
     add_op("mod_iii", OP_MOD_III);
-    add_op("where_ifii", OP_WHERE_IFII);
+    add_op("where_ibii", OP_WHERE_IBII);
 
     add_op("cast_fb", OP_CAST_FB);
     add_op("cast_fi", OP_CAST_FI);
@@ -1339,7 +1340,7 @@
     add_op("tan_ff", OP_TAN_FF);
     add_op("sqrt_ff", OP_SQRT_FF);
     add_op("arctan2_fff", OP_ARCTAN2_FFF);
-    add_op("where_ffff", OP_WHERE_FFFF);
+    add_op("where_fbff", OP_WHERE_FBFF);
     add_op("func_ff", OP_FUNC_FF);
     add_op("func_fff", OP_FUNC_FFF);
 
@@ -1356,7 +1357,7 @@
     add_op("sub_ccc", OP_SUB_CCC);
     add_op("mul_ccc", OP_MUL_CCC);
     add_op("div_ccc", OP_DIV_CCC);
-    add_op("where_cfcc", OP_WHERE_CFCC);
+    add_op("where_cbcc", OP_WHERE_CBCC);
     add_op("func_cc", OP_FUNC_CC);
     add_op("func_ccc", OP_FUNC_CCC);
 
Index: timing.py
===================================================================
--- timing.py	(revisión: 2439)
+++ timing.py	(copia de trabajo)
@@ -88,13 +88,13 @@
 """ % ((array_size,)*3)
 expr5 = 'where(0.1*a > arctan2(a, b), 2*a, arctan2(a,b))'
 
-expr6 = 'where(a, 2, b)'
+expr6 = 'where(a != 0.0, 2, b)'
 
-expr7 = 'where(a-10, a, 2)'
+expr7 = 'where(a-10 != 0.0, a, 2)'
 
-expr8 = 'where(a%2, b+5, 2)'
+expr8 = 'where(a%2 != 0.0, b+5, 2)'
 
-expr9 = 'where(a%2, 2, b+5)'
+expr9 = 'where(a%2 != 0.0, 2, b+5)'
 
 expr10 = 'a**2 + (b+1)**-2.5'
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 309 bytes
Desc: Digital signature
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20061220/9f955e95/attachment.sig>


More information about the NumPy-Discussion mailing list