summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arraysetops.py9
-rw-r--r--getlimits.py4
-rw-r--r--index_tricks.py34
-rw-r--r--scimath.py366
-rw-r--r--tests/test_arraysetops.py4
-rw-r--r--tests/test_getlimits.py10
-rw-r--r--tests/test_polynomial.py8
7 files changed, 397 insertions, 38 deletions
diff --git a/arraysetops.py b/arraysetops.py
index 6693fa81c..1d99f7a97 100644
--- a/arraysetops.py
+++ b/arraysetops.py
@@ -201,9 +201,13 @@ def setmember1d( ar1, ar2 ):
numpy.lib.arraysetops has a number of other functions for performing set
operations on arrays.
"""
- zlike = nm.zeros_like
+ ar1 = nm.asarray( ar1 )
+ ar2 = nm.asarray( ar2 )
ar = nm.concatenate( (ar1, ar2 ) )
- tt = nm.concatenate( (zlike( ar1 ), zlike( ar2 ) + 1) )
+ b1 = nm.zeros( ar1.shape, dtype = nm.int8 )
+ b2 = nm.ones( ar2.shape, dtype = nm.int8 )
+ tt = nm.concatenate( (b1, b2) )
+
# We need this to be a stable sort, so always use 'mergesort' here. The
# values from the first array should always come before the values from the
# second array.
@@ -212,7 +216,6 @@ def setmember1d( ar1, ar2 ):
aux2 = tt[perm]
# flag = ediff1d( aux, 1 ) == 0
flag = nm.concatenate( (aux[1:] == aux[:-1], [False] ) )
-
ii = nm.where( flag * aux2 )[0]
aux = perm[ii+1]
perm[ii+1] = perm[ii]
diff --git a/getlimits.py b/getlimits.py
index 00c3ea846..89b40203f 100644
--- a/getlimits.py
+++ b/getlimits.py
@@ -7,7 +7,7 @@ from machar import MachAr
import numpy.core.numeric as numeric
import numpy.core.numerictypes as ntypes
from numpy.core.numeric import array
-import numpy as N
+import numpy as np
def _frz(a):
"""fix rank-0 --> rank-1"""
@@ -128,7 +128,7 @@ class iinfo:
_max_vals = {}
def __init__(self, type):
- self.dtype = N.dtype(type)
+ self.dtype = np.dtype(type)
self.kind = self.dtype.kind
self.bits = self.dtype.itemsize * 8
self.key = "%s%d" % (self.kind, self.bits)
diff --git a/index_tricks.py b/index_tricks.py
index 26a44976c..c45148057 100644
--- a/index_tricks.py
+++ b/index_tricks.py
@@ -1,5 +1,3 @@
-## Automatically adapted for numpy Sep 19, 2005 by convertcode.py
-
__all__ = ['unravel_index',
'mgrid',
'ogrid',
@@ -48,7 +46,7 @@ def unravel_index(x,dims):
# Reverse
# [dcb,dc,d,1]
dim_prod = _nx.cumprod([1] + list(dims)[:0:-1])[::-1]
- # Indeces become [x/dcb % a, x/dc % b, x/d % c, x/1 % d]
+ # Indices become [x/dcb % a, x/dc % b, x/d % c, x/1 % d]
return tuple(x/dim_prod % dims)
def ix_(*args):
@@ -193,7 +191,7 @@ class nd_grid(object):
mgrid = nd_grid(sparse=False)
ogrid = nd_grid(sparse=True)
-class concatenator(object):
+class AxisConcatenator(object):
"""Translates slice objects to concatenation along an axis.
"""
def _retval(self, res):
@@ -313,26 +311,30 @@ class concatenator(object):
# etc. because otherwise we couldn't get the doc string to come out right
# in help(r_)
-class r_class(concatenator):
+class RClass(AxisConcatenator):
"""Translates slice objects to concatenation along the first axis.
- For example:
- >>> r_[array([1,2,3]), 0, 0, array([4,5,6])]
- array([1, 2, 3, 0, 0, 4, 5, 6])
+ For example:
+ >>> r_[array([1,2,3]), 0, 0, array([4,5,6])]
+ array([1, 2, 3, 0, 0, 4, 5, 6])
"""
def __init__(self):
- concatenator.__init__(self, 0)
+ AxisConcatenator.__init__(self, 0)
-r_ = r_class()
+r_ = RClass()
-class c_class(concatenator):
+class CClass(AxisConcatenator):
"""Translates slice objects to concatenation along the second axis.
+
+ For example:
+ >>> c_[array([[1,2,3]]), 0, 0, array([[4,5,6]])]
+ array([1, 2, 3, 0, 0, 4, 5, 6])
"""
def __init__(self):
- concatenator.__init__(self, -1, ndmin=2, trans1d=0)
+ AxisConcatenator.__init__(self, -1, ndmin=2, trans1d=0)
-c_ = c_class()
+c_ = CClass()
class ndenumerate(object):
"""
@@ -423,7 +425,7 @@ class ndindex(object):
#
#
-class _index_expression_class(object):
+class IndexExpression(object):
"""
A nicer way to build up index tuples for arrays.
@@ -451,7 +453,7 @@ class _index_expression_class(object):
stop = None
return self[start:stop:None]
-index_exp = _index_expression_class(1)
-s_ = _index_expression_class(0)
+index_exp = IndexExpression(maketuple=True)
+s_ = IndexExpression(maketuple=False)
# End contribution from Konrad.
diff --git a/scimath.py b/scimath.py
index c15f254a3..429eac9c8 100644
--- a/scimath.py
+++ b/scimath.py
@@ -2,6 +2,17 @@
Wrapper functions to more user-friendly calling of certain math functions
whose output data-type is different than the input data-type in certain
domains of the input.
+
+For example, for functions like log() with branch cuts, the versions in this
+module provide the mathematically valid answers in the complex plane:
+
+>>> import math
+>>> from numpy.lib import scimath
+>>> scimath.log(-math.exp(1)) == (1+1j*math.pi)
+True
+
+Similarly, sqrt(), other base logarithms, power() and trig functions are
+correctly handled. See their respective docstrings for specific examples.
"""
__all__ = ['sqrt', 'log', 'log2', 'logn','log10', 'power', 'arccos',
@@ -12,51 +23,266 @@ import numpy.core.numerictypes as nt
from numpy.core.numeric import asarray, any
from numpy.lib.type_check import isreal
-
-#__all__.extend([key for key in dir(nx.umath)
-# if key[0] != '_' and key not in __all__])
-
_ln2 = nx.log(2.0)
def _tocomplex(arr):
- if isinstance(arr.dtype, (nt.single, nt.byte, nt.short, nt.ubyte,
- nt.ushort)):
+ """Convert its input `arr` to a complex array.
+
+ The input is returned as a complex array of the smallest type that will fit
+ the original data: types like single, byte, short, etc. become csingle,
+ while others become cdouble.
+
+ A copy of the input is always made.
+
+ Parameters
+ ----------
+ arr : array
+
+ Returns
+ -------
+ array
+ An array with the same input data as the input but in complex form.
+
+ Examples
+ --------
+
+ >>> import numpy as np
+
+ First, consider an input of type short:
+
+ >>> a = np.array([1,2,3],np.short)
+
+ >>> ac = _tocomplex(a); ac
+ array([ 1.+0.j, 2.+0.j, 3.+0.j], dtype=complex64)
+
+ >>> ac.dtype
+ dtype('complex64')
+
+ If the input is of type double, the output is correspondingly of the
+ complex double type as well:
+
+ >>> b = np.array([1,2,3],np.double)
+
+ >>> bc = _tocomplex(b); bc
+ array([ 1.+0.j, 2.+0.j, 3.+0.j])
+
+ >>> bc.dtype
+ dtype('complex128')
+
+ Note that even if the input was complex to begin with, a copy is still
+ made, since the astype() method always copies:
+
+ >>> c = np.array([1,2,3],np.csingle)
+
+ >>> cc = _tocomplex(c); cc
+ array([ 1.+0.j, 2.+0.j, 3.+0.j], dtype=complex64)
+
+ >>> c *= 2; c
+ array([ 2.+0.j, 4.+0.j, 6.+0.j], dtype=complex64)
+
+ >>> cc
+ array([ 1.+0.j, 2.+0.j, 3.+0.j], dtype=complex64)
+ """
+ if issubclass(arr.dtype.type, (nt.single, nt.byte, nt.short, nt.ubyte,
+ nt.ushort,nt.csingle)):
return arr.astype(nt.csingle)
else:
return arr.astype(nt.cdouble)
def _fix_real_lt_zero(x):
+ """Convert `x` to complex if it has real, negative components.
+
+ Otherwise, output is just the array version of the input (via asarray).
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array
+
+ Examples
+ --------
+ >>> _fix_real_lt_zero([1,2])
+ array([1, 2])
+
+ >>> _fix_real_lt_zero([-1,2])
+ array([-1.+0.j, 2.+0.j])
+ """
x = asarray(x)
if any(isreal(x) & (x<0)):
x = _tocomplex(x)
return x
def _fix_int_lt_zero(x):
+ """Convert `x` to double if it has real, negative components.
+
+ Otherwise, output is just the array version of the input (via asarray).
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array
+
+ Examples
+ --------
+ >>> _fix_int_lt_zero([1,2])
+ array([1, 2])
+
+ >>> _fix_int_lt_zero([-1,2])
+ array([-1., 2.])
+ """
x = asarray(x)
if any(isreal(x) & (x < 0)):
x = x * 1.0
return x
def _fix_real_abs_gt_1(x):
+ """Convert `x` to complex if it has real components x_i with abs(x_i)>1.
+
+ Otherwise, output is just the array version of the input (via asarray).
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array
+
+ Examples
+ --------
+ >>> _fix_real_abs_gt_1([0,1])
+ array([0, 1])
+
+ >>> _fix_real_abs_gt_1([0,2])
+ array([ 0.+0.j, 2.+0.j])
+ """
x = asarray(x)
if any(isreal(x) & (abs(x)>1)):
x = _tocomplex(x)
return x
def sqrt(x):
+ """Return the square root of x.
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array_like output.
+
+ Examples
+ --------
+
+ For real, non-negative inputs this works just like numpy.sqrt():
+ >>> sqrt(1)
+ 1.0
+
+ >>> sqrt([1,4])
+ array([ 1., 2.])
+
+ But it automatically handles negative inputs:
+ >>> sqrt(-1)
+ (0.0+1.0j)
+
+ >>> sqrt([-1,4])
+ array([ 0.+1.j, 2.+0.j])
+ """
x = _fix_real_lt_zero(x)
return nx.sqrt(x)
def log(x):
+ """Return the natural logarithm of x.
+
+ If x contains negative inputs, the answer is computed and returned in the
+ complex domain.
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array_like
+
+ Examples
+ --------
+ >>> import math
+
+ >>> log(math.exp(1))
+ 1.0
+
+ Negative arguments are correctly handled (recall that for negative
+ arguments, the identity exp(log(z))==z does not hold anymore):
+
+ >>> log(-math.exp(1)) == (1+1j*math.pi)
+ True
+ """
x = _fix_real_lt_zero(x)
return nx.log(x)
def log10(x):
+ """Return the base 10 logarithm of x.
+
+ If x contains negative inputs, the answer is computed and returned in the
+ complex domain.
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array_like
+
+ Examples
+ --------
+
+ (We set the printing precision so the example can be auto-tested)
+ >>> import numpy as np; np.set_printoptions(precision=4)
+
+ >>> log10([10**1,10**2])
+ array([ 1., 2.])
+
+
+ >>> log10([-10**1,-10**2,10**2])
+ array([ 1.+1.3644j, 2.+1.3644j, 2.+0.j ])
+ """
x = _fix_real_lt_zero(x)
return nx.log10(x)
def logn(n, x):
- """ Take log base n of x.
+ """Take log base n of x.
+
+ If x contains negative inputs, the answer is computed and returned in the
+ complex domain.
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array_like
+
+ Examples
+ --------
+
+ (We set the printing precision so the example can be auto-tested)
+ >>> import numpy as np; np.set_printoptions(precision=4)
+
+ >>> logn(2,[4,8])
+ array([ 2., 3.])
+
+ >>> logn(2,[-4,-8,8])
+ array([ 2.+4.5324j, 3.+4.5324j, 3.+0.j ])
"""
x = _fix_real_lt_zero(x)
n = _fix_real_lt_zero(n)
@@ -64,23 +290,149 @@ def logn(n, x):
def log2(x):
""" Take log base 2 of x.
+
+ If x contains negative inputs, the answer is computed and returned in the
+ complex domain.
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array_like
+
+ Examples
+ --------
+
+ (We set the printing precision so the example can be auto-tested)
+ >>> import numpy as np; np.set_printoptions(precision=4)
+
+ >>> log2([4,8])
+ array([ 2., 3.])
+
+ >>> log2([-4,-8,8])
+ array([ 2.+4.5324j, 3.+4.5324j, 3.+0.j ])
"""
x = _fix_real_lt_zero(x)
return nx.log(x)/_ln2
def power(x, p):
+ """Return x**p.
+
+ If x contains negative values, it is converted to the complex domain.
+
+ If p contains negative values, it is converted to floating point.
+
+ Parameters
+ ----------
+ x : array_like
+ p : array_like of integers
+
+ Returns
+ -------
+ array_like
+
+ Examples
+ --------
+ (We set the printing precision so the example can be auto-tested)
+ >>> import numpy as np; np.set_printoptions(precision=4)
+
+ >>> power([2,4],2)
+ array([ 4, 16])
+
+ >>> power([2,4],-2)
+ array([ 0.25 , 0.0625])
+
+ >>> power([-2,4],2)
+ array([ 4.+0.j, 16.+0.j])
+ """
x = _fix_real_lt_zero(x)
p = _fix_int_lt_zero(p)
return nx.power(x, p)
def arccos(x):
+ """Compute the inverse cosine of x.
+
+ For real x with abs(x)<=1, this returns the principal value.
+
+ If abs(x)>1, the complex arccos() is computed.
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array_like
+
+ Examples
+ --------
+ >>> import numpy as np; np.set_printoptions(precision=4)
+
+ >>> arccos(1)
+ 0.0
+
+ >>> arccos([1,2])
+ array([ 0.-0.j , 0.+1.317j])
+ """
x = _fix_real_abs_gt_1(x)
return nx.arccos(x)
def arcsin(x):
+ """Compute the inverse sine of x.
+
+ For real x with abs(x)<=1, this returns the principal value.
+
+ If abs(x)>1, the complex arcsin() is computed.
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array_like
+
+ Examples
+ --------
+ (We set the printing precision so the example can be auto-tested)
+ >>> import numpy as np; np.set_printoptions(precision=4)
+
+ >>> arcsin(0)
+ 0.0
+
+ >>> arcsin([0,1])
+ array([ 0. , 1.5708])
+ """
x = _fix_real_abs_gt_1(x)
return nx.arcsin(x)
def arctanh(x):
+ """Compute the inverse hyperbolic tangent of x.
+
+ For real x with abs(x)<=1, this returns the principal value.
+
+ If abs(x)>1, the complex arctanh() is computed.
+
+ Parameters
+ ----------
+ x : array_like
+
+ Returns
+ -------
+ array_like
+
+ Examples
+ --------
+ (We set the printing precision so the example can be auto-tested)
+ >>> import numpy as np; np.set_printoptions(precision=4)
+
+ >>> arctanh(0)
+ 0.0
+
+ >>> arctanh([0,2])
+ array([ 0.0000+0.j , 0.5493-1.5708j])
+ """
x = _fix_real_abs_gt_1(x)
return nx.arctanh(x)
diff --git a/tests/test_arraysetops.py b/tests/test_arraysetops.py
index e2e703b9a..5a5a8fbd8 100644
--- a/tests/test_arraysetops.py
+++ b/tests/test_arraysetops.py
@@ -145,6 +145,10 @@ class TestAso(NumpyTestCase):
assert_array_equal([], setdiff1d([],[]))
+ def check_setdiff1d_char_array(self):
+ a = numpy.array(['a','b','c'])
+ b = numpy.array(['a','b','s'])
+ assert_array_equal(setdiff1d(a,b),numpy.array(['c']))
##
# 03.11.2005, c
diff --git a/tests/test_getlimits.py b/tests/test_getlimits.py
index 3c53f3322..a85228689 100644
--- a/tests/test_getlimits.py
+++ b/tests/test_getlimits.py
@@ -2,12 +2,10 @@
"""
from numpy.testing import *
-set_package_path()
import numpy.lib;reload(numpy.lib)
from numpy.lib.getlimits import finfo, iinfo
from numpy import single,double,longdouble
-import numpy as N
-restore_path()
+import numpy as np
##################################################
@@ -39,15 +37,15 @@ class TestIinfo(NumpyTestCase):
def check_basic(self):
dts = zip(['i1', 'i2', 'i4', 'i8',
'u1', 'u2', 'u4', 'u8'],
- [N.int8, N.int16, N.int32, N.int64,
- N.uint8, N.uint16, N.uint32, N.uint64])
+ [np.int8, np.int16, np.int32, np.int64,
+ np.uint8, np.uint16, np.uint32, np.uint64])
for dt1, dt2 in dts:
assert_equal(iinfo(dt1).min, iinfo(dt2).min)
assert_equal(iinfo(dt1).max, iinfo(dt2).max)
self.assertRaises(ValueError, iinfo, 'f4')
def check_unsigned_max(self):
- types = N.sctypes['uint']
+ types = np.sctypes['uint']
for T in types:
assert_equal(iinfo(T).max, T(-1))
diff --git a/tests/test_polynomial.py b/tests/test_polynomial.py
index c9a230775..17d22e10e 100644
--- a/tests/test_polynomial.py
+++ b/tests/test_polynomial.py
@@ -74,22 +74,22 @@ poly1d([ 2.])
"""
from numpy.testing import *
-import numpy as N
+import numpy as np
class TestDocs(NumpyTestCase):
def check_doctests(self): return self.rundocs()
def check_roots(self):
- assert_array_equal(N.roots([1,0,0]), [0,0])
+ assert_array_equal(np.roots([1,0,0]), [0,0])
def check_str_leading_zeros(self):
- p = N.poly1d([4,3,2,1])
+ p = np.poly1d([4,3,2,1])
p[3] = 0
assert_equal(str(p),
" 2\n"
"3 x + 2 x + 1")
- p = N.poly1d([1,2])
+ p = np.poly1d([1,2])
p[0] = 0
p[1] = 0
assert_equal(str(p), " \n0")