Skip to content

Commit

Permalink
Merge branch 'maintenance/1.5.x' of github.com:numpy/numpy into maint…
Browse files Browse the repository at this point in the history
…enance/1.5.x
  • Loading branch information
charris committed Oct 17, 2010
2 parents cc8673e + b55eacd commit 427d3fc
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 53 deletions.
23 changes: 9 additions & 14 deletions numpy/add_newdocs.py
Expand Up @@ -1295,12 +1295,9 @@
dot(`a`, `b`). If the first argument is complex the complex conjugate
of the first argument is used for the calculation of the dot product.
For 2-D arrays it is equivalent to matrix multiplication, and for 1-D
arrays to inner product of vectors (with complex conjugation of `a`).
For N dimensions it is a sum product over the last axis of `a` and
the second-to-last of `b`::
dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
Note that `vdot` handles multidimensional arrays differently than `dot`:
it does *not* perform a matrix product, but flattens input arguments
to 1-D vectors first. Consequently, it should only be used for vectors.
Parameters
----------
Expand All @@ -1313,21 +1310,14 @@
Returns
-------
output : ndarray
Returns dot product of `a` and `b`. Can be an int, float, or
Dot product of `a` and `b`. Can be an int, float, or
complex depending on the types of `a` and `b`.
See Also
--------
dot : Return the dot product without using the complex conjugate of the
first argument.
Notes
-----
The dot product is the summation of element wise multiplication.
.. math::
a \\cdot b = \\sum_{i=1}^n a_i^*b_i = a_1^*b_1+a_2^*b_2+\\cdots+a_n^*b_n
Examples
--------
>>> a = np.array([1+2j,3+4j])
Expand All @@ -1336,12 +1326,17 @@
(70-8j)
>>> np.vdot(b, a)
(70+8j)
Note that higher-dimensional arrays are flattened!
>>> a = np.array([[1, 4], [5, 6]])
>>> b = np.array([[4, 1], [2, 2]])
>>> np.vdot(a, b)
30
>>> np.vdot(b, a)
30
>>> 1*4 + 4*1 + 5*2 + 6*2
30
""")

Expand Down
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 @@ -1123,6 +1123,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 @@ -387,14 +387,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 427d3fc

Please sign in to comment.