Skip to content

Commit

Permalink
Merge branch 'master' of git@github.com:numpy/numpy
Browse files Browse the repository at this point in the history
  • Loading branch information
Pearu Peterson committed Oct 16, 2010
2 parents 1ef8aac + 93f7521 commit 43b05fd
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 39 deletions.
2 changes: 1 addition & 1 deletion numpy/core/src/multiarray/convert_datatype.c
Expand Up @@ -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 "
Expand Down
2 changes: 1 addition & 1 deletion numpy/core/src/scalarmathmodule.c.src
Expand Up @@ -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 "
Expand Down
30 changes: 30 additions & 0 deletions numpy/core/src/umath/loops.c.src
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions numpy/core/src/umath/loops.h
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions numpy/core/src/umath/loops.h.src
Expand Up @@ -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
Expand Down
27 changes: 21 additions & 6 deletions numpy/core/src/umath/umathmodule.c.src
Expand Up @@ -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,
Expand All @@ -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
};
Expand All @@ -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);
Expand Down
27 changes: 21 additions & 6 deletions numpy/core/tests/test_umath.py
Expand Up @@ -379,14 +379,29 @@ def test_nan_any(self):


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):
Expand Down
36 changes: 11 additions & 25 deletions numpy/distutils/fcompiler/gnu.py
Expand Up @@ -202,8 +202,18 @@ def get_flags_opt(self):
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'
Expand Down Expand Up @@ -249,30 +259,6 @@ def version_match(self, version_string):

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':
Expand Down

0 comments on commit 43b05fd

Please sign in to comment.