diff options
author | Pearu Peterson <pearu@pearu-laptop.(none)> | 2010-10-16 21:38:04 +0300 |
---|---|---|
committer | Pearu Peterson <pearu@pearu-laptop.(none)> | 2010-10-16 21:38:04 +0300 |
commit | 43b05fdd1c0ba1c6686297d16d257985dd986d3b (patch) | |
tree | fa1da8d128f0b91665eddf3edccaa7b68370ab12 | |
parent | 1ef8aac121008e558040d8937788daed46ce8ca4 (diff) | |
parent | 93f7521dd0ac9edc0034eec5501a126cc4683b70 (diff) | |
download | numpy-43b05fdd1c0ba1c6686297d16d257985dd986d3b.tar.gz |
Merge branch 'master' of git@github.com:numpy/numpy
-rw-r--r-- | numpy/core/src/multiarray/convert_datatype.c | 2 | ||||
-rw-r--r-- | numpy/core/src/scalarmathmodule.c.src | 2 | ||||
-rw-r--r-- | numpy/core/src/umath/loops.c.src | 30 | ||||
-rw-r--r-- | numpy/core/src/umath/loops.h | 6 | ||||
-rw-r--r-- | numpy/core/src/umath/loops.h.src | 2 | ||||
-rw-r--r-- | numpy/core/src/umath/umathmodule.c.src | 27 | ||||
-rw-r--r-- | numpy/core/tests/test_umath.py | 27 | ||||
-rw-r--r-- | numpy/distutils/fcompiler/gnu.py | 36 |
8 files changed, 93 insertions, 39 deletions
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index 5cb62b82f..f93a45717 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -121,7 +121,7 @@ PyArray_GetCastFunc(PyArray_Descr *descr, int type_num) #if PY_VERSION_HEX >= 0x02050000 ret = PyErr_WarnEx(cls, "Casting complex values to real discards the imaginary " - "part", 0); + "part", 1); #else ret = PyErr_Warn(cls, "Casting complex values to real discards the imaginary " diff --git a/numpy/core/src/scalarmathmodule.c.src b/numpy/core/src/scalarmathmodule.c.src index 6261c4c73..6913f517d 100644 --- a/numpy/core/src/scalarmathmodule.c.src +++ b/numpy/core/src/scalarmathmodule.c.src @@ -990,7 +990,7 @@ emit_complexwarning() #if PY_VERSION_HEX >= 0x02050000 return PyErr_WarnEx(cls, "Casting complex values to real discards the imaginary " - "part", 0); + "part", 1); #else return PyErr_Warn(cls, "Casting complex values to real discards the imaginary " diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src index 850126482..c61d16ae4 100644 --- a/numpy/core/src/umath/loops.c.src +++ b/numpy/core/src/umath/loops.c.src @@ -1286,6 +1286,36 @@ NPY_NO_EXPORT void *((@type@ *)op1) = ldexp@c@(in1, in2); } } + +NPY_NO_EXPORT void +@TYPE@_ldexp_long(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)) +{ + /* + * Additional loop to handle long integer inputs (cf. #866, #1633). + * long != int on many 64-bit platforms, so we need this second loop + * to handle the default integer type. + */ + BINARY_LOOP { + const @type@ in1 = *(@type@ *)ip1; + const long in2 = *(long *)ip2; + if (((int)in2) == in2) { + /* Range OK */ + *((@type@ *)op1) = ldexp@c@(in1, ((int)in2)); + } + else { + /* + * Outside int range -- also ldexp will overflow in this case, + * given that exponent has less bits than int. + */ + if (in2 > 0) { + *((@type@ *)op1) = ldexp@c@(in1, NPY_MAX_INT); + } + else { + *((@type@ *)op1) = ldexp@c@(in1, NPY_MIN_INT); + } + } + } +} #endif #define @TYPE@_true_divide @TYPE@_divide diff --git a/numpy/core/src/umath/loops.h b/numpy/core/src/umath/loops.h index 59e9556c2..7cb4b22cc 100644 --- a/numpy/core/src/umath/loops.h +++ b/numpy/core/src/umath/loops.h @@ -1675,6 +1675,8 @@ FLOAT_frexp(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); #ifdef HAVE_LDEXPF NPY_NO_EXPORT void FLOAT_ldexp(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); +NPY_NO_EXPORT void +FLOAT_ldexp_long(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); #endif #define FLOAT_true_divide FLOAT_divide @@ -1827,6 +1829,8 @@ DOUBLE_frexp(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)) #ifdef HAVE_LDEXP NPY_NO_EXPORT void DOUBLE_ldexp(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); +NPY_NO_EXPORT void +DOUBLE_ldexp_long(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); #endif #define DOUBLE_true_divide DOUBLE_divide @@ -1979,6 +1983,8 @@ LONGDOUBLE_frexp(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(fu #ifdef HAVE_LDEXPL NPY_NO_EXPORT void LONGDOUBLE_ldexp(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); +NPY_NO_EXPORT void +LONGDOUBLE_ldexp_long(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); #endif #define LONGDOUBLE_true_divide LONGDOUBLE_divide diff --git a/numpy/core/src/umath/loops.h.src b/numpy/core/src/umath/loops.h.src index ca3fb37ee..33dfe882e 100644 --- a/numpy/core/src/umath/loops.h.src +++ b/numpy/core/src/umath/loops.h.src @@ -268,6 +268,8 @@ NPY_NO_EXPORT void #ifdef HAVE_LDEXP@C@ NPY_NO_EXPORT void @TYPE@_ldexp(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); +NPY_NO_EXPORT void +@TYPE@_ldexp_long(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func)); #endif #define @TYPE@_true_divide @TYPE@_divide diff --git a/numpy/core/src/umath/umathmodule.c.src b/numpy/core/src/umath/umathmodule.c.src index 9694f521d..c3da9f3d3 100644 --- a/numpy/core/src/umath/umathmodule.c.src +++ b/numpy/core/src/umath/umathmodule.c.src @@ -164,6 +164,8 @@ static PyUFuncGenericFunction frexp_functions[] = { }; static void * blank3_data[] = { (void *)NULL, (void *)NULL, (void *)NULL}; +static void * blank6_data[] = { (void *)NULL, (void *)NULL, (void *)NULL, + (void *)NULL, (void *)NULL, (void *)NULL}; static char frexp_signatures[] = { #ifdef HAVE_FREXPF PyArray_FLOAT, PyArray_FLOAT, PyArray_INT, @@ -174,22 +176,35 @@ static char frexp_signatures[] = { #endif }; +#if NPY_SIZEOF_LONG == NPY_SIZEOF_INT +#define LDEXP_LONG(typ) typ##_ldexp +#else +#define LDEXP_LONG(typ) typ##_ldexp_long +#endif + static PyUFuncGenericFunction ldexp_functions[] = { #ifdef HAVE_LDEXPF FLOAT_ldexp, + LDEXP_LONG(FLOAT), #endif - DOUBLE_ldexp + DOUBLE_ldexp, + LDEXP_LONG(DOUBLE) #ifdef HAVE_LDEXPL - ,LONGDOUBLE_ldexp + , + LONGDOUBLE_ldexp, + LDEXP_LONG(LONGDOUBLE) #endif }; static char ldexp_signatures[] = { #ifdef HAVE_LDEXPF PyArray_FLOAT, PyArray_INT, PyArray_FLOAT, + PyArray_FLOAT, PyArray_LONG, PyArray_FLOAT, #endif + PyArray_DOUBLE, PyArray_INT, PyArray_DOUBLE, PyArray_DOUBLE, PyArray_LONG, PyArray_DOUBLE #ifdef HAVE_LDEXPL + ,PyArray_LONGDOUBLE, PyArray_INT, PyArray_LONGDOUBLE ,PyArray_LONGDOUBLE, PyArray_LONG, PyArray_LONGDOUBLE #endif }; @@ -213,14 +228,14 @@ InitOtherOperators(PyObject *dictionary) { PyDict_SetItemString(dictionary, "frexp", f); Py_DECREF(f); - num = 1; + num = 2; #ifdef HAVE_LDEXPL - num += 1; + num += 2; #endif #ifdef HAVE_LDEXPF - num += 1; + num += 2; #endif - f = PyUFunc_FromFuncAndData(ldexp_functions, blank3_data, ldexp_signatures, num, + f = PyUFunc_FromFuncAndData(ldexp_functions, blank6_data, ldexp_signatures, num, 2, 1, PyUFunc_None, "ldexp", "Compute y = x1 * 2**x2.",0); PyDict_SetItemString(dictionary, "ldexp", f); diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py index 2dace8c16..1245030a4 100644 --- a/numpy/core/tests/test_umath.py +++ b/numpy/core/tests/test_umath.py @@ -379,14 +379,29 @@ class TestArctan2SpecialValues(TestCase): class TestLdexp(TestCase): + def _check_ldexp(self, tp): + assert_almost_equal(ncu.ldexp(np.array(2., np.float32), + np.array(3, tp)), 16.) + assert_almost_equal(ncu.ldexp(np.array(2., np.float64), + np.array(3, tp)), 16.) + assert_almost_equal(ncu.ldexp(np.array(2., np.longdouble), + np.array(3, tp)), 16.) + def test_ldexp(self): + # The default Python int type should work assert_almost_equal(ncu.ldexp(2., 3), 16.) - assert_almost_equal(ncu.ldexp(np.array(2., np.float32), np.array(3, np.int16)), 16.) - assert_almost_equal(ncu.ldexp(np.array(2., np.float32), np.array(3, np.int32)), 16.) - assert_almost_equal(ncu.ldexp(np.array(2., np.float64), np.array(3, np.int16)), 16.) - assert_almost_equal(ncu.ldexp(np.array(2., np.float64), np.array(3, np.int32)), 16.) - assert_almost_equal(ncu.ldexp(np.array(2., np.longdouble), np.array(3, np.int16)), 16.) - assert_almost_equal(ncu.ldexp(np.array(2., np.longdouble), np.array(3, np.int32)), 16.) + # The following int types should all be accepted + self._check_ldexp(np.int8) + self._check_ldexp(np.int16) + self._check_ldexp(np.int32) + self._check_ldexp('i') + self._check_ldexp('l') + + def test_ldexp_overflow(self): + imax = np.iinfo(np.dtype('l')).max + imin = np.iinfo(np.dtype('l')).min + assert_equal(ncu.ldexp(2., imax), np.inf) + assert_equal(ncu.ldexp(2., imin), 0) class TestMaximum(TestCase): diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py index becdefad5..632c6d97a 100644 --- a/numpy/distutils/fcompiler/gnu.py +++ b/numpy/distutils/fcompiler/gnu.py @@ -202,8 +202,18 @@ class GnuFCompiler(FCompiler): opt.append('-funroll-loops') return opt + def _c_arch_flags(self): + """ Return detected arch flags from CFLAGS """ + from distutils import sysconfig + cflags = sysconfig.get_config_vars()['CFLAGS'] + arch_re = re.compile(r"-arch\s+(\w+)") + arch_flags = [] + for arch in arch_re.findall(cflags): + arch_flags += ['-arch', arch] + return arch_flags + def get_flags_arch(self): - return [] + return self._c_arch_flags() class Gnu95FCompiler(GnuFCompiler): compiler_type = 'gnu95' @@ -249,30 +259,6 @@ class Gnu95FCompiler(GnuFCompiler): g2c = 'gfortran' - def _universal_flags(self, cmd): - """Return a list of -arch flags for every supported architecture.""" - if not sys.platform == 'darwin': - return [] - arch_flags = [] - for arch in ["ppc", "i686", "x86_64", "ppc64"]: - if _can_target(cmd, arch): - arch_flags.extend(["-arch", arch]) - return arch_flags - - def get_flags(self): - flags = GnuFCompiler.get_flags(self) - arch_flags = self._universal_flags(self.compiler_f90) - if arch_flags: - flags[:0] = arch_flags - return flags - - def get_flags_linker_so(self): - flags = GnuFCompiler.get_flags_linker_so(self) - arch_flags = self._universal_flags(self.linker_so) - if arch_flags: - flags[:0] = arch_flags - return flags - def get_library_dirs(self): opt = GnuFCompiler.get_library_dirs(self) if sys.platform == 'win32': |