[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