BUG: Fix complex to bool conversion in lowlevel_strided_loops #477

Merged
merged 2 commits into from Oct 4, 2012
@@ -811,9 +811,17 @@ static void
dst_value[0] = _CONVERT_FN(src_value[0]);
dst_value[1] = _CONVERT_FN(src_value[1]);
# elif !@aligned@
- dst_value = _CONVERT_FN(src_value[0]);
+# if @is_bool2@
+ dst_value = _CONVERT_FN(src_value[0]) || _CONVERT_FN(src_value[1]);
+# else
+ dst_value = _CONVERT_FN(src_value[0]);
+# endif
# else
- *(_TYPE2 *)dst = _CONVERT_FN(src_value[0]);
+# if @is_bool2@
+ *(_TYPE2 *)dst = _CONVERT_FN(src_value[0]) || _CONVERT_FN(src_value[1]);
+# else
+ *(_TYPE2 *)dst = _CONVERT_FN(src_value[0]);
+# endif
# endif
#else
# if @is_complex2@
@@ -1459,6 +1459,14 @@ def test_complex_scalar_complex_cast(self):
x = tp(1+2j)
assert_equal(complex(x), 1+2j)
+ def test_complex_boolean_cast(self):
@charris
charris Oct 2, 2012 NumPy member

Might as well test the astype method too.

@charris
charris Oct 2, 2012 NumPy member

And maybe logical_or.reduce and logical_and.reduce as well.

In [1]: a = ones(3)*1j

In [2]: logical_or.reduce(a)
Out[2]: True

In [3]: logical_and.reduce(a)
Out[3]: True

You could maybe put those tests in numpy/core/test_ufunc. If you want to go for completeness, you could do it for all numeric types. The easy way to do that is to use the typecodes in np.typecodes

In [4]: np.typecodes
Out[4]: 
{'All': '?bhilqpBHILQPefdgFDGSUVOMm',
 'AllFloat': 'efdgFDG',
 'AllInteger': 'bBhHiIlLqQpP',
 'Character': 'c',
 'Complex': 'FDG',
 'Datetime': 'Mm',
 'Float': 'efdg',
 'Integer': 'bhilqp',
 'UnsignedInteger': 'BHILQP'}
@charris
charris Oct 2, 2012 NumPy member

And if you do that and are working in the test directory you can run those tests by doing

charris@f16 [tests (pull-477)]$ python test_ufunc.py
+ """Ticket #2218"""
+ for tp in [np.csingle, np.cdouble, np.clongdouble]:
+ x = np.array([0, 0+0.5j, 0.5+0j], dtype=tp)
+ assert_equal(x.astype(bool), np.array([0, 1, 1], dtype=bool))
+ assert_(np.any(x))
+ assert_(np.all(x[1:]))
+
def test_uint_int_conversion(self):
x = 2**64 - 1
assert_equal(int(np.uint64(x)), x)