summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorcookedm <cookedm@localhost>2006-03-07 22:02:23 +0000
committercookedm <cookedm@localhost>2006-03-07 22:02:23 +0000
commitc9d2cdc913171d079eabb6b71405d7101041356b (patch)
treea66f5fe7b0d197b434e83fe3e17dbd87076f3839 /numpy
parente3a1d502e5d08a755dd1d91eb74341c7617adbdd (diff)
parent5bb7342c6c2fa9757edc28df0dbbc8d433ac50d8 (diff)
downloadnumpy-c9d2cdc913171d079eabb6b71405d7101041356b.tar.gz
Merge trunk (r2142:2204) to power_optimization branch
Diffstat (limited to 'numpy')
-rw-r--r--numpy/__init__.py16
-rw-r--r--numpy/_import_tools.py14
-rw-r--r--numpy/core/__init__.py5
-rw-r--r--numpy/core/arrayprint.py14
-rw-r--r--numpy/core/blasdot/_dotblas.c15
-rw-r--r--numpy/core/code_generators/generate_umath.py6
-rw-r--r--numpy/core/code_generators/multiarray_api_order.txt1
-rw-r--r--numpy/core/defmatrix.py23
-rw-r--r--numpy/core/include/numpy/arrayobject.h34
-rw-r--r--numpy/core/include/numpy/ufuncobject.h2
-rw-r--r--numpy/core/ma.py137
-rw-r--r--numpy/core/memmap.py2
-rw-r--r--numpy/core/numeric.py29
-rw-r--r--numpy/core/numerictypes.py9
-rw-r--r--numpy/core/records.py4
-rw-r--r--numpy/core/setup.py2
-rw-r--r--numpy/core/src/arraymethods.c142
-rw-r--r--numpy/core/src/arrayobject.c365
-rw-r--r--numpy/core/src/arraytypes.inc.src41
-rw-r--r--numpy/core/src/multiarraymodule.c138
-rw-r--r--numpy/core/src/scalartypes.inc.src30
-rw-r--r--numpy/core/src/ufuncobject.c34
-rw-r--r--numpy/core/src/umathmodule.c.src43
-rw-r--r--numpy/core/tests/test_ma.py15
-rw-r--r--numpy/core/tests/test_multiarray.py62
-rw-r--r--numpy/core/tests/test_umath.py2
-rw-r--r--numpy/dft/__init__.py6
-rw-r--r--numpy/distutils/__init__.py5
-rw-r--r--numpy/distutils/ccompiler.py8
-rw-r--r--numpy/distutils/misc_util.py2
-rwxr-xr-xnumpy/f2py/f2py2e.py2
-rw-r--r--numpy/lib/UserArray.py217
-rw-r--r--numpy/lib/__init__.py5
-rw-r--r--numpy/lib/function_base.py3
-rw-r--r--numpy/lib/getlimits.py10
-rw-r--r--numpy/lib/index_tricks.py47
-rw-r--r--numpy/lib/polynomial.py6
-rw-r--r--numpy/lib/shape_base.py37
-rw-r--r--numpy/lib/twodim_base.py13
-rw-r--r--numpy/linalg/__init__.py5
-rw-r--r--numpy/linalg/linalg.py39
-rw-r--r--numpy/random/__init__.py5
-rw-r--r--numpy/testing/info.py2
-rw-r--r--numpy/testing/numpytest.py111
-rw-r--r--numpy/testing/utils.py17
45 files changed, 1203 insertions, 522 deletions
diff --git a/numpy/__init__.py b/numpy/__init__.py
index a945c75a5..17202cd95 100644
--- a/numpy/__init__.py
+++ b/numpy/__init__.py
@@ -31,20 +31,26 @@ else:
del _os
from _import_tools import PackageLoader
pkgload = PackageLoader()
- pkgload('testing','core','linalg','lib','dft','random','f2py','distutils',
+ pkgload('testing','core','lib','linalg','dft','random','f2py',
+ 'distutils',
verbose=NUMPY_IMPORT_VERBOSE,postpone=False)
- __doc__ += """
+ if __doc__ is not None:
+ __doc__ += """
Available subpackages
---------------------
"""
- __doc__ += pkgload.get_pkgdocs()
+ if __doc__ is not None:
+ __doc__ += pkgload.get_pkgdocs()
+
+ def test(level=1, verbosity=1):
+ return NumpyTest().test(level, verbosity)
- test = ScipyTest('numpy').test
import add_newdocs
- __doc__ += """
+ if __doc__ is not None:
+ __doc__ += """
Utility tools
-------------
diff --git a/numpy/_import_tools.py b/numpy/_import_tools.py
index 5d4e66de1..4989ab340 100644
--- a/numpy/_import_tools.py
+++ b/numpy/_import_tools.py
@@ -327,3 +327,17 @@ class PackageLoader:
self._format_titles(symbols,'-->')
return retstr
+
+class PackageLoaderDebug(PackageLoader):
+ def _execcmd(self,cmdstr):
+ """ Execute command in parent_frame."""
+ frame = self.parent_frame
+ print 'Executing',`cmdstr`,'...',
+ sys.stdout.flush()
+ exec (cmdstr, frame.f_globals,frame.f_locals)
+ print 'ok'
+ sys.stdout.flush()
+ return
+
+if int(os.environ.get('NUMPY_IMPORT_DEBUG','0')):
+ PackageLoader = PackageLoaderDebug
diff --git a/numpy/core/__init__.py b/numpy/core/__init__.py
index af57f0f69..429e423c5 100644
--- a/numpy/core/__init__.py
+++ b/numpy/core/__init__.py
@@ -25,5 +25,6 @@ __all__ += defmatrix.__all__
__all__ += rec.__all__
__all__ += char.__all__
-from numpy.testing import ScipyTest
-test = ScipyTest().test
+def test(level=1, verbosity=1):
+ from numpy.testing import NumpyTest
+ return NumpyTest().test(level, verbosity)
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
index 4e5db082a..a78601188 100644
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -79,7 +79,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
linewidth the number of characters per line for the purpose of inserting
line breaks.
(default 75)
- supress Boolean value indicating whether or not suppress printing
+ suppress Boolean value indicating whether or not suppress printing
of small floating point values using scientific notation
(default False)
"""
@@ -95,7 +95,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
if (precision is not None):
_float_output_precision = precision
if (suppress is not None):
- _float_output_supress_small = not not suppress
+ _float_output_suppress_small = not not suppress
return
def get_printoptions():
@@ -139,8 +139,6 @@ def _array2string(a, max_line_width, precision, suppress_small, separator=' ',
else:
summary_insert = ""
data = a.ravel()
-
- items_per_line = a.shape[-1]
try:
format_function = a._format
@@ -168,9 +166,9 @@ def _array2string(a, max_line_width, precision, suppress_small, separator=' ',
format = "%s"
format_function = lambda x, f = format: repr(x)
else:
- format = '%s'
- format_function = lambda x, f = format: format % str(x)
-
+ format = '%s'
+ format_function = lambda x, f = format: format % str(x)
+
next_line_prefix = " " # skip over "["
next_line_prefix += " "*len(prefix) # skip over array(
@@ -252,7 +250,7 @@ def _formatArray(a, format_function, rank, max_line_len,
s += _formatArray(a[i], format_function, rank-1, max_line_len,
" " + next_line_prefix, separator, edge_items,
summary_insert)
- s = s.rstrip()+ sep.rstrip() + '\n'*max(rank-1,1)
+ s = s.rstrip() + sep.rstrip() + '\n'*max(rank-1,1)
if summary_insert1:
s += next_line_prefix + summary_insert1 + "\n"
diff --git a/numpy/core/blasdot/_dotblas.c b/numpy/core/blasdot/_dotblas.c
index 6490e40e7..d1971fa0f 100644
--- a/numpy/core/blasdot/_dotblas.c
+++ b/numpy/core/blasdot/_dotblas.c
@@ -229,6 +229,10 @@ dotblas_matrixproduct(PyObject *dummy, PyObject *args)
ap1shape = ap2shape;
ap2shape = _scalar;
}
+
+ if (ap1shape == _row) ap1stride = ap1->strides[1];
+ else ap1stride = ap1->strides[0];
+
/* Fix it so that dot(shape=(N,1), shape=(1,))
and dot(shape=(1,), shape=(1,N)) both return
an (N,) array (but use the fast scalar code)
@@ -238,16 +242,13 @@ dotblas_matrixproduct(PyObject *dummy, PyObject *args)
nd = 1;
if (ap1shape == _column) {
dimensions[0] = ap1->dimensions[0];
- ap1stride = ap1->strides[0] / sizeof(double);
}
else {
dimensions[0] = ap1->dimensions[1];
- ap1stride = ap1->strides[1] / sizeof(double);
}
l = dimensions[0];
}
else {
- ap1stride = ap1->strides[0] / sizeof(double);
nd = ap1->nd;
for (l = 1, j = 0; j < nd; j++) {
dimensions[j] = ap1->dimensions[j];
@@ -310,7 +311,7 @@ dotblas_matrixproduct(PyObject *dummy, PyObject *args)
}
else if (ap1shape != _matrix) {
cblas_daxpy(l, *((double *)ap2->data), (double *)ap1->data,
- ap1stride, (double *)ret->data, 1);
+ ap1stride/sizeof(double), (double *)ret->data, 1);
}
else {
int maxind, oind, i, a1s, rets;
@@ -343,7 +344,7 @@ dotblas_matrixproduct(PyObject *dummy, PyObject *args)
}
else if (ap1shape != _matrix) {
cblas_zaxpy(l, (double *)ap2->data, (double *)ap1->data,
- ap1stride, (double *)ret->data, 1);
+ ap1stride/sizeof(cdouble), (double *)ret->data, 1);
}
else {
int maxind, oind, i, a1s, rets;
@@ -372,7 +373,7 @@ dotblas_matrixproduct(PyObject *dummy, PyObject *args)
}
else if (ap1shape != _matrix) {
cblas_saxpy(l, *((float *)ap2->data), (float *)ap1->data,
- ap1stride, (float *)ret->data, 1);
+ ap1stride/sizeof(float), (float *)ret->data, 1);
}
else {
int maxind, oind, i, a1s, rets;
@@ -405,7 +406,7 @@ dotblas_matrixproduct(PyObject *dummy, PyObject *args)
}
else if (ap1shape != _matrix) {
cblas_caxpy(l, (float *)ap2->data, (float *)ap1->data,
- ap1stride, (float *)ret->data, 1);
+ ap1stride/sizeof(cfloat), (float *)ret->data, 1);
}
else {
int maxind, oind, i, a1s, rets;
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py
index ac26cc6cc..4edbb5363 100644
--- a/numpy/core/code_generators/generate_umath.py
+++ b/numpy/core/code_generators/generate_umath.py
@@ -432,6 +432,12 @@ defdict = {
TD(flts, f='floor'),
TD(M, f='floor'),
),
+'rint' :
+ Ufunc(1, 1, None,
+ 'round x elementwise to the nearest integer, round halfway cases away from zero',
+ TD(flts, f='rint'),
+ TD(M, f='rint'),
+ ),
'arctan2' :
Ufunc(2, 1, None,
'a safe and correct arctan(x1/x2)',
diff --git a/numpy/core/code_generators/multiarray_api_order.txt b/numpy/core/code_generators/multiarray_api_order.txt
index d328ad7fc..c558b636b 100644
--- a/numpy/core/code_generators/multiarray_api_order.txt
+++ b/numpy/core/code_generators/multiarray_api_order.txt
@@ -65,4 +65,5 @@ PyArray_ArangeObj
PyArray_SortkindConverter
PyArray_LexSort
PyArray_GetNDArrayCVersion
+PyArray_Round
diff --git a/numpy/core/defmatrix.py b/numpy/core/defmatrix.py
index 9234d2f53..d89260ef6 100644
--- a/numpy/core/defmatrix.py
+++ b/numpy/core/defmatrix.py
@@ -2,8 +2,7 @@
__all__ = ['matrix', 'bmat', 'mat', 'asmatrix']
import numeric as N
-from numeric import ArrayType, concatenate, integer, multiply, power, \
- isscalar, binary_repr
+from numeric import ArrayType, concatenate, isscalar, binary_repr
import types
import string as str_
import sys
@@ -101,6 +100,16 @@ class matrix(N.ndarray):
def __array_finalize__(self, obj):
ndim = self.ndim
+ if (ndim == 2):
+ return
+ if (ndim > 2):
+ newshape = tuple([x for x in self.shape if x > 1])
+ ndim = len(newshape)
+ if ndim == 2:
+ self.shape = newshape
+ return
+ elif (ndim > 2):
+ raise ValueError, "shape too large to be a matrix."
if ndim == 0:
self.shape = (1,1)
elif ndim == 1:
@@ -135,7 +144,11 @@ class matrix(N.ndarray):
return truend
def __mul__(self, other):
- return N.dot(self, other)
+ if isinstance(other, N.ndarray) or N.isscalar(other) or \
+ not hasattr(other, '__rmul__'):
+ return N.dot(self, other)
+ else:
+ return NotImplemented
def __rmul__(self, other):
return N.dot(other, self)
@@ -180,7 +193,7 @@ class matrix(N.ndarray):
raise TypeError, "exponent must be an integer"
def __rpow__(self, other):
- raise NotImplementedError
+ return NotImplemented
def __repr__(self):
return repr(self.__array__()).replace('array','matrix')
@@ -251,7 +264,7 @@ def _from_string(str,gdict,ldict):
return concatenate(rowtup,axis=0)
-def bmat(obj,ldict=None, gdict=None):
+def bmat(obj, ldict=None, gdict=None):
"""Build a matrix object from string, nested sequence, or array.
Ex: F = bmat('A, B; C, D')
diff --git a/numpy/core/include/numpy/arrayobject.h b/numpy/core/include/numpy/arrayobject.h
index 264e2649b..c380b3837 100644
--- a/numpy/core/include/numpy/arrayobject.h
+++ b/numpy/core/include/numpy/arrayobject.h
@@ -1,3 +1,4 @@
+
/* This expects the following variables to be defined (besides
the usual ones from pyconfig.h
@@ -77,8 +78,8 @@ extern "C" CONFUSE_EMACS
#define PY_FAIL 0
#define PY_SUCCEED 1
- /* Helpful to distinguish what is installed */
-#define NDARRAY_VERSION 0x00090500
+ /* Helpful to distinguish what is installed */
+#define NDARRAY_VERSION 0x00090504
/* Some platforms don't define bool, long long, or long double.
Handle that here.
@@ -224,6 +225,17 @@ typedef enum {
} PyArray_SORTKIND;
#define PyArray_NSORTS PyArray_TIMSORT + 1
+
+typedef enum {
+ PyArray_NOSCALAR=0,
+ PyArray_BOOL_SCALAR=1,
+ PyArray_INTPOS_SCALAR=2,
+ PyArray_INTNEG_SCALAR=3,
+ PyArray_FLOAT_SCALAR=4,
+ PyArray_COMPLEX_SCALAR=5,
+ PyArray_OBJECT_SCALAR=6,
+} PyArray_SCALARKIND;
+
/* Define bit-width array types and typedefs */
#define MAX_INT8 127
@@ -799,6 +811,8 @@ typedef int (PyArray_FillFunc)(void *, intp, void *);
typedef int (PyArray_SortFunc)(void *, intp, void *);
typedef int (PyArray_ArgSortFunc)(void *, intp *, intp, void *);
+typedef int (PyArray_FillWithScalarFunc)(void *, intp, void *, void *);
+
typedef struct {
intp *ptr;
int len;
@@ -841,6 +855,9 @@ typedef struct {
/* Used for arange */
PyArray_FillFunc *fill;
+ /* Function to fill arrays with scalar values */
+ PyArray_FillWithScalarFunc *fillwithscalar;
+
/* Sorting functions */
PyArray_SortFunc *sort[PyArray_NSORTS];
PyArray_ArgSortFunc *argsort[PyArray_NSORTS];
@@ -905,6 +922,7 @@ typedef struct PyArrayObject {
PyObject *weakreflist; /* For weakreferences */
} PyArrayObject;
+
#define fortran fortran_ /* For some compilers */
/* Mirrors buffer object to ptr */
@@ -1018,13 +1036,6 @@ typedef struct {
#endif
-#define UFUNC_NOSCALAR 0
-#define UFUNC_BOOL_SCALAR 1
-#define UFUNC_INTPOS_SCALAR 2
-#define UFUNC_INTNEG_SCALAR 3
-#define UFUNC_FLOAT_SCALAR 4
-#define UFUNC_COMPLEX_SCALAR 5
-#define UFUNC_OBJECT_SCALAR 6
typedef struct {
@@ -1397,9 +1408,8 @@ typedef struct {
#define PyArray_DescrCheck(op) ((op)->ob_type == &PyArrayDescr_Type)
-#define PyArray_Check(op) ((op)->ob_type == &PyArray_Type || \
- PyObject_TypeCheck((op), &PyBigArray_Type))
-#define PyBigArray_CheckExact(op) ((op)->ob_type == &PyBigArray_Type)
+#define PyArray_Check(op) ((op)->ob_type == &PyArray_Type || \
+ PyObject_TypeCheck((op), &PyArray_Type))
#define PyArray_CheckExact(op) ((op)->ob_type == &PyArray_Type)
#define PyArray_IsZeroDim(op) (PyArray_Check(op) && (PyArray_NDIM(op) == 0))
diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h
index eb195a4ab..84b8661c5 100644
--- a/numpy/core/include/numpy/ufuncobject.h
+++ b/numpy/core/include/numpy/ufuncobject.h
@@ -301,7 +301,7 @@ typedef struct {
}
#define generate_divbyzero_error() fp_raise_xcp(FP_DIV_BY_ZERO)
-#define generate_overflow_error() fp_raise_xcp(FE_OVERFLOW)
+#define generate_overflow_error() fp_raise_xcp(FP_OVERFLOW)
#else
diff --git a/numpy/core/ma.py b/numpy/core/ma.py
index ae10ca681..36cf32c90 100644
--- a/numpy/core/ma.py
+++ b/numpy/core/ma.py
@@ -7,11 +7,11 @@ Released for unlimited redistribution.
Adapted for numpy_core 2005 by Travis Oliphant and
(mainly) Paul Dubois.
"""
-import string, types, sys
+import types, sys
import umath
import oldnumeric
-from numeric import e, pi, newaxis, ndarray, inf
+from numeric import newaxis, ndarray, inf
from oldnumeric import typecodes, amax, amin
from numerictypes import *
import numeric
@@ -21,7 +21,7 @@ ufunc_domain = {}
# Ufunc fills lookup for __array__
ufunc_fills = {}
-MaskType=bool_
+MaskType = bool_
nomask = MaskType(0)
divide_tolerance = 1.e-35
@@ -77,11 +77,11 @@ def default_fill_value (obj):
if isinstance(obj, types.FloatType):
return default_real_fill_value
elif isinstance(obj, types.IntType) or isinstance(obj, types.LongType):
- return default_integer_fill_value
+ return default_integer_fill_value
elif isinstance(obj, types.StringType):
- return default_character_fill_value
+ return default_character_fill_value
elif isinstance(obj, types.ComplexType):
- return default_complex_fill_value
+ return default_complex_fill_value
elif isinstance(obj, MaskedArray) or isinstance(obj, ndarray):
x = obj.dtype.char
if x in typecodes['Float']:
@@ -120,7 +120,7 @@ def maximum_fill_value (obj):
if isinstance(obj, types.FloatType):
return -inf
elif isinstance(obj, types.IntType) or isinstance(obj, types.LongType):
- return -sys.maxint
+ return -sys.maxint
elif isinstance(obj, MaskedArray) or isinstance(obj, ndarray):
x = obj.dtype.char
if x in typecodes['Float']:
@@ -183,7 +183,7 @@ def make_mask (m, copy=0, flag=0):
else:
result = m.astype(MaskType)
else:
- result = filled(m,True).astype(MaskType)
+ result = filled(m, True).astype(MaskType)
if flag and not oldnumeric.sometrue(oldnumeric.ravel(result)):
return nomask
@@ -298,6 +298,7 @@ class masked_unary_operation:
self.fill = fill
self.domain = domain
self.__doc__ = getattr(aufunc, "__doc__", str(aufunc))
+ self.__name__ = getattr(aufunc, "__name__", str(aufunc))
ufunc_domain[aufunc] = domain
ufunc_fills[aufunc] = fill,
@@ -309,14 +310,6 @@ class masked_unary_operation:
if self.domain is not None:
m = mask_or(m, self.domain(d1))
result = self.f(d1, *args, **kwargs)
- if m is not nomask:
- try:
- shape = result.shape
- except AttributeError:
- pass
- else:
- if m.shape != shape:
- m = mask_or(getmaskarray(a), getmaskarray(b))
return masked_array(result, m)
def __str__ (self):
@@ -330,8 +323,8 @@ class domain_safe_divide:
return umath.absolute(a) * self.tolerance >= umath.absolute(b)
class domained_binary_operation:
- """Binary operations that have a domain, like divide. These are complicated so they
- are a separate class. They have no reduce, outer or accumulate.
+ """Binary operations that have a domain, like divide. These are complicated
+ so they are a separate class. They have no reduce, outer or accumulate.
"""
def __init__ (self, abfunc, domain, fillx=0, filly=0):
"""abfunc(fillx, filly) must be defined.
@@ -342,8 +335,9 @@ class domained_binary_operation:
self.fillx = fillx
self.filly = filly
self.__doc__ = getattr(abfunc, "__doc__", str(abfunc))
+ self.__name__ = getattr(abfunc, "__name__", str(abfunc))
ufunc_domain[abfunc] = domain
- ufunc_fills[abfunc] = fillx,filly
+ ufunc_fills[abfunc] = fillx, filly
def __call__(self, a, b):
"Execute the call behavior."
@@ -358,14 +352,6 @@ class domained_binary_operation:
mb = mask_or(mb, t)
m = mask_or(ma, mb)
result = self.f(d1, d2)
- if m is not nomask:
- try:
- shape = result.shape
- except AttributeError:
- pass
- else:
- if m.shape != shape:
- m = mask_or(getmaskarray(a), getmaskarray(b))
return masked_array(result, m)
def __str__ (self):
@@ -381,7 +367,7 @@ class masked_binary_operation:
self.filly = filly
self.__doc__ = getattr(abfunc, "__doc__", str(abfunc))
ufunc_domain[abfunc] = None
- ufunc_fills[abfunc] = fillx,filly
+ ufunc_fills[abfunc] = fillx, filly
def __call__ (self, a, b, *args, **kwargs):
"Execute the call behavior."
@@ -389,14 +375,6 @@ class masked_binary_operation:
d1 = filled(a, self.fillx)
d2 = filled(b, self.filly)
result = self.f(d1, d2, *args, **kwargs)
- if m is not nomask:
- try:
- shape = result.shape
- except AttributeError:
- pass
- else:
- if m.shape != shape:
- m = mask_or(getmaskarray(a), getmaskarray(b))
return masked_array(result, m)
def reduce (self, target, axis=0):
@@ -406,8 +384,8 @@ class masked_binary_operation:
if t.shape == ():
t = t.reshape(1)
if m is not nomask:
- m = make_mask(m, copy=1)
- m.shape = (1,)
+ m = make_mask(m, copy=1)
+ m.shape = (1,)
if m is nomask:
return masked_array (self.f.reduce (t, axis))
else:
@@ -462,7 +440,14 @@ tanh = masked_unary_operation(umath.tanh)
absolute = masked_unary_operation(umath.absolute)
fabs = masked_unary_operation(umath.fabs)
negative = masked_unary_operation(umath.negative)
-nonzero = masked_unary_operation(oldnumeric.nonzero)
+
+def nonzero(a):
+ """returns the indices of the elements of a which are not zero and not masked
+
+ a must be 1d
+ """
+ return asarray(filled(a, 0).nonzero())
+
around = masked_unary_operation(oldnumeric.round_)
floor = masked_unary_operation(umath.floor)
ceil = masked_unary_operation(umath.ceil)
@@ -751,11 +736,11 @@ array(data = %(data)s,
n = len(self.shape)
if self._mask is nomask:
- if n <=1:
+ if n <= 1:
return without_mask1 % {'data':str(self.filled())}
return without_mask % {'data':str(self.filled())}
else:
- if n <=1:
+ if n <= 1:
return with_mask % {
'data': str(self.filled()),
'mask': str(self._mask),
@@ -976,7 +961,7 @@ array(data = %(data)s,
"Return divide(other, self)"
return floor_divide(other, self)
- def __pow__(self,other, third=None):
+ def __pow__(self, other, third=None):
"Return power(self, other, third)"
return power(self, other, third)
@@ -987,7 +972,7 @@ array(data = %(data)s,
def __iadd__(self, other):
"Add other to self in place."
t = self._data.dtype.char
- f = filled(other,0)
+ f = filled(other, 0)
t1 = f.dtype.char
if t == t1:
pass
@@ -1030,7 +1015,7 @@ array(data = %(data)s,
def __imul__(self, other):
"Add other to self in place."
t = self._data.dtype.char
- f = filled(other,0)
+ f = filled(other, 0)
t1 = f.dtype.char
if t == t1:
pass
@@ -1073,7 +1058,7 @@ array(data = %(data)s,
def __isub__(self, other):
"Subtract other from self in place."
t = self._data.dtype.char
- f = filled(other,0)
+ f = filled(other, 0)
t1 = f.dtype.char
if t == t1:
pass
@@ -1118,7 +1103,7 @@ array(data = %(data)s,
def __idiv__(self, other):
"Divide self by other in place."
t = self._data.dtype.char
- f = filled(other,0)
+ f = filled(other, 0)
t1 = f.dtype.char
if t == t1:
pass
@@ -1154,22 +1139,22 @@ array(data = %(data)s,
self._shared_mask = 1
return self
- def __eq__(self,other):
+ def __eq__(self, other):
return equal(self,other)
- def __ne__(self,other):
+ def __ne__(self, other):
return not_equal(self,other)
- def __lt__(self,other):
+ def __lt__(self, other):
return less(self,other)
- def __le__(self,other):
+ def __le__(self, other):
return less_equal(self,other)
- def __gt__(self,other):
+ def __gt__(self, other):
return greater(self,other)
- def __ge__(self,other):
+ def __ge__(self, other):
return greater_equal(self,other)
def astype (self, tc):
@@ -1204,7 +1189,7 @@ array(data = %(data)s,
if ls == 1:
return s[0]
if axis is None:
- return reduce(lambda x,y:x*y, s)
+ return reduce(lambda x, y:x*y, s)
else:
n = s[axis]
t = list(s)
@@ -1214,9 +1199,9 @@ array(data = %(data)s,
w = oldnumeric.ravel(m).astype(int)
n1 = size(w)
if n1 == 1:
- n2 = w[0]
+ n2 = w[0]
else:
- n2 = umath.add.reduce(w)
+ n2 = umath.add.reduce(w)
return n1 - n2
else:
n1 = size(m, axis)
@@ -1350,6 +1335,10 @@ array(data = %(data)s,
v = default_fill_value (self.raw_data())
self._fill_value = v
+ def _get_ndim(self):
+ return self._data.ndim
+ ndim = property(_get_ndim, doc=numeric.ndarray.ndim.__doc__)
+
def _get_size (self):
return self._data.size
size = property(fget=_get_size, doc="Number of elements in the array.")
@@ -1500,7 +1489,7 @@ def left_shift (a, n):
d = umath.left_shift(filled(a), n)
return masked_array(d)
else:
- d = umath.left_shift(filled(a,0), n)
+ d = umath.left_shift(filled(a, 0), n)
return masked_array(d, m)
def right_shift (a, n):
@@ -1510,7 +1499,7 @@ def right_shift (a, n):
d = umath.right_shift(filled(a), n)
return masked_array(d)
else:
- d = umath.right_shift(filled(a,0), n)
+ d = umath.right_shift(filled(a, 0), n)
return masked_array(d, m)
def resize (a, new_shape):
@@ -1628,7 +1617,7 @@ def average (a, axis=0, weights=None, returned = 0):
else:
if weights is None:
n = add.reduce(a.ravel())
- w = oldnumeric.choose(mask, (1.0,0.0)).ravel()
+ w = oldnumeric.choose(mask, (1.0, 0.0)).ravel()
d = umath.add.reduce(w)
del w
else:
@@ -1654,7 +1643,7 @@ def average (a, axis=0, weights=None, returned = 0):
elif wsh == (ash[axis],):
ni = ash[axis]
r = [newaxis]*len(ash)
- r[axis] = slice(None,None,1)
+ r[axis] = slice(None, None, 1)
w = eval ("w["+ repr(tuple(r)) + "] * ones(ash, float)")
n = add.reduce(a*w, axis)
d = add.reduce(w, axis)
@@ -1679,7 +1668,7 @@ def average (a, axis=0, weights=None, returned = 0):
elif wsh == (ash[axis],):
ni = ash[axis]
r = [newaxis]*len(ash)
- r[axis] = slice(None,None,1)
+ r[axis] = slice(None, None, 1)
w = eval ("w["+ repr(tuple(r)) + "] * masked_array(ones(ash, float), mask)")
n = add.reduce(a*w, axis)
d = add.reduce(w, axis)
@@ -1711,7 +1700,7 @@ def where (condition, x, y):
The type depends on x and y. It is integer if both x and y are
the value masked.
"""
- fc = filled(not_equal(condition,0), 0)
+ fc = filled(not_equal(condition, 0), 0)
xv = filled(x)
xm = getmask(x)
yv = filled(y)
@@ -1732,7 +1721,7 @@ def choose (indices, t):
m = getmask(x)
if m is nomask: return 0
return m
- c = filled(indices,0)
+ c = filled(indices, 0)
masks = [nmask(x) for x in t]
a = [fmask(x) for x in t]
d = numeric.choose(c, a)
@@ -1766,7 +1755,7 @@ def masked_less_equal(x, value, copy=1):
def masked_not_equal(x, value, copy=1):
"masked_not_equal(x, value) = x masked where x != value"
- d = filled(x,0)
+ d = filled(x, 0)
c = umath.not_equal(d, value)
m = mask_or(c, getmask(x))
return array(d, mask=m, copy=copy)
@@ -1775,7 +1764,7 @@ def masked_equal(x, value, copy=1):
"""masked_equal(x, value) = x masked where x == value
For floating point consider masked_values(x, value) instead.
"""
- d = filled(x,0)
+ d = filled(x, 0)
c = umath.equal(d, value)
m = mask_or(c, getmask(x))
return array(d, mask=m, copy=copy)
@@ -1788,7 +1777,7 @@ def masked_inside(x, v1, v2, copy=1):
t = v2
v2 = v1
v1 = t
- d=filled(x, 0)
+ d = filled(x, 0)
c = umath.logical_and(umath.less_equal(d, v2), umath.greater_equal(d, v1))
m = mask_or(c, getmask(x))
return array(d, mask = m, copy=copy)
@@ -1801,7 +1790,7 @@ def masked_outside(x, v1, v2, copy=1):
t = v2
v2 = v1
v1 = t
- d = filled(x,0)
+ d = filled(x, 0)
c = umath.logical_or(umath.less(d, v1), umath.greater(d, v2))
m = mask_or(c, getmask(x))
return array(d, mask = m, copy=copy)
@@ -1886,7 +1875,7 @@ def putmask(a, mask, values):
a.unshare_mask()
numeric.putmask(a.raw_mask(), mask, 0)
-def innerproduct(a,b):
+def innerproduct(a, b):
"""innerproduct(a,b) returns the dot product of two arrays, which has
shape a.shape[:-1] + b.shape[:-1] with elements computed by summing the
product of the elements from the last dimensions of a and b.
@@ -1900,8 +1889,8 @@ def innerproduct(a,b):
def outerproduct(a, b):
"""outerproduct(a,b) = {a[i]*b[j]}, has shape (len(a),len(b))"""
- fa = filled(a,0).ravel()
- fb = filled(b,0).ravel()
+ fa = filled(a, 0).ravel()
+ fb = filled(b, 0).ravel()
d = numeric.outerproduct(fa, fb)
ma = getmask(a)
mb = getmask(b)
@@ -1909,7 +1898,7 @@ def outerproduct(a, b):
return masked_array(d)
ma = getmaskarray(a)
mb = getmaskarray(b)
- m = make_mask(1-numeric.outerproduct(1-ma,1-mb), copy=0)
+ m = make_mask(1-numeric.outerproduct(1-ma, 1-mb), copy=0)
return masked_array(d, m)
def dot(a, b):
@@ -1917,7 +1906,7 @@ def dot(a, b):
is over the last dimension of a and the second-to-last dimension of b.
Masked values are replaced by zeros. See also innerproduct.
"""
- return innerproduct(filled(a,0), numeric.swapaxes(filled(b,0), -1, -2))
+ return innerproduct(filled(a, 0), numeric.swapaxes(filled(b, 0), -1, -2))
def compress(condition, x, dimension=-1):
"""Select those parts of x for which condition is true.
@@ -1926,7 +1915,7 @@ def compress(condition, x, dimension=-1):
c = filled(condition, 0)
m = getmask(x)
if m is not nomask:
- m=numeric.compress(c, m, dimension)
+ m = numeric.compress(c, m, dimension)
d = numeric.compress(c, filled(x), dimension)
return masked_array(d, m)
@@ -2093,7 +2082,7 @@ def argmax (x, axis = -1, fill_value=None):
def fromfunction (f, s):
"""apply f to s to create array as in umath."""
- return masked_array(numeric.fromfunction(f,s))
+ return masked_array(numeric.fromfunction(f, s))
def asarray(data, dtype=None):
"""asarray(data, dtype) = array(data, dtype, copy=0)
@@ -2158,7 +2147,6 @@ array.min = _m(_min)
del _min
array.mean = _m(average)
array.nbytes = property(_m(not_implemented))
-array.ndim = _m(not_implemented)
array.newbyteorder = _m(not_implemented)
array.nonzero = _m(nonzero)
array.prod = _m(product)
@@ -2180,6 +2168,7 @@ array.trace = _m(not_implemented)
array.transpose = _m(transpose)
array.var = _m(not_implemented)
array.view = _m(not_implemented)
+array.round = _m(around)
del _m, MethodType, not_implemented
diff --git a/numpy/core/memmap.py b/numpy/core/memmap.py
index f4dc0b463..8e9faa5b0 100644
--- a/numpy/core/memmap.py
+++ b/numpy/core/memmap.py
@@ -80,7 +80,7 @@ class memmap(ndarray):
return self
def __array_finalize__(self, obj):
- if not isinstance(obj, memmap):
+ if obj is not None and not isinstance(obj, memmap):
raise ValueError, "Cannot create a memmap array that way"
self._mmap = None
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index cc1b0b1de..4ba599081 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -1,4 +1,4 @@
-__all__ = ['newaxis', 'ndarray', 'bigndarray', 'flatiter', 'ufunc',
+__all__ = ['newaxis', 'ndarray', 'flatiter', 'ufunc',
'arange', 'array', 'zeros', 'empty', 'broadcast', 'dtype',
'fromstring', 'fromfile', 'frombuffer','newbuffer',
'getbuffer',
@@ -43,10 +43,9 @@ extend_all(numerictypes)
newaxis = None
ndarray = multiarray.ndarray
-bigndarray = multiarray.bigndarray
flatiter = multiarray.flatiter
broadcast = multiarray.broadcast
-dtype=multiarray.dtype
+dtype = multiarray.dtype
ufunc = type(sin)
arange = multiarray.arange
@@ -176,7 +175,7 @@ def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None):
returned.
"""
if axis is not None:
- axisa,axisb,axisc=(axis,)*3
+ axisa,axisb,axisc=(axis,)*3
a = _move_axis_to_0(asarray(a), axisa)
b = _move_axis_to_0(asarray(b), axisb)
msg = "incompatible dimensions for cross product\n"\
@@ -236,15 +235,11 @@ def array_repr(arr, max_line_width=None, precision=None, suppress_small=None):
return cName + "(%s)" % lst
else:
typename=arr.dtype.type.__name__[:-6]
+ lf = ''
if issubclass(arr.dtype.type, flexible):
- if typename not in ['unicode','string','void']:
- typename = arr.dtype.type.__name__
- if typename == 'unicode':
- size = arr.itemsize >> 2
- else:
- size = arr.itemsize;
- typename = "(%s,%d)" % (typename, size)
- return cName + "(%s, dtype=%s)" % (lst, typename)
+ typename = str(arr.dtype)
+ lf = '\n'+' '*len("array(")
+ return cName + "(%s, %sdtype=%s)" % (lst, lf, typename)
def array_str(a, max_line_width=None, precision=None, suppress_small=None):
return array2string(a, max_line_width, precision, suppress_small, ' ', "", str)
@@ -344,11 +339,11 @@ def ones(shape, dtype=int_, fortran=False):
"""ones(shape, dtype=int_) returns an array of the given
dimensions which is initialized to all ones.
"""
- # This appears to be slower...
- #a = empty(shape, dtype, fortran)
- #a.fill(1)
- a = zeros(shape, dtype, fortran)
- a+=1
+ a = empty(shape, dtype, fortran)
+ a.fill(1)
+ # Above is faster now after addition of fast loops.
+ #a = zeros(shape, dtype, fortran)
+ #a+=1
return a
def identity(n,dtype=int_):
diff --git a/numpy/core/numerictypes.py b/numpy/core/numerictypes.py
index aeb2c5225..d7df600c4 100644
--- a/numpy/core/numerictypes.py
+++ b/numpy/core/numerictypes.py
@@ -1,5 +1,3 @@
-# Borrowed and adapted from numarray
-
"""numerictypes: Define the numeric type objects
This module is designed so 'from numerictypes import *' is safe.
@@ -78,7 +76,8 @@ $Id: numerictypes.py,v 1.17 2005/09/09 22:20:06 teoliphant Exp $
"""
# we add more at the bottom
-__all__ = ['typeDict', 'typeNA', 'sctypes', 'ScalarType', 'obj2sctype', 'cast', 'nbytes', 'sctype2char','maximum_sctype', 'issctype']
+__all__ = ['typeDict', 'typeNA', 'sctypes', 'ScalarType', 'obj2sctype', 'cast', 'nbytes',
+ 'sctype2char', 'maximum_sctype', 'issctype']
from multiarray import typeinfo, ndarray, array, empty
import types as _types
@@ -233,7 +232,7 @@ def _construct_char_code_lookup():
for name in typeinfo.keys():
tup = typeinfo[name]
if isinstance(tup, tuple):
- if tup[0] not in ['p','P']:
+ if tup[0] not in ['p','P']:
_sctype2char_dict[tup[-1]] = tup[0]
_construct_char_code_lookup()
@@ -368,7 +367,7 @@ for key in _sctype2char_dict.keys():
cast[key] = lambda x, k=key : array(x, copy=False).astype(k)
-_unicodesize = array('u','U').itemsize
+_unicodesize = array('u','U1').itemsize
# Create the typestring lookup dictionary
_typestr = _typedict()
diff --git a/numpy/core/records.py b/numpy/core/records.py
index fa901482e..f389388d7 100644
--- a/numpy/core/records.py
+++ b/numpy/core/records.py
@@ -1,12 +1,10 @@
-__all__ = ['record', 'recarray','format_parser']
+__all__ = ['record', 'recarray', 'format_parser']
import numeric as sb
from defchararray import chararray
import numerictypes as nt
-import sys
import types
import stat, os
-import _internal
_byteorderconv = {'b':'>',
'l':'<',
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index dce7477d1..75e21551a 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -73,6 +73,8 @@ def configuration(parent_package='',top_path=None):
moredefs.append('HAVE_ISNAN')
if config_cmd.check_func('isinf', **kws_args):
moredefs.append('HAVE_ISINF')
+ if config_cmd.check_func('rint', **kws_args):
+ moredefs.append('HAVE_RINT')
if sys.version[:3] < '2.4':
kws_args['headers'].append('stdlib.h')
diff --git a/numpy/core/src/arraymethods.c b/numpy/core/src/arraymethods.c
index fe87009e0..c48904f25 100644
--- a/numpy/core/src/arraymethods.c
+++ b/numpy/core/src/arraymethods.c
@@ -21,7 +21,7 @@ array_take(PyArrayObject *self, PyObject *args, PyObject *kwds)
return _ARET(PyArray_Take(self, indices, dimension));
}
-static char doc_fill[] = "a.fill(value) places the scalar value at every"\
+static char doc_fill[] = "a.fill(value) places the scalar value at every "\
"position in the array.";
static PyObject *
@@ -166,9 +166,9 @@ array_view(PyArrayObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "|O", &otype)) return NULL;
if (otype) {
- if (PyType_Check(otype) && \
+ if (PyType_Check(otype) && \
PyType_IsSubtype((PyTypeObject *)otype,
- &PyBigArray_Type)) {
+ &PyArray_Type)) {
return PyArray_View(self, NULL,
(PyTypeObject *)otype);
}
@@ -183,12 +183,15 @@ array_view(PyArrayObject *self, PyObject *args)
static char doc_argmax[] = "a.argmax(axis=None)";
static PyObject *
-array_argmax(PyArrayObject *self, PyObject *args)
+array_argmax(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
int axis=MAX_DIMS;
+ static char *kwlist[] = {"axis", NULL};
- if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter,
- &axis)) return NULL;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+ PyArray_AxisConverter,
+ &axis))
+ return NULL;
return _ARET(PyArray_ArgMax(self, axis));
}
@@ -196,12 +199,15 @@ array_argmax(PyArrayObject *self, PyObject *args)
static char doc_argmin[] = "a.argmin(axis=None)";
static PyObject *
-array_argmin(PyArrayObject *self, PyObject *args)
+array_argmin(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
int axis=MAX_DIMS;
+ static char *kwlist[] = {"axis", NULL};
- if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter,
- &axis)) return NULL;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+ PyArray_AxisConverter,
+ &axis))
+ return NULL;
return _ARET(PyArray_ArgMin(self, axis));
}
@@ -209,12 +215,15 @@ array_argmin(PyArrayObject *self, PyObject *args)
static char doc_max[] = "a.max(axis=None)";
static PyObject *
-array_max(PyArrayObject *self, PyObject *args)
+array_max(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
int axis=MAX_DIMS;
+ static char *kwlist[] = {"axis", NULL};
- if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter,
- &axis)) return NULL;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+ PyArray_AxisConverter,
+ &axis))
+ return NULL;
return PyArray_Max(self, axis);
}
@@ -222,13 +231,16 @@ array_max(PyArrayObject *self, PyObject *args)
static char doc_ptp[] = "a.ptp(axis=None) a.max(axis)-a.min(axis)";
static PyObject *
-array_ptp(PyArrayObject *self, PyObject *args)
+array_ptp(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
int axis=MAX_DIMS;
+ static char *kwlist[] = {"axis", NULL};
- if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter,
- &axis)) return NULL;
-
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+ PyArray_AxisConverter,
+ &axis))
+ return NULL;
+
return PyArray_Ptp(self, axis);
}
@@ -236,17 +248,19 @@ array_ptp(PyArrayObject *self, PyObject *args)
static char doc_min[] = "a.min(axis=None)";
static PyObject *
-array_min(PyArrayObject *self, PyObject *args)
+array_min(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
int axis=MAX_DIMS;
+ static char *kwlist[] = {"axis", NULL};
- if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter,
- &axis)) return NULL;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+ PyArray_AxisConverter,
+ &axis))
+ return NULL;
return PyArray_Min(self, axis);
}
-
static char doc_swapaxes[] = "a.swapaxes(axis1, axis2) returns new view with axes swapped.";
static PyObject *
@@ -590,13 +604,13 @@ array_getarray(PyArrayObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "|O&", PyArray_DescrConverter,
&newtype)) return NULL;
- /* convert to PyArray_Type or PyBigArray_Type */
- if (!PyArray_CheckExact(self) || !PyBigArray_CheckExact(self)) {
+ /* convert to PyArray_Type */
+ if (!PyArray_CheckExact(self)) {
PyObject *new;
PyTypeObject *subtype = &PyArray_Type;
if (!PyType_IsSubtype(self->ob_type, &PyArray_Type)) {
- subtype = &PyBigArray_Type;
+ subtype = &PyArray_Type;
}
Py_INCREF(PyArray_DESCR(self));
@@ -642,18 +656,29 @@ array_copy(PyArrayObject *self, PyObject *args)
return PyArray_NewCopy(self, fortran);
}
-static char doc_resize[] = "self.resize(new_shape). "\
+static char doc_resize[] = "self.resize(new_shape, refcheck=True). "\
"Change size and shape of self inplace.\n"\
"\n Array must own its own memory and not be referenced by other " \
"arrays\n Returns None.";
static PyObject *
-array_resize(PyArrayObject *self, PyObject *args)
+array_resize(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
PyArray_Dims newshape;
PyObject *ret;
int n;
-
+ int refcheck = 1;
+
+ if (kwds != NULL) {
+ PyObject *ref;
+ ref = PyDict_GetItemString(kwds, "refcheck");
+ if (ref) {
+ refcheck = PyInt_AsLong(ref);
+ if (refcheck==-1 && PyErr_Occurred()) {
+ return NULL;
+ }
+ }
+ }
n = PyTuple_Size(args);
if (n <= 1) {
if (!PyArg_ParseTuple(args, "O&", PyArray_IntpConverter,
@@ -668,7 +693,8 @@ array_resize(PyArrayObject *self, PyObject *args)
return NULL;
}
}
- ret = PyArray_Resize(self, &newshape);
+
+ ret = PyArray_Resize(self, &newshape, refcheck);
PyDimMem_FREE(newshape.ptr);
if (ret == NULL) return NULL;
Py_DECREF(ret);
@@ -741,7 +767,7 @@ array_sort(PyArrayObject *self, PyObject *args, PyObject *kwds)
static char doc_argsort[] = "a.argsort(axis=-1,kind='quicksort')\n"\
" Return the indexes into a that would sort it along the"\
- " given axis; kind can be 'quicksort', 'mergesort', or 'heapsort'";
+ " given axis; kind can be 'quicksort', 'mergesort', or 'heapsort'";
static PyObject *
array_argsort(PyArrayObject *self, PyObject *args, PyObject *kwds)
@@ -1013,7 +1039,8 @@ array_setstate(PyArrayObject *self, PyObject *args)
self->strides = self->dimensions + nd;
memcpy(self->dimensions, dimensions, sizeof(intp)*nd);
(void) _array_fill_strides(self->strides, dimensions, nd,
- self->descr->elsize, fortran,
+ self->descr->elsize,
+ (fortran ? FORTRAN : CONTIGUOUS),
&(self->flags));
}
@@ -1275,12 +1302,15 @@ array_cumprod(PyArrayObject *self, PyObject *args, PyObject *kwds)
static char doc_any[] = "a.any(axis=None)";
static PyObject *
-array_any(PyArrayObject *self, PyObject *args)
+array_any(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
int axis=MAX_DIMS;
+ static char *kwlist[] = {"axis", NULL};
- if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter,
- &axis)) return NULL;
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+ PyArray_AxisConverter,
+ &axis))
+ return NULL;
return PyArray_Any(self, axis);
}
@@ -1288,13 +1318,16 @@ array_any(PyArrayObject *self, PyObject *args)
static char doc_all[] = "a.all(axis=None)";
static PyObject *
-array_all(PyArrayObject *self, PyObject *args)
+array_all(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
int axis=MAX_DIMS;
+ static char *kwlist[] = {"axis", NULL};
- if (!PyArg_ParseTuple(args, "|O&", PyArray_AxisConverter,
- &axis)) return NULL;
-
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+ PyArray_AxisConverter,
+ &axis))
+ return NULL;
+
return PyArray_All(self, axis);
}
@@ -1348,7 +1381,7 @@ array_compress(PyArrayObject *self, PyObject *args, PyObject *kwds)
return _ARET(PyArray_Compress(self, condition, axis));
}
-static char doc_nonzero[] = "a.nonzero() return a tuple of indices referencing"\
+static char doc_nonzero[] = "a.nonzero() return a tuple of indices referencing "\
"the elements of a that are nonzero.";
static PyObject *
@@ -1360,7 +1393,7 @@ array_nonzero(PyArrayObject *self, PyObject *args)
}
-static char doc_trace[] = "a.trace(offset=0, axis1=0, axis2=1, dtype=None) \n"\
+static char doc_trace[] = "a.trace(offset=0, axis1=0, axis2=1, dtype=None)\n"\
"return the sum along the offset diagonal of the arrays indicated\n" \
"axis1 and axis2.";
@@ -1451,6 +1484,20 @@ array_ravel(PyArrayObject *self, PyObject *args)
return PyArray_Ravel(self, fortran);
}
+static char doc_round[] = "a.round(decimals=0)";
+
+static PyObject *
+array_round(PyArrayObject *self, PyObject *args, PyObject *kwds)
+{
+ int decimals = 0;
+ static char *kwlist[] = {"decimals", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwlist,
+ &decimals))
+ return NULL;
+
+ return _ARET(PyArray_Round(self, decimals));
+}
static char doc_setflags[] = "a.setflags(write=None, align=None, uic=None)";
@@ -1549,7 +1596,8 @@ static PyMethodDef array_methods[] = {
{"setfield", (PyCFunction)array_setfield,
METH_VARARGS | METH_KEYWORDS, doc_setfield},
{"copy", (PyCFunction)array_copy, 1, doc_copy},
- {"resize", (PyCFunction)array_resize, 1, doc_resize},
+ {"resize", (PyCFunction)array_resize,
+ METH_VARARGS | METH_KEYWORDS, doc_resize},
/* for subtypes */
{"__array__", (PyCFunction)array_getarray, 1, doc_array_getarray},
@@ -1590,9 +1638,9 @@ static PyMethodDef array_methods[] = {
{"searchsorted", (PyCFunction)array_searchsorted,
METH_VARARGS, doc_searchsorted},
{"argmax", (PyCFunction)array_argmax,
- METH_VARARGS, doc_argmax},
+ METH_VARARGS|METH_KEYWORDS, doc_argmax},
{"argmin", (PyCFunction)array_argmin,
- METH_VARARGS, doc_argmin},
+ METH_VARARGS|METH_KEYWORDS, doc_argmin},
{"reshape", (PyCFunction)array_reshape,
METH_VARARGS, doc_reshape},
{"squeeze", (PyCFunction)array_squeeze,
@@ -1602,11 +1650,11 @@ static PyMethodDef array_methods[] = {
{"swapaxes", (PyCFunction)array_swapaxes,
METH_VARARGS, doc_swapaxes},
{"max", (PyCFunction)array_max,
- METH_VARARGS, doc_max},
+ METH_VARARGS|METH_KEYWORDS, doc_max},
{"min", (PyCFunction)array_min,
- METH_VARARGS, doc_min},
+ METH_VARARGS|METH_KEYWORDS, doc_min},
{"ptp", (PyCFunction)array_ptp,
- METH_VARARGS, doc_ptp},
+ METH_VARARGS|METH_KEYWORDS, doc_ptp},
{"mean", (PyCFunction)array_mean,
METH_VARARGS|METH_KEYWORDS, doc_mean},
{"trace", (PyCFunction)array_trace,
@@ -1634,15 +1682,17 @@ static PyMethodDef array_methods[] = {
{"cumprod", (PyCFunction)array_cumprod,
METH_VARARGS|METH_KEYWORDS, doc_cumprod},
{"all", (PyCFunction)array_all,
- METH_VARARGS, doc_all},
+ METH_VARARGS|METH_KEYWORDS, doc_all},
{"any", (PyCFunction)array_any,
- METH_VARARGS, doc_any},
+ METH_VARARGS|METH_KEYWORDS, doc_any},
{"compress", (PyCFunction)array_compress,
METH_VARARGS|METH_KEYWORDS, doc_compress},
{"flatten", (PyCFunction)array_flatten,
METH_VARARGS, doc_flatten},
{"ravel", (PyCFunction)array_ravel,
METH_VARARGS, doc_ravel},
+ {"round", (PyCFunction)array_round,
+ METH_VARARGS|METH_KEYWORDS, doc_round},
{"setflags", (PyCFunction)array_setflags,
METH_VARARGS|METH_KEYWORDS, doc_setflags},
{"newbyteorder", (PyCFunction)array_newbyteorder,
diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c
index 2e2f6021b..8ef1758e1 100644
--- a/numpy/core/src/arrayobject.c
+++ b/numpy/core/src/arrayobject.c
@@ -32,8 +32,6 @@ PyArray_GetPriority(PyObject *obj, double default_)
if (PyArray_CheckExact(obj))
return priority;
- if (PyBigArray_CheckExact(obj))
- return PyArray_BIG_PRIORITY;
ret = PyObject_GetAttrString(obj, "__array_priority__");
if (ret != NULL) priority = PyFloat_AsDouble(ret);
@@ -1995,13 +1993,20 @@ array_subscript(PyArrayObject *self, PyObject *op)
return NULL;
}
if (self->nd == 0) {
- if (op == Py_Ellipsis)
- return PyArray_ToScalar(self->data, self);
+ if (op == Py_Ellipsis) {
+ /* XXX: This leads to a small inconsistency
+ XXX: with the nd>0 case where (x[...] is x)
+ XXX: is false for nd>0 case. */
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
if (op == Py_None)
return add_new_axes_0d(self, 1);
if (PyTuple_Check(op)) {
- if (0 == PyTuple_GET_SIZE(op))
- return PyArray_ToScalar(self->data, self);
+ if (0 == PyTuple_GET_SIZE(op)) {
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
if ((nd = count_new_axes_0d(op)) == -1)
return NULL;
return add_new_axes_0d(self, nd);
@@ -2211,7 +2216,43 @@ array_ass_sub(PyArrayObject *self, PyObject *index, PyObject *op)
static PyObject *
array_subscript_nice(PyArrayObject *self, PyObject *op)
{
- return PyArray_Return((PyArrayObject *)array_subscript(self, op));
+ /* The following is just a copy of PyArray_Return with an
+ additional logic in the nd == 0 case. More efficient
+ implementation may be possible by refactoring
+ array_subscript */
+
+ PyArrayObject *mp = (PyArrayObject *)array_subscript(self, op);
+
+ if (mp == NULL) return NULL;
+
+ if (PyErr_Occurred()) {
+ Py_XDECREF(mp);
+ return NULL;
+ }
+
+ if (!PyArray_Check(mp)) return (PyObject *)mp;
+
+ if (mp->nd == 0) {
+ Bool noellipses = TRUE;
+ if (op == Py_Ellipsis)
+ noellipses = FALSE;
+ else if (PySequence_Check(op)) {
+ int n, i;
+ n = PySequence_Size(op);
+ for (i = 0; i < n; ++i)
+ if (PySequence_GetItem(op, i) == Py_Ellipsis) {
+ noellipses = FALSE;
+ break;
+ }
+ }
+ if (noellipses) {
+ PyObject *ret;
+ ret = PyArray_ToScalar(mp->data, mp);
+ Py_DECREF(mp);
+ return ret;
+ }
+ }
+ return (PyObject *)mp;
}
@@ -2337,14 +2378,11 @@ typedef struct {
*floor,
*ceil,
*maximum,
- *minimum;
-
+ *minimum,
+ *rint;
} NumericOps;
-static NumericOps n_ops = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+static NumericOps n_ops; /* NB: static objects inlitialized to zero */
/* Dictionary can contain any of the numeric operations, by name.
Those not present will not be changed
@@ -2397,6 +2435,7 @@ PyArray_SetNumericOps(PyObject *dict)
SET(ceil);
SET(maximum);
SET(minimum);
+ SET(rint);
return 0;
}
@@ -2445,6 +2484,7 @@ PyArray_GetNumericOps(void)
GET(ceil);
GET(maximum);
GET(minimum);
+ GET(rint);
return dict;
fail:
@@ -3099,8 +3139,8 @@ array_slice(PyArrayObject *self, int ilow, int ihigh)
self->nd, self->dimensions,
self->strides, data,
self->flags, (PyObject *)self);
-
self->dimensions[0] = l;
+ if (r == NULL) return NULL;
r->base = (PyObject *)self;
Py_INCREF(self);
PyArray_UpdateFlags(r, UPDATE_ALL_FLAGS);
@@ -3314,6 +3354,7 @@ static PyObject *
array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
{
PyObject *array_other, *result;
+ int typenum;
switch (cmp_op)
{
@@ -3330,13 +3371,17 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
}
/* Try to convert other to an array */
if (!PyArray_Check(other)) {
+ typenum = self->descr->type_num;
+ if (typenum != PyArray_OBJECT) {
+ typenum = PyArray_NOTYPE;
+ }
array_other = PyArray_FromObject(other,
- self->descr->type_num, 0, 0);
- /* If not successful, then return the integer
- object 0. This fixes code that used to
+ typenum, 0, 0);
+ /* If not successful, then return False
+ This fixes code that used to
allow equality comparisons between arrays
and other objects which would give a result
- of 0
+ of False
*/
if ((array_other == NULL) || \
(array_other == Py_None)) {
@@ -3371,8 +3416,12 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
}
/* Try to convert other to an array */
if (!PyArray_Check(other)) {
+ typenum = self->descr->type_num;
+ if (typenum != PyArray_OBJECT) {
+ typenum = PyArray_NOTYPE;
+ }
array_other = PyArray_FromObject(other,
- self->descr->type_num, 0, 0);
+ typenum, 0, 0);
/* If not successful, then objects cannot be
compared and cannot be equal, therefore,
return True;
@@ -3649,49 +3698,40 @@ PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
}
/* This routine checks to see if newstrides (of length nd) will not
- walk outside of the memory implied by a single segment array of the provided
- dimensions and element size. If numbytes is 0 it will be calculated from
- the provided shape and element size.
-
- For axes with a positive stride this function checks for a walk
- beyond the right end of the buffer, for axes with a negative stride,
- it checks for a walk beyond the left end of the buffer. Zero strides
- are disallowed.
+ ever be able to walk outside of the memory implied numbytes and offset.
+
+ The available memory is assumed to start at -offset and proceed
+ to numbytes-offset. The strides are checked to ensure
+ that accessing memory using striding will not try to reach beyond
+ this memory for any of the axes.
+
+ If numbytes is 0 it will be calculated using the dimensions and
+ element-size.
+
+ This function checks for walking beyond the beginning and right-end
+ of the buffer and therefore works for any integer stride (positive
+ or negative).
*/
+
/*OBJECT_API*/
static Bool
PyArray_CheckStrides(int elsize, int nd, intp numbytes, intp offset,
intp *dims, intp *newstrides)
{
int i;
+ intp byte_begin;
+ intp begin;
+ intp end;
if (numbytes == 0)
numbytes = PyArray_MultiplyList(dims, nd) * elsize;
+ begin = -offset;
+ end = numbytes - offset - elsize;
for (i=0; i<nd; i++) {
- intp stride = newstrides[i];
- if (stride > 0) {
- /* The last stride does not need to be fully inside
- the buffer, only its first elsize bytes */
- if (offset + stride*(dims[i]-1)+elsize > numbytes) {
- return FALSE;
- }
- }
- else if (stride < 0) {
- if (offset + stride*dims[i] < 0) {
- return FALSE;
- }
- } else {
- /* XXX: Zero strides may be useful, but currently
- XXX: allowing them would lead to strange results,
- XXX: for example :
- XXX: >>> x = arange(5)
- XXX: >>> x.strides = 0
- XXX: >>> x += 1
- XXX: >>> x
- XXX: array([5, 5, 5, 5, 5]) */
+ byte_begin = newstrides[i]*(dims[i]-1);
+ if ((byte_begin < begin) || (byte_begin > end))
return FALSE;
- }
}
return TRUE;
@@ -3911,7 +3951,7 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
self->nd = nd;
self->dimensions = NULL;
self->data = NULL;
- if (data == NULL) { /* strides is NULL too */
+ if (data == NULL) {
self->flags = DEFAULT_FLAGS;
if (flags) {
self->flags |= FORTRAN;
@@ -3938,14 +3978,9 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
sd = _array_fill_strides(self->strides, dims, nd, sd,
flags, &(self->flags));
}
- else {
- if (data == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "if 'strides' is given in " \
- "array creation, data must " \
- "be given too");
- goto fail;
- }
+ else { /* we allow strides even when we create
+ the memory, but be careful with this...
+ */
memcpy(self->strides, strides, sizeof(intp)*nd);
}
}
@@ -3988,22 +4023,23 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
/* call the __array_finalize__
method if a subtype and some object passed in */
- if ((obj != NULL) && (subtype != &PyArray_Type) &&
- (subtype != &PyBigArray_Type)) {
+ if ((subtype != &PyArray_Type)) {
PyObject *res, *func, *args;
static PyObject *str=NULL;
if (str == NULL) {
str = PyString_InternFromString("__array_finalize__");
}
- if (!(self->flags & OWNDATA)) { /* did not allocate own data */
- /* update flags before calling back into
- Python */
+ if (strides != NULL) { /* did not allocate own data
+ or funny strides */
+ /* update flags before calling back into
+ Python */
PyArray_UpdateFlags(self, UPDATE_ALL_FLAGS);
}
func = PyObject_GetAttr((PyObject *)self, str);
if (func) {
args = PyTuple_New(1);
+ if (obj == NULL) obj=Py_None;
Py_INCREF(obj);
PyTuple_SET_ITEM(args, 0, obj);
res = PyObject_Call(func, args, NULL);
@@ -4026,9 +4062,13 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
/*OBJECT_API
Resize (reallocate data). Only works if nothing else is referencing
this array and it is contiguous.
+ If refcheck is 0, then the reference count is not checked
+ and assumed to be 1.
+ You still must own this data and have no weak-references and no base
+ object.
*/
static PyObject *
-PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape)
+PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck)
{
intp oldsize, newsize;
int new_nd=newshape->len, k, n, elsize;
@@ -4039,9 +4079,9 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape)
intp *dimptr;
char *new_data;
- if (!PyArray_ISCONTIGUOUS(self)) {
+ if (!PyArray_ISONESEGMENT(self)) {
PyErr_SetString(PyExc_ValueError,
- "resize only works on contiguous arrays");
+ "resize only works on single-segment arrays");
return NULL;
}
@@ -4056,7 +4096,8 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape)
return NULL;
}
- refcnt = REFCOUNT(self);
+ if (refcheck) refcnt = REFCOUNT(self);
+ else refcnt = 1;
if ((refcnt > 2) || (self->base != NULL) || \
(self->weakreflist != NULL)) {
PyErr_SetString(PyExc_ValueError,
@@ -4117,7 +4158,7 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape)
/* make new_strides variable */
sd = (intp) self->descr->elsize;
sd = _array_fill_strides(new_strides, new_dimensions, new_nd, sd,
- 0, &(self->flags));
+ self->flags, &(self->flags));
memmove(self->dimensions, new_dimensions, new_nd*sizeof(intp));
@@ -4173,9 +4214,17 @@ PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)
copyswap = arr->descr->f->copyswap;
if (PyArray_ISONESEGMENT(arr)) {
char *toptr=PyArray_DATA(arr);
- while (size--) {
- copyswap(toptr, fromptr, swap, itemsize);
- toptr += itemsize;
+ PyArray_FillWithScalarFunc* fillwithscalar =
+ arr->descr->f->fillwithscalar;
+ if (fillwithscalar && PyArray_ISALIGNED(arr)) {
+ copyswap(fromptr, NULL, swap, itemsize);
+ fillwithscalar(toptr, size, fromptr, arr);
+ }
+ else {
+ while (size--) {
+ copyswap(toptr, fromptr, swap, itemsize);
+ toptr += itemsize;
+ }
}
}
else {
@@ -4242,14 +4291,44 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
type_num = descr->type_num;
itemsize = descr->elsize;
- if (dims.ptr == NULL) {
- PyErr_SetString(PyExc_ValueError, "need to give a "\
- "valid shape as the first argument");
- goto fail;
- }
+ if (itemsize == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "data-type with unspecified variable length");
+ goto fail;
+ }
+
+ if (strides.ptr != NULL) {
+ intp nb, off;
+ if (strides.len != dims.len) {
+ PyErr_SetString(PyExc_ValueError,
+ "strides, if given, must be " \
+ "the same length as shape");
+ goto fail;
+ }
+ if (buffer.ptr == NULL) {
+ nb = 0;
+ off = 0;
+ }
+ else {
+ nb = buffer.len;
+ off = offset;
+ }
+
+
+ if (!PyArray_CheckStrides(itemsize, dims.len,
+ nb, off,
+ dims.ptr, strides.ptr)) {
+ PyErr_SetString(PyExc_ValueError,
+ "strides is incompatible " \
+ "with shape of requested " \
+ "array and size of buffer");
+ goto fail;
+ }
+ }
+
if (buffer.ptr == NULL) {
- ret = (PyArrayObject *)\
+ ret = (PyArrayObject *) \
PyArray_NewFromDescr(subtype, descr,
(int)dims.len,
dims.ptr,
@@ -4261,32 +4340,16 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
}
else { /* buffer given -- use it */
if (dims.len == 1 && dims.ptr[0] == -1) {
- dims.ptr[offset] = buffer.len / itemsize;
+ dims.ptr[0] = (buffer.len-offset) / itemsize;
}
- else if (buffer.len < itemsize* \
+ else if ((strides.ptr == NULL) && \
+ buffer.len < itemsize* \
PyArray_MultiplyList(dims.ptr, dims.len)) {
PyErr_SetString(PyExc_TypeError,
"buffer is too small for " \
"requested array");
goto fail;
}
- if (strides.ptr != NULL) {
- if (strides.len != dims.len) {
- PyErr_SetString(PyExc_ValueError,
- "strides, if given, must be "\
- "the same length as shape");
- goto fail;
- }
- if (!PyArray_CheckStrides(itemsize, strides.len,
- buffer.len, offset,
- dims.ptr, strides.ptr)) {
- PyErr_SetString(PyExc_ValueError,
- "strides is incompatible "\
- "with shape of requested "\
- "array and size of buffer");
- goto fail;
- }
- }
if (type_num == PyArray_OBJECT) {
PyErr_SetString(PyExc_TypeError, "cannot construct "\
"an object array from buffer data");
@@ -4396,7 +4459,10 @@ array_strides_set(PyArrayObject *self, PyObject *obj)
{
PyArray_Dims newstrides = {NULL, 0};
PyArrayObject *new;
- intp numbytes;
+ intp numbytes=0;
+ intp offset=0;
+ int buf_len;
+ char *buf;
if (!PyArray_IntpConverter(obj, &newstrides) || \
newstrides.ptr == NULL) {
@@ -4409,15 +4475,27 @@ array_strides_set(PyArrayObject *self, PyObject *obj)
goto fail;
}
new = self;
- while(new->base != NULL) {
- if (PyArray_Check(new->base))
- new = (PyArrayObject *)new->base;
+ while(new->base && PyArray_Check(new->base)) {
+ new = (PyArrayObject *)(new->base);
+ }
+ /* Get the available memory through the buffer
+ interface on new->base or if that fails
+ from the current new */
+ if (new->base && PyObject_AsReadBuffer(new->base,
+ (const void **)&buf,
+ &buf_len) >= 0) {
+ offset = self->data - buf;
+ numbytes = buf_len + offset;
+ }
+ else {
+ PyErr_Clear();
+ numbytes = PyArray_MultiplyList(new->dimensions,
+ new->nd)*new->descr->elsize;
+ offset = self->data - new->data;
}
- numbytes = PyArray_MultiplyList(new->dimensions,
- new->nd)*new->descr->elsize;
if (!PyArray_CheckStrides(self->descr->elsize, self->nd, numbytes,
- self->data - new->data,
+ offset,
self->dimensions, newstrides.ptr)) {
PyErr_SetString(PyExc_ValueError, "strides is not "\
"compatible with available memory");
@@ -4449,8 +4527,6 @@ array_priority_get(PyArrayObject *self)
{
if (PyArray_CheckExact(self))
return PyFloat_FromDouble(PyArray_PRIORITY);
- else if (PyBigArray_CheckExact(self))
- return PyFloat_FromDouble(PyArray_BIG_PRIORITY);
else
return PyFloat_FromDouble(PyArray_SUBTYPE_PRIORITY);
}
@@ -5055,10 +5131,10 @@ static char Arraytype__doc__[] =
" No __init__ method is needed because the array is fully \n"
" initialized after the __new__ method.";
-static PyTypeObject PyBigArray_Type = {
+static PyTypeObject PyArray_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
- "numpy.bigndarray", /*tp_name*/
+ "numpy.ndarray", /*tp_name*/
sizeof(PyArrayObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
@@ -5069,7 +5145,7 @@ static PyTypeObject PyBigArray_Type = {
(cmpfunc)0, /*tp_compare*/
(reprfunc)array_repr, /*tp_repr*/
&array_as_number, /*tp_as_number*/
- NULL, /*tp_as_sequence*/
+ &array_as_sequence, /*tp_as_sequence*/
&array_as_mapping, /*tp_as_mapping*/
(hashfunc)0, /*tp_hash*/
(ternaryfunc)0, /*tp_call*/
@@ -5077,7 +5153,7 @@ static PyTypeObject PyBigArray_Type = {
(getattrofunc)0, /*tp_getattro*/
(setattrofunc)0, /*tp_setattro*/
- NULL, /*tp_as_buffer*/
+ &array_as_buffer, /*tp_as_buffer*/
(Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_CHECKTYPES), /*tp_flags*/
@@ -5116,20 +5192,6 @@ static PyTypeObject PyBigArray_Type = {
0 /* tp_weaklist */
};
-/* A standard array will subclass from the Big Array and
- add the array_as_sequence table
- and the array_as_buffer table
- */
-
-static PyTypeObject PyArray_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "numpy.ndarray", /*tp_name*/
- sizeof(PyArrayObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
-};
-
-
/* The rest of this code is to build the right kind of array from a python */
/* object. */
@@ -5474,12 +5536,16 @@ Array_FromScalar(PyObject *op, PyArray_Descr *typecode)
if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) {
itemsize = PyObject_Length(op);
if (type == PyArray_UNICODE) itemsize *= 4;
+
+ if (itemsize != typecode->elsize) {
+ PyArray_DESCR_REPLACE(typecode);
+ typecode->elsize = itemsize;
+ }
}
- ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, typecode,
+ ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, typecode,
0, NULL,
NULL, NULL, 0, NULL);
-
if (ret == NULL) return NULL;
if (ret->nd > 0) {
PyErr_SetString(PyExc_ValueError,
@@ -5823,7 +5889,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags)
itemsize = newtype->elsize;
/* Don't copy if sizes are compatible */
- if (PyArray_EquivTypes(oldtype, newtype)) {
+ if ((flags & ENSURECOPY) || PyArray_EquivTypes(oldtype, newtype)) {
arrflags = arr->flags;
copy = (flags & ENSURECOPY) || \
@@ -5840,8 +5906,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags)
PyErr_SetString(PyExc_ValueError, msg);
return NULL;
}
- if ((flags & ENSUREARRAY) && \
- (subtype != &PyBigArray_Type)) {
+ if ((flags & ENSUREARRAY)) {
subtype = &PyArray_Type;
}
ret = (PyArrayObject *) \
@@ -5864,8 +5929,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags)
/* If no copy then just increase the reference
count and return the input */
else {
- if ((flags & ENSUREARRAY) && \
- (subtype != &PyBigArray_Type)) {
+ if ((flags & ENSUREARRAY)) {
Py_DECREF(newtype);
Py_INCREF(arr->descr);
ret = (PyArrayObject *) \
@@ -5900,8 +5964,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags)
PyErr_SetString(PyExc_ValueError, msg);
return NULL;
}
- if ((flags & ENSUREARRAY) && \
- (subtype != &PyBigArray_Type)) {
+ if ((flags & ENSUREARRAY)) {
subtype = &PyArray_Type;
}
ret = (PyArrayObject *)\
@@ -6242,22 +6305,28 @@ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context)
array_meth = PyObject_GetAttrString(op, "__array__");
if (array_meth == NULL) {PyErr_Clear(); return Py_NotImplemented;}
if (context == NULL) {
- if (typecode == NULL) new = PyObject_CallFunction(array_meth, NULL);
+ if (typecode == NULL) new = PyObject_CallFunction(array_meth,
+ NULL);
else new = PyObject_CallFunction(array_meth, "O", typecode);
}
else {
if (typecode == NULL) {
- new = PyObject_CallFunction(array_meth, "OO", Py_None, context);
- if (new == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
+ new = PyObject_CallFunction(array_meth, "OO", Py_None,
+ context);
+ if (new == NULL && \
+ PyErr_ExceptionMatches(PyExc_TypeError)) {
PyErr_Clear();
new = PyObject_CallFunction(array_meth, "");
}
}
else {
- new = PyObject_CallFunction(array_meth, "OO", typecode, context);
- if (new == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
+ new = PyObject_CallFunction(array_meth, "OO",
+ typecode, context);
+ if (new == NULL && \
+ PyErr_ExceptionMatches(PyExc_TypeError)) {
PyErr_Clear();
- new = PyObject_CallFunction(array_meth, "O", typecode);
+ new = PyObject_CallFunction(array_meth, "O",
+ typecode);
}
}
}
@@ -6305,7 +6374,8 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth,
PyObject *new;
if (r == NULL) return NULL;
if (newtype != NULL || flags != 0) {
- new = PyArray_FromArray((PyArrayObject *)r, newtype, flags);
+ new = PyArray_FromArray((PyArrayObject *)r, newtype,
+ flags);
Py_DECREF(r);
r = new;
}
@@ -6456,7 +6526,7 @@ PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int min_depth,
ENSUREARRAY) */
/* that special cases Arrays and PyArray_Scalars up front */
/* It *steals a reference* to the object */
-/* It also guarantees that the result is PyArray_Type or PyBigArray_Type */
+/* It also guarantees that the result is PyArray_Type */
/* Because it decrefs op if any conversion needs to take place
so it can be used like PyArray_EnsureArray(some_function(...)) */
@@ -6469,7 +6539,7 @@ PyArray_EnsureArray(PyObject *op)
if (op == NULL) return NULL;
- if (PyArray_CheckExact(op) || PyBigArray_CheckExact(op)) return op;
+ if (PyArray_CheckExact(op)) return op;
if (PyArray_IsScalar(op, Generic)) {
new = PyArray_FromScalar(op, NULL);
@@ -7577,8 +7647,19 @@ PyArray_MapIterBind(PyArrayMapIterObject *mit, PyArrayObject *arr)
therefore we can extract the subspace with a simple
getitem call which will use view semantics
*/
+ /* But, be sure to do it with a true array.
+ */
+ if (PyArray_CheckExact(arr)) {
+ sub = array_subscript(arr, mit->indexobj);
+ }
+ else {
+ Py_INCREF(arr);
+ obj = PyArray_EnsureArray((PyObject *)arr);
+ if (obj == NULL) goto fail;
+ sub = array_subscript((PyArrayObject *)obj, mit->indexobj);
+ Py_DECREF(obj);
+ }
- sub = PyObject_GetItem((PyObject *)arr, mit->indexobj);
if (sub == NULL) goto fail;
mit->subspace = (PyArrayIterObject *)PyArray_IterNew(sub);
Py_DECREF(sub);
diff --git a/numpy/core/src/arraytypes.inc.src b/numpy/core/src/arraytypes.inc.src
index 0fd105ab1..4bd24904a 100644
--- a/numpy/core/src/arraytypes.inc.src
+++ b/numpy/core/src/arraytypes.inc.src
@@ -1713,6 +1713,45 @@ static void
/**end repeat**/
+/* this requires buffer to be filled with objects or NULL */
+static void
+OBJECT_fillwithscalar(PyObject **buffer, intp length, PyObject **value, void *ignored)
+{
+ intp i;
+ PyObject *val = *value;
+ for (i=0; i<length; i++) {
+ Py_XDECREF(buffer[i]);
+ Py_INCREF(val);
+ buffer[i] = val;
+ }
+}
+/**begin repeat
+#NAME=BOOL,BYTE,UBYTE#
+#typ=Bool,byte,ubyte#
+*/
+static void
+@NAME@_fillwithscalar(@typ@ *buffer, intp length, @typ@ *value, void *ignored)
+{
+ memset(buffer, *value, length);
+}
+/**end repeat**/
+
+/**begin repeat
+#NAME=SHORT,USHORT,INT,UINT,LONG,ULONG,LONGLONG,ULONGLONG,FLOAT,DOUBLE,LONGDOUBLE,CFLOAT,CDOUBLE,CLONGDOUBLE#
+#typ=short,ushort,int,uint,long,ulong,longlong,ulonglong,float,double,longdouble,cfloat,cdouble,clongdouble#
+*/
+static void
+@NAME@_fillwithscalar(@typ@ *buffer, intp length, @typ@ *value, void *ignored)
+{
+ register intp i;
+ @typ@ val = *value;
+ for (i=0; i<length; ++i) {
+ buffer[i] = val;
+ }
+}
+
+/**end repeat**/
+
#define _ALIGN(type) offsetof(struct {char c; type v;},v)
/**begin repeat
@@ -1758,6 +1797,7 @@ static PyArray_ArrFuncs _Py@NAME@_ArrFuncs = {
(PyArray_FromStrFunc*)@from@_fromstr,
(PyArray_NonzeroFunc*)@from@_nonzero,
(PyArray_FillFunc*)NULL,
+ (PyArray_FillWithScalarFunc*)NULL,
{
NULL, NULL, NULL, NULL
},
@@ -1828,6 +1868,7 @@ static PyArray_ArrFuncs _Py@NAME@_ArrFuncs = {
(PyArray_FromStrFunc*)@from@_fromstr,
(PyArray_NonzeroFunc*)@from@_nonzero,
(PyArray_FillFunc*)@from@_fill,
+ (PyArray_FillWithScalarFunc*)@from@_fillwithscalar,
{
NULL, NULL, NULL, NULL
},
diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c
index 481e5709a..3e3f71527 100644
--- a/numpy/core/src/multiarraymodule.c
+++ b/numpy/core/src/multiarraymodule.c
@@ -195,6 +195,87 @@ PyArray_Ravel(PyArrayObject *a, int fortran)
return PyArray_Flatten(a, fortran);
}
+static double
+power_of_ten(int n)
+{
+ static const double p10[] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8};
+ double ret;
+ if (n < 9)
+ ret = p10[n];
+ else {
+ ret = 1e9;
+ while (n-- > 9)
+ ret *= 10.;
+ }
+ return ret;
+}
+
+/*MULTIARRAY_API
+ Round
+*/
+static PyObject *
+PyArray_Round(PyArrayObject *a, int decimals)
+{
+ /* do the most common case first */
+ if (decimals == 0) {
+ if (PyArray_ISINTEGER(a)) {
+ Py_INCREF(a);
+ return (PyObject *)a;
+ }
+ return PyArray_GenericUnaryFunction((PyAO *)a, n_ops.rint);
+ }
+ if (decimals > 0) {
+ PyObject *f, *ret;
+ if (PyArray_ISINTEGER(a)) {
+ Py_INCREF(a);
+ return (PyObject *)a;
+ }
+ f = PyFloat_FromDouble(power_of_ten(decimals));
+ if (f==NULL) return NULL;
+ ret = PyNumber_Multiply((PyObject *)a, f);
+ if (ret==NULL) {Py_DECREF(f); return NULL;}
+ if (PyArray_IsScalar(ret, Generic)) {
+ /* array scalars cannot be modified inplace */
+ PyObject *tmp;
+ tmp = PyObject_CallFunction(n_ops.rint, "O", ret);
+ Py_DECREF(ret);
+ ret = PyObject_CallFunction(n_ops.divide, "OO",
+ tmp, f);
+ Py_DECREF(tmp);
+ } else {
+ PyObject_CallFunction(n_ops.rint, "OO", ret, ret);
+ PyObject_CallFunction(n_ops.divide, "OOO", ret,
+ f, ret);
+ }
+ Py_DECREF(f);
+ return ret;
+ }
+ else {
+ /* remaining case: decimals < 0 */
+ PyObject *f, *ret;
+ f = PyFloat_FromDouble(power_of_ten(-decimals));
+ if (f==NULL) return NULL;
+ ret = PyNumber_Divide((PyObject *)a, f);
+ if (ret==NULL) {Py_DECREF(f); return NULL;}
+ if (PyArray_IsScalar(ret, Generic)) {
+ /* array scalars cannot be modified inplace */
+ PyObject *tmp;
+ tmp = PyObject_CallFunction(n_ops.rint, "O", ret);
+ Py_DECREF(ret);
+ ret = PyObject_CallFunction(n_ops.multiply, "OO",
+ tmp, f);
+ Py_DECREF(tmp);
+ } else {
+ PyObject_CallFunction(n_ops.rint, "OO", ret, ret);
+ PyObject_CallFunction(n_ops.multiply, "OOO", ret,
+ f, ret);
+ }
+ Py_DECREF(f);
+ return ret;
+ }
+}
+
+
/*MULTIARRAY_API
Flatten
*/
@@ -1434,40 +1515,40 @@ _signbit_set(PyArrayObject *arr)
/*OBJECT_API*/
-static char
+static PyArray_SCALARKIND
PyArray_ScalarKind(int typenum, PyArrayObject **arr)
{
if (PyTypeNum_ISSIGNED(typenum)) {
- if (arr && _signbit_set(*arr)) return UFUNC_INTNEG_SCALAR;
- else return UFUNC_INTPOS_SCALAR;
+ if (arr && _signbit_set(*arr)) return PyArray_INTNEG_SCALAR;
+ else return PyArray_INTPOS_SCALAR;
}
- if (PyTypeNum_ISFLOAT(typenum)) return UFUNC_FLOAT_SCALAR;
- if (PyTypeNum_ISUNSIGNED(typenum)) return UFUNC_INTPOS_SCALAR;
- if (PyTypeNum_ISCOMPLEX(typenum)) return UFUNC_COMPLEX_SCALAR;
- if (PyTypeNum_ISBOOL(typenum)) return UFUNC_BOOL_SCALAR;
+ if (PyTypeNum_ISFLOAT(typenum)) return PyArray_FLOAT_SCALAR;
+ if (PyTypeNum_ISUNSIGNED(typenum)) return PyArray_INTPOS_SCALAR;
+ if (PyTypeNum_ISCOMPLEX(typenum)) return PyArray_COMPLEX_SCALAR;
+ if (PyTypeNum_ISBOOL(typenum)) return PyArray_BOOL_SCALAR;
- return UFUNC_OBJECT_SCALAR;
+ return PyArray_OBJECT_SCALAR;
}
-
/*OBJECT_API*/
static int
-PyArray_CanCoerceScalar(char thistype, char neededtype, char scalar)
+PyArray_CanCoerceScalar(char thistype, char neededtype,
+ PyArray_SCALARKIND scalar)
{
switch(scalar) {
- case UFUNC_NOSCALAR:
- case UFUNC_BOOL_SCALAR:
- case UFUNC_OBJECT_SCALAR:
+ case PyArray_NOSCALAR:
+ case PyArray_BOOL_SCALAR:
+ case PyArray_OBJECT_SCALAR:
return PyArray_CanCastSafely(thistype, neededtype);
- case UFUNC_INTPOS_SCALAR:
+ case PyArray_INTPOS_SCALAR:
return (neededtype >= PyArray_UBYTE);
- case UFUNC_INTNEG_SCALAR:
+ case PyArray_INTNEG_SCALAR:
return (neededtype >= PyArray_BYTE) && \
!(PyTypeNum_ISUNSIGNED(neededtype));
- case UFUNC_FLOAT_SCALAR:
+ case PyArray_FLOAT_SCALAR:
return (neededtype >= PyArray_FLOAT);
- case UFUNC_COMPLEX_SCALAR:
+ case PyArray_COMPLEX_SCALAR:
return (neededtype >= PyArray_CFLOAT);
}
fprintf(stderr, "\n**Error** coerce fall through: %d %d %d\n\n",
@@ -4246,7 +4327,7 @@ _array_fromobject(PyObject *ignored, PyObject *args, PyObject *kws)
return NULL;
/* fast exit if simple call */
- if ((PyArray_CheckExact(op) || PyBigArray_CheckExact(op))) {
+ if (PyArray_CheckExact(op)) {
if (type==NULL) {
if (!copy && fortran==PyArray_ISFORTRAN(op)) {
Py_INCREF(op);
@@ -5750,25 +5831,6 @@ DL_EXPORT(void) initmultiarray(void) {
d = PyModule_GetDict(m);
if (!d) goto err;
- /* Create the module and add the functions */
- if (PyType_Ready(&PyBigArray_Type) < 0)
- return;
-
- PyArray_Type.tp_base = &PyBigArray_Type;
-
- PyArray_Type.tp_as_mapping = &array_as_mapping;
- /* Even though, this would be inherited, it needs to be set now
- so that the __getitem__ will map to the as_mapping descriptor
- */
- PyArray_Type.tp_as_number = &array_as_number;
- /* For good measure */
- PyArray_Type.tp_as_sequence = &array_as_sequence;
- PyArray_Type.tp_as_buffer = &array_as_buffer;
- PyArray_Type.tp_flags = (Py_TPFLAGS_DEFAULT
- | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_CHECKTYPES);
- PyArray_Type.tp_doc = Arraytype__doc__;
-
if (PyType_Ready(&PyArray_Type) < 0)
return;
@@ -5800,8 +5862,6 @@ DL_EXPORT(void) initmultiarray(void) {
s = PyString_FromString("3.0");
PyDict_SetItemString(d, "__version__", s);
Py_DECREF(s);
- Py_INCREF(&PyBigArray_Type);
- PyDict_SetItemString(d, "bigndarray", (PyObject *)&PyBigArray_Type);
Py_INCREF(&PyArray_Type);
PyDict_SetItemString(d, "ndarray", (PyObject *)&PyArray_Type);
Py_INCREF(&PyArrayIter_Type);
diff --git a/numpy/core/src/scalartypes.inc.src b/numpy/core/src/scalartypes.inc.src
index 9926cd83c..b984cf81a 100644
--- a/numpy/core/src/scalartypes.inc.src
+++ b/numpy/core/src/scalartypes.inc.src
@@ -459,14 +459,11 @@ gentype_multiply(PyObject *m1, PyObject *m2)
Py_DECREF(arr);
Py_DECREF(tup);
return ret;
-
}
-
-
/**begin repeat
-#name=negative, absolute, invert, int, long, float, oct, hex#
+#name=positive, negative, absolute, invert, int, long, float, oct, hex#
*/
static PyObject *
@@ -639,7 +636,6 @@ static PyObject *
/**end repeat**/
-static PyObject *gentype_copy(PyObject *, PyObject *);
static PyNumberMethods gentype_as_number = {
(binaryfunc)gentype_add, /*nb_add*/
@@ -650,7 +646,7 @@ static PyNumberMethods gentype_as_number = {
(binaryfunc)gentype_divmod, /*nb_divmod*/
(ternaryfunc)gentype_power, /*nb_power*/
(unaryfunc)gentype_negative,
- (unaryfunc)gentype_copy, /*nb_pos*/
+ (unaryfunc)gentype_positive, /*nb_pos*/
(unaryfunc)gentype_absolute, /*(unaryfunc)gentype_abs,*/
(inquiry)gentype_nonzero_number, /*nb_nonzero*/
(unaryfunc)gentype_invert, /*nb_invert*/
@@ -1065,7 +1061,7 @@ gentype_wraparray(PyObject *scalar, PyObject *args)
/**begin repeat
-#name=tolist, item, tostring, astype, copy, resize, __deepcopy__, choose, searchsorted, argmax, argmin, reshape, view, swapaxes, max, min, ptp, conj, conjugate, nonzero, all, any, flatten, ravel, fill, transpose, newbyteorder#
+#name=tolist, item, tostring, astype, copy, __deepcopy__, choose, searchsorted, reshape, view, swapaxes, conj, conjugate, nonzero, flatten, ravel, fill, transpose, newbyteorder#
*/
static PyObject *
@@ -1124,7 +1120,7 @@ gentype_byteswap(PyObject *self, PyObject *args)
/**begin repeat
-#name=take, getfield, put, putmask, repeat, tofile, mean, trace, diagonal, clip, std, var, sum, cumsum, prod, cumprod, compress, sort, argsort#
+#name=take, getfield, put, putmask, repeat, tofile, mean, trace, diagonal, clip, std, var, sum, cumsum, prod, cumprod, compress, sort, argsort, round, argmax, argmin, max, min, ptp, any, all, resize#
*/
static PyObject *
@@ -1338,9 +1334,9 @@ static PyMethodDef gentype_methods[] = {
{"searchsorted", (PyCFunction)gentype_searchsorted,
METH_VARARGS, NULL},
{"argmax", (PyCFunction)gentype_argmax,
- METH_VARARGS, NULL},
+ METH_VARARGS|METH_KEYWORDS, NULL},
{"argmin", (PyCFunction)gentype_argmin,
- METH_VARARGS, NULL},
+ METH_VARARGS|METH_KEYWORDS, NULL},
{"reshape", (PyCFunction)gentype_reshape,
METH_VARARGS, NULL},
{"squeeze", (PyCFunction)gentype_squeeze,
@@ -1350,11 +1346,11 @@ static PyMethodDef gentype_methods[] = {
{"swapaxes", (PyCFunction)gentype_swapaxes,
METH_VARARGS, NULL},
{"max", (PyCFunction)gentype_max,
- METH_VARARGS, NULL},
+ METH_VARARGS|METH_KEYWORDS, NULL},
{"min", (PyCFunction)gentype_min,
- METH_VARARGS, NULL},
+ METH_VARARGS|METH_KEYWORDS, NULL},
{"ptp", (PyCFunction)gentype_ptp,
- METH_VARARGS, NULL},
+ METH_VARARGS|METH_KEYWORDS, NULL},
{"mean", (PyCFunction)gentype_mean,
METH_VARARGS|METH_KEYWORDS, NULL},
{"trace", (PyCFunction)gentype_trace,
@@ -1382,15 +1378,17 @@ static PyMethodDef gentype_methods[] = {
{"cumprod", (PyCFunction)gentype_cumprod,
METH_VARARGS|METH_KEYWORDS, NULL},
{"all", (PyCFunction)gentype_all,
- METH_VARARGS, NULL},
+ METH_VARARGS|METH_KEYWORDS, NULL},
{"any", (PyCFunction)gentype_any,
- METH_VARARGS, NULL},
+ METH_VARARGS|METH_KEYWORDS, NULL},
{"compress", (PyCFunction)gentype_compress,
METH_VARARGS|METH_KEYWORDS, NULL},
{"flatten", (PyCFunction)gentype_flatten,
METH_VARARGS, NULL},
{"ravel", (PyCFunction)gentype_ravel,
METH_VARARGS, NULL},
+ {"round", (PyCFunction)gentype_round,
+ METH_VARARGS|METH_KEYWORDS, NULL},
{"setflags", (PyCFunction)gentype_setflags,
METH_VARARGS|METH_KEYWORDS, NULL},
{"newbyteorder", (PyCFunction)gentype_newbyteorder,
@@ -2423,8 +2421,8 @@ PyArray_TypeObjectFromType(int type)
descr = PyArray_DescrFromType(type);
if (descr == NULL) return NULL;
- Py_INCREF((PyObject *)descr->typeobj);
obj = (PyObject *)descr->typeobj;
+ Py_INCREF(obj);
Py_DECREF(descr);
return obj;
}
diff --git a/numpy/core/src/ufuncobject.c b/numpy/core/src/ufuncobject.c
index e09b1ffd5..3083bb461 100644
--- a/numpy/core/src/ufuncobject.c
+++ b/numpy/core/src/ufuncobject.c
@@ -610,7 +610,7 @@ _lowest_type(char intype)
static int
select_types(PyUFuncObject *self, int *arg_types,
PyUFuncGenericFunction *function, void **data,
- char *scalars)
+ PyArray_SCALARKIND *scalars)
{
int i=0, j;
@@ -663,7 +663,7 @@ select_types(PyUFuncObject *self, int *arg_types,
/* If the first argument is a scalar we need to place
the start type as the lowest type in the class
*/
- if (scalars[0] != UFUNC_NOSCALAR) {
+ if (scalars[0] != PyArray_NOSCALAR) {
start_type = _lowest_type(start_type);
}
@@ -850,7 +850,7 @@ construct_matrices(PyUFuncLoopObject *loop, PyObject *args, PyArrayObject **mps)
{
int nargs, i, maxsize;
int arg_types[MAX_ARGS];
- char scalars[MAX_ARGS];
+ PyArray_SCALARKIND scalars[MAX_ARGS];
PyUFuncObject *self=loop->ufunc;
Bool allscalars=TRUE;
PyTypeObject *subtype=&PyArray_Type;
@@ -889,21 +889,17 @@ construct_matrices(PyUFuncLoopObject *loop, PyObject *args, PyArrayObject **mps)
at this point
*/
if (mps[i]->nd > 0) {
- scalars[i] = UFUNC_NOSCALAR;
+ scalars[i] = PyArray_NOSCALAR;
allscalars=FALSE;
}
else scalars[i] = PyArray_ScalarKind(arg_types[i], &(mps[i]));
- /* If any input is a big-array */
- if (!PyType_IsSubtype(mps[i]->ob_type, &PyArray_Type)) {
- subtype = &PyBigArray_Type;
- }
}
/* If everything is a scalar, then use normal coercion rules */
if (allscalars) {
for (i=0; i<self->nin; i++) {
- scalars[i] = UFUNC_NOSCALAR;
+ scalars[i] = PyArray_NOSCALAR;
}
}
@@ -921,7 +917,6 @@ construct_matrices(PyUFuncLoopObject *loop, PyObject *args, PyArrayObject **mps)
(loop->ufunc->nin==2) && (loop->ufunc->nout == 1)) {
PyObject *_obj = PyTuple_GET_ITEM(args, 1);
if (!PyArray_CheckExact(_obj) && \
- !PyBigArray_CheckExact(_obj) && \
PyObject_HasAttrString(_obj, "__array_priority__") && \
_has_reflected_op(_obj, loop->ufunc->name)) {
loop->notimplemented = 1;
@@ -1716,7 +1711,8 @@ construct_reduce(PyUFuncObject *self, PyArrayObject **arr, int axis,
PyArrayObject *aar;
intp loop_i[MAX_DIMS];
int arg_types[3] = {otype, otype, otype};
- char scalars[3] = {UFUNC_NOSCALAR, UFUNC_NOSCALAR, UFUNC_NOSCALAR};
+ PyArray_SCALARKIND scalars[3] = {PyArray_NOSCALAR, PyArray_NOSCALAR,
+ PyArray_NOSCALAR};
int i, j;
int nd = (*arr)->nd;
/* Reduce type is the type requested of the input
@@ -2535,7 +2531,7 @@ _find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout)
nargs = PyTuple_GET_SIZE(args);
for (i=0; i<nin; i++) {
obj = PyTuple_GET_ITEM(args, i);
- if (PyArray_CheckExact(obj) || PyBigArray_CheckExact(obj) || \
+ if (PyArray_CheckExact(obj) || \
PyArray_IsAnyScalar(obj))
continue;
wrap = PyObject_GetAttrString(obj, "__array_wrap__");
@@ -2546,6 +2542,7 @@ _find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout)
++np;
}
else {
+ Py_DECREF(wrap);
wrap = NULL;
}
}
@@ -2594,8 +2591,7 @@ _find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout)
obj = PyTuple_GET_ITEM(args, j);
if (obj == Py_None)
continue;
- if (PyArray_CheckExact(obj) ||
- PyBigArray_CheckExact(obj)) {
+ if (PyArray_CheckExact(obj)) {
output_wrap[i] = Py_None;
}
else {
@@ -2616,7 +2612,8 @@ _find_array_wrap(PyObject *args, PyObject **output_wrap, int nin, int nout)
Py_XINCREF(output_wrap[i]);
}
}
-
+
+ Py_XDECREF(wrap);
return;
}
@@ -2691,9 +2688,12 @@ ufunc_generic_call(PyUFuncObject *self, PyObject *args)
}
res = PyObject_CallFunction(wrap, "O(OOi)",
mps[j], self, args, i);
- if (res == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
+ if (res == NULL && \
+ PyErr_ExceptionMatches(PyExc_TypeError)) {
PyErr_Clear();
- res = PyObject_CallFunctionObjArgs(wrap, mps[j], NULL);
+ res = PyObject_CallFunctionObjArgs(wrap,
+ mps[j],
+ NULL);
}
Py_DECREF(wrap);
if (res == NULL) goto fail;
diff --git a/numpy/core/src/umathmodule.c.src b/numpy/core/src/umathmodule.c.src
index 11d7c0c7b..0da04e53f 100644
--- a/numpy/core/src/umathmodule.c.src
+++ b/numpy/core/src/umathmodule.c.src
@@ -222,7 +222,7 @@ static longdouble atanhl(longdouble x)
extern double hypot(double, double);
#endif
#else
-double hypot(double x, double y)
+static double hypot(double x, double y)
{
double yx;
@@ -243,6 +243,30 @@ double hypot(double x, double y)
#endif
+#ifndef HAVE_RINT
+static double
+rint (double x)
+{
+ double y, r;
+
+ y = floor(x);
+ r = x - y;
+
+ if (r > 0.5) goto rndup;
+
+ /* Round to nearest even */
+ if (r==0.5) {
+ r = y - 2.0*floor(0.5*y);
+ if (r==1.0) {
+ rndup:
+ y+=1.0;
+ }
+ }
+ return y;
+}
+#endif
+
+
/* Define isnan, isinf, isfinite, signbit if needed */
/* Use fpclassify if possible */
@@ -287,7 +311,6 @@ double hypot(double x, double y)
#include "_signbit.c"
#endif
-
/* Now defined the extended type macros */
#if !defined(isnan)
@@ -357,10 +380,10 @@ double hypot(double x, double y)
/**begin repeat
-#kind=(sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,sqrt,log10,log,exp,asin,acos,atan)*2#
-#typ=longdouble*16, float*16#
-#c=l*16,f*16#
-#TYPE=LONGDOUBLE*16, FLOAT*16#
+#kind=(sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,sqrt,log10,log,exp,asin,acos,atan,rint)*2#
+#typ=longdouble*17, float*17#
+#c=l*17,f*17#
+#TYPE=LONGDOUBLE*17, FLOAT*17#
*/
#ifndef HAVE_@TYPE@_FUNCS
#ifdef @kind@@c@
@@ -659,19 +682,19 @@ nc_pow@c@(c@typ@ *a, c@typ@ *b, c@typ@ *r)
}
if (bi == 0 && (n=(intp)br) == br) {
if (n > -100 && n < 100) {
- c@typ@ p, a;
+ c@typ@ p, aa;
intp mask = 1;
if (n < 0) n = -n;
- a = nc_1@c@;
+ aa = nc_1@c@;
p.real = ar; p.imag = ai;
while (1) {
if (n & mask)
- nc_prod@c@(&a,&p,&a);
+ nc_prod@c@(&aa,&p,&aa);
mask <<= 1;
if (n < mask || mask <= 0) break;
nc_prod@c@(&p,&p,&p);
}
- r->real = a.real; r->imag = a.imag;
+ r->real = aa.real; r->imag = aa.imag;
if (bi < 0) nc_quot@c@(&nc_1@c@, r, r);
return;
}
diff --git a/numpy/core/tests/test_ma.py b/numpy/core/tests/test_ma.py
index 03274237e..abee7d91f 100644
--- a/numpy/core/tests/test_ma.py
+++ b/numpy/core/tests/test_ma.py
@@ -2,6 +2,7 @@ import numpy
import types, time
from numpy.core.ma import *
from numpy.testing import ScipyTestCase, ScipyTest
+pi = numpy.pi
def eq(v,w, msg=''):
result = allclose(v,w)
if not result:
@@ -620,7 +621,12 @@ class test_ma(ScipyTestCase):
self.failUnless(eq(a.sum(), a.data.sum()))
self.failUnless(eq(a.take([1,2]), a.data.take([1,2])))
self.failUnless(eq(m.transpose(), m.data.transpose()))
-
+
+ def check_testArrayAttributes(self):
+ a = array([1,3,2])
+ b = array([1,3,2], mask=[1,0,1])
+ self.failUnlessEqual(a.ndim, 1)
+
def check_testAPI(self):
self.failIf([m for m in dir(numpy.ndarray)
if m not in dir(array) and not m.startswith('_')])
@@ -685,7 +691,12 @@ class test_ufuncs(ScipyTestCase):
self.failUnless((amask.min(0) == [5,6,7,8]).all())
self.failUnless(amask.max(1)[0].mask)
self.failUnless(amask.min(1)[0].mask)
-
+
+ def test_nonzero(self):
+ for t in "?bhilqpBHILQPfdgFDGO":
+ x = array([1,0,2,0], mask=[0,0,1,1])
+ self.failUnless(eq(nonzero(x), [0]))
+
def eqmask(m1, m2):
if m1 is nomask:
return m2 is nomask
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 72672bf0d..f220a949a 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -70,10 +70,10 @@ class test_attributes(ScipyTestCase):
strides=strides*x.itemsize)
assert_equal(make_array(4, 4, -1), array([4, 3, 2, 1]))
self.failUnlessRaises(ValueError, make_array, 4, 4, -2)
- self.failUnlessRaises(ValueError, make_array, 4, 3, -1)
+ self.failUnlessRaises(ValueError, make_array, 4, 2, -1)
self.failUnlessRaises(ValueError, make_array, 8, 3, 1)
- self.failUnlessRaises(ValueError, make_array, 8, 3, 0)
- self.failUnlessRaises(ValueError, lambda: ndarray([1], strides=4))
+ #self.failUnlessRaises(ValueError, make_array, 8, 3, 0)
+ #self.failUnlessRaises(ValueError, lambda: ndarray([1], strides=4))
def check_set_stridesattr(self):
@@ -87,10 +87,21 @@ class test_attributes(ScipyTestCase):
return r
assert_equal(make_array(4, 4, -1), array([4, 3, 2, 1]))
self.failUnlessRaises(ValueError, make_array, 4, 4, -2)
- self.failUnlessRaises(ValueError, make_array, 4, 3, -1)
+ self.failUnlessRaises(ValueError, make_array, 4, 2, -1)
self.failUnlessRaises(ValueError, make_array, 8, 3, 1)
- self.failUnlessRaises(ValueError, make_array, 8, 3, 0)
-
+ #self.failUnlessRaises(ValueError, make_array, 8, 3, 0)
+
+ def check_fill(self):
+ for t in "?bhilqpBHILQPfdgFDGO":
+ x = empty((3,2,1), t)
+ y = empty((3,2,1), t)
+ x.fill(1)
+ y[...] = 1
+ assert_equal(x,y)
+
+ x = array([(0,0.0), (1,1.0)], dtype='i4,f8')
+ x.fill(x[0])
+ assert_equal(x['f1'][1], x['f1'][0])
class test_dtypedescr(ScipyTestCase):
def check_construction(self):
@@ -117,8 +128,8 @@ class test_zero_rank(ScipyTestCase):
a,b = self.d
self.failUnlessEqual(a[...], 0)
self.failUnlessEqual(b[...], 'x')
- self.failUnless(type(a[...]) is a.dtype.type)
- self.failUnless(type(b[...]) is str)
+ self.failUnless(a[...] is a)
+ self.failUnless(b[...] is b)
def check_empty_subscript(self):
a,b = self.d
@@ -173,6 +184,14 @@ class test_zero_rank(ScipyTestCase):
self.failUnlessRaises(IndexError, subscript, a, (newaxis, 0))
self.failUnlessRaises(IndexError, subscript, a, (newaxis,)*50)
+ def check_constructor(self):
+ x = ndarray(())
+ x[()] = 5
+ self.failUnlessEqual(x[()], 5)
+ y = ndarray((),buffer=x)
+ y[()] = 6
+ self.failUnlessEqual(x[()], 6)
+
class test_creation(ScipyTestCase):
def check_from_attribute(self):
class x(object):
@@ -189,8 +208,33 @@ class test_bool(ScipyTestCase):
b1 = bool_(True)
self.failUnless(a1 is b1)
self.failUnless(array([True])[0] is a1)
- self.failUnless(array(True)[...] is a1)
+ self.failUnless(array(True)[()] is a1)
+
+
+class test_methods(ScipyTestCase):
+ def check_test_round(self):
+ assert_equal(array([1.2,1.5]).round(), [1,2])
+ assert_equal(array(1.5).round(), 2)
+ assert_equal(array([12.2,15.5]).round(-1), [10,20])
+ assert_equal(array([12.15,15.51]).round(1), [12.2,15.5])
+
+class test_subscripting(ScipyTestCase):
+ def check_test_zero_rank(self):
+ x = array([1,2,3])
+ self.failUnless(isinstance(x[0], int))
+ self.failUnless(type(x[0, ...]) is ndarray)
+
+class test_pickling(ScipyTestCase):
+ def setUp(self):
+ self.carray = array([[2,9],[7,0],[3,8]])
+ self.tarray = transpose(self.carray)
+
+ def check_both(self):
+ import pickle
+ assert_equal(self.carray, pickle.loads(self.carray.dumps()))
+ assert_equal(self.tarray, pickle.loads(self.tarray.dumps()))
+
# Import tests from unicode
set_local_path()
from test_unicode import *
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index a29a5ecca..204c88dab 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -23,6 +23,8 @@ class test_power(ScipyTestCase):
assert_almost_equal(x**(-1), [1/(1+2j), 1/(2+3j), 1/(3+4j)])
assert_almost_equal(x**(0.5), [ncu.sqrt(1+2j), ncu.sqrt(2+3j),
ncu.sqrt(3+4j)])
+ assert_almost_equal(x**14, [-76443+16124j, 23161315+58317492j,
+ 5583548873 + 2465133864j])
class test_log1p(ScipyTestCase):
def check_log1p(self):
diff --git a/numpy/dft/__init__.py b/numpy/dft/__init__.py
index 236aefdcb..817c99bc8 100644
--- a/numpy/dft/__init__.py
+++ b/numpy/dft/__init__.py
@@ -4,5 +4,7 @@ from info import __doc__
from fftpack import *
from helper import *
-from numpy.testing import ScipyTest
-test = ScipyTest().test
+def test(level=1, verbosity=1):
+ from numpy.testing import NumpyTest
+ return NumpyTest().test(level, verbosity)
+
diff --git a/numpy/distutils/__init__.py b/numpy/distutils/__init__.py
index 3094541c1..3af26ac41 100644
--- a/numpy/distutils/__init__.py
+++ b/numpy/distutils/__init__.py
@@ -14,5 +14,6 @@ except ImportError:
_INSTALLED = False
if _INSTALLED:
- from numpy.testing import ScipyTest
- test = ScipyTest().test
+ def test(level=1, verbosity=1):
+ from numpy.testing import NumpyTest
+ return NumpyTest().test(level, verbosity)
diff --git a/numpy/distutils/ccompiler.py b/numpy/distutils/ccompiler.py
index efd458897..3e5d25dce 100644
--- a/numpy/distutils/ccompiler.py
+++ b/numpy/distutils/ccompiler.py
@@ -13,6 +13,14 @@ from exec_command import exec_command
from misc_util import cyg2win32, is_sequence, mingw32
from distutils.spawn import _nt_quote_args
+# hack to set compiler optimizing options. Needs to integrated with something.
+import distutils.sysconfig
+_old_init_posix = distutils.sysconfig._init_posix
+def _new_init_posix():
+ _old_init_posix()
+ distutils.sysconfig._config_vars['OPT'] = '-Wall -g -O2'
+#distutils.sysconfig._init_posix = _new_init_posix
+
# Using customized CCompiler.spawn.
def CCompiler_spawn(self, cmd, display=None):
if display is None:
diff --git a/numpy/distutils/misc_util.py b/numpy/distutils/misc_util.py
index 0de24cc94..c32b2f23c 100644
--- a/numpy/distutils/misc_util.py
+++ b/numpy/distutils/misc_util.py
@@ -293,7 +293,7 @@ def is_local_src_dir(directory):
def general_source_files(top_path):
pruned_directories = {'CVS':1, '.svn':1, 'build':1}
- prune_file_pat = re.compile(r'(?:[~#]|\.py[co]|\.o)$')
+ prune_file_pat = re.compile(r'(?:^\..*|[~#]|\.py[co]|\.o)$')
for dirpath, dirnames, filenames in os.walk(top_path, topdown=True):
pruned = [ d for d in dirnames if d not in pruned_directories ]
dirnames[:] = pruned
diff --git a/numpy/f2py/f2py2e.py b/numpy/f2py/f2py2e.py
index 4f5963dff..e4aeeffe2 100755
--- a/numpy/f2py/f2py2e.py
+++ b/numpy/f2py/f2py2e.py
@@ -162,7 +162,7 @@ Extra options (only effective with -c):
Version: %s
numpy Version: %s
Requires: Python 2.3 or higher.
-License: LGPL (see http://www.fsf.org)
+License: NumPy license (see LICENSE.txt in the NumPy source code)
Copyright 1999 - 2005 Pearu Peterson all rights reserved.
http://cens.ioc.ee/projects/f2py2e/"""%(f2py_version, numpy_version)
diff --git a/numpy/lib/UserArray.py b/numpy/lib/UserArray.py
new file mode 100644
index 000000000..26b4b6578
--- /dev/null
+++ b/numpy/lib/UserArray.py
@@ -0,0 +1,217 @@
+# Standard container-class for easy backward compatibility
+# with Numeric.
+# Try to inherit from the ndarray instead of using this
+# class as this is not complete.
+
+from numpy.core import *
+import string
+
+class UserArray(object):
+ def __init__(self, data, dtype=None, copy=True):
+ self.array = array(data, dtype, copy)
+
+ def __repr__(self):
+ if len(self.shape) > 0:
+ return self.__class__.__name__+repr(self.array)[len("array"):]
+ else:
+ return self.__class__.__name__+"("+repr(self.array)+")"
+
+ def __array__(self,t=None):
+ if t: return self.array.astype(t)
+ return self.array
+
+ def __float__(self):
+ return float(self.array)
+
+ # Array as sequence
+ def __len__(self): return len(self.array)
+
+ def __getitem__(self, index):
+ return self._rc(self.array[index])
+
+ def __getslice__(self, i, j):
+ return self._rc(self.array[i:j])
+
+
+ def __setitem__(self, index, value):
+ self.array[index] = asarray(value,self.dtype)
+ def __setslice__(self, i, j, value):
+ self.array[i:j] = asarray(value,self.dtype)
+
+ def __abs__(self):
+ return self._rc(absolute(self.array))
+ def __neg__(self):
+ return self._rc(-self.array)
+
+ def __add__(self, other):
+ return self._rc(self.array+asarray(other))
+ __radd__ = __add__
+
+ def __iadd__(self, other):
+ add(self.array, other, self.array)
+ return self
+
+ def __sub__(self, other):
+ return self._rc(self.array-asarray(other))
+ def __rsub__(self, other):
+ return self._rc(asarray(other)-self.array)
+ def __isub__(self, other):
+ subtract(self.array, other, self.array)
+ return self
+
+ def __mul__(self, other):
+ return self._rc(multiply(self.array,asarray(other)))
+ __rmul__ = __mul__
+ def __imul__(self, other):
+ multiply(self.array, other, self.array)
+ return self
+
+ def __div__(self, other):
+ return self._rc(divide(self.array,asarray(other)))
+ def __rdiv__(self, other):
+ return self._rc(divide(asarray(other),self.array))
+ def __idiv__(self, other):
+ divide(self.array, other, self.array)
+ return self
+
+ def __mod__(self, other):
+ return self._rc(remainder(self.array, other))
+ def __rmod__(self, other):
+ return self._rc(remainder(other, self.array))
+ def __imod__(self, other):
+ remainder(self.array, other, self.array)
+ return self
+
+ def __divmod__(self, other):
+ return (self._rc(divide(self.array,other)),
+ self._rc(remainder(self.array, other)))
+ def __rdivmod__(self, other):
+ return (self._rc(divide(other, self.array)),
+ self._rc(remainder(other, self.array)))
+
+ def __pow__(self,other):
+ return self._rc(power(self.array,asarray(other)))
+ def __rpow__(self,other):
+ return self._rc(power(asarray(other),self.array))
+ def __ipow__(self,other):
+ power(self.array, other, self.array)
+ return self
+
+ def __lshift__(self,other):
+ return self._rc(left_shift(self.array, other))
+ def __rshift__(self,other):
+ return self._rc(right_shift(self.array, other))
+ def __rlshift__(self,other):
+ return self._rc(left_shift(other, self.array))
+ def __rrshift__(self,other):
+ return self._rc(right_shift(other, self.array))
+ def __ilshift__(self,other):
+ left_shift(self.array, other, self.array)
+ return self
+ def __irshift__(self,other):
+ right_shift(self.array, other, self.array)
+ return self
+
+ def __and__(self, other):
+ return self._rc(bitwise_and(self.array, other))
+ def __rand__(self, other):
+ return self._rc(bitwise_and(other, self.array))
+ def __iand__(self, other):
+ bitwise_and(self.array, other, self.array)
+ return self
+
+ def __xor__(self, other):
+ return self._rc(bitwise_xor(self.array, other))
+ def __rxor__(self, other):
+ return self._rc(bitwise_xor(other, self.array))
+ def __ixor__(self, other):
+ bitwise_xor(self.array, other, self.array)
+ return self
+
+ def __or__(self, other):
+ return self._rc(bitwise_or(self.array, other))
+ def __ror__(self, other):
+ return self._rc(bitwise_or(other, self.array))
+ def __ior__(self, other):
+ bitwise_or(self.array, other, self.array)
+ return self
+
+ def __neg__(self):
+ return self._rc(-self.array)
+ def __pos__(self):
+ return self._rc(self.array)
+ def __abs__(self):
+ return self._rc(abs(self.array))
+ def __invert__(self):
+ return self._rc(invert(self.array))
+
+ def _scalarfunc(a, func):
+ if len(a.shape) == 0:
+ return func(a[0])
+ else:
+ raise TypeError, "only rank-0 arrays can be converted to Python scalars."
+
+ def __complex__(self): return self._scalarfunc(complex)
+ def __float__(self): return self._scalarfunc(float)
+ def __int__(self): return self._scalarfunc(int)
+ def __long__(self): return self._scalarfunc(long)
+ def __hex__(self): return self._scalarfunc(hex)
+ def __oct__(self): return self._scalarfunc(oct)
+
+ def __lt__(self,other): return self._rc(less(self.array,other))
+ def __le__(self,other): return self._rc(less_equal(self.array,other))
+ def __eq__(self,other): return self._rc(equal(self.array,other))
+ def __ne__(self,other): return self._rc(not_equal(self.array,other))
+ def __gt__(self,other): return self._rc(greater(self.array,other))
+ def __ge__(self,other): return self._rc(greater_equal(self.array,other))
+
+ def copy(self): return self._rc(self.array.copy())
+
+ def tostring(self): return self.array.tostring()
+
+ def byteswap(self): return self._rc(self.array.byteswap())
+
+ def astype(self, typecode): return self._rc(self.array.astype(typecode))
+
+ def _rc(self, a):
+ if len(shape(a)) == 0: return a
+ else: return self.__class__(a)
+
+ def __array_wrap__(self, *args):
+ return self.__class__(args[0])
+
+ def __setattr__(self,attr,value):
+ if attr == 'array':
+ object.__setattr__(self, attr, value)
+ return
+ try:
+ self.array.__setattr__(attr, value)
+ except AttributeError:
+ object.__setattr__(self, attr, value)
+
+ # Only called after other approaches fail.
+ def __getattr__(self,attr):
+ return self.array.__getattribute__(attr)
+
+#############################################################
+# Test of class UserArray
+#############################################################
+if __name__ == '__main__':
+ import numpy
+
+ temp=reshape(arange(10000),(100,100))
+
+ ua=UserArray(temp)
+ # new object created begin test
+ print dir(ua)
+ print shape(ua),ua.shape # I have changed Numeric.py
+
+ ua_small=ua[:3,:5]
+ print ua_small
+ ua_small[0,0]=10 # this did not change ua[0,0], which is not normal behavior
+ print ua_small[0,0],ua[0,0]
+ print sin(ua_small)/3.*6.+sqrt(ua_small**2)
+ print less(ua_small,103),type(less(ua_small,103))
+ print type(ua_small*reshape(arange(15),shape(ua_small)))
+ print reshape(ua_small,(5,3))
+ print transpose(ua_small)
diff --git a/numpy/lib/__init__.py b/numpy/lib/__init__.py
index 8b470d07f..a7de2e13f 100644
--- a/numpy/lib/__init__.py
+++ b/numpy/lib/__init__.py
@@ -30,5 +30,6 @@ __all__ += getlimits.__all__
__all__ += utils.__all__
__all__ += arraysetops.__all__
-from numpy.testing import ScipyTest
-test = ScipyTest().test
+def test(level=1, verbosity=1):
+ from numpy.testing import NumpyTest
+ return NumpyTest().test(level, verbosity)
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index cee17b0aa..e44e37027 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -11,7 +11,6 @@ __all__ = ['logspace', 'linspace',
]
import types
-import math
import numpy.core.numeric as _nx
from numpy.core.numeric import ones, zeros, arange, concatenate, array, \
asarray, empty, empty_like, asanyarray
@@ -210,7 +209,7 @@ def piecewise(x, condlist, funclist, *args, **kw):
if n == n2-1: # compute the "otherwise" condition.
totlist = condlist[0]
for k in range(1, n):
- totlist |= condlist
+ totlist |= condlist[k]
condlist.append(~totlist)
n += 1
if (n != n2):
diff --git a/numpy/lib/getlimits.py b/numpy/lib/getlimits.py
index 921baebe2..776e2550c 100644
--- a/numpy/lib/getlimits.py
+++ b/numpy/lib/getlimits.py
@@ -75,13 +75,15 @@ class finfo(object):
else:
raise ValueError,`dtype`
- for word in ['tiny', 'precision', 'resolution','iexp',
- 'maxexp','minexp','epsneg','negep',
+ for word in ['precision', 'iexp',
+ 'maxexp','minexp','negep',
'machep']:
setattr(self,word,getattr(machar, word))
- self.max = machar.huge
+ for word in ['tiny','resolution','epsneg']:
+ setattr(self,word,getattr(machar, word).squeeze())
+ self.max = machar.huge.squeeze()
self.min = -self.max
- self.eps = machar.epsilon
+ self.eps = machar.epsilon.squeeze()
self.nexp = machar.iexp
self.nmant = machar.it
self.machar = machar
diff --git a/numpy/lib/index_tricks.py b/numpy/lib/index_tricks.py
index 899fd5f47..15aae9949 100644
--- a/numpy/lib/index_tricks.py
+++ b/numpy/lib/index_tricks.py
@@ -223,24 +223,35 @@ class concatenator(object):
def __len__(self):
return 0
-r_=concatenator(0)
-r_.__doc__ = """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])
-"""
-c_=concatenator(-1)
-c_.__doc__ = """Translates slice objects to concatenation along the second axis.
-
- For example:
- >>> c_[array([[1],[2],[3]]), array([[4],[5],[6]])]
- array([[1, 4],
- [2, 5],
- [3, 6]])
-"""
-#row = concatenator(0,1)
-#col = concatenator(-1,1)
+# separate classes are used here instead of just making r_ = concatentor(0),
+# etc. because otherwise we couldn't get the doc string to come out right
+# in help(r_)
+
+class r_class(concatenator):
+ """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])
+ """
+ def __init__(self):
+ concatenator.__init__(self, 0)
+
+r_ = r_class()
+
+class c_class(concatenator):
+ """Translates slice objects to concatenation along the second axis.
+
+ For example:
+ >>> c_[array([[1],[2],[3]]), array([[4],[5],[6]])]
+ array([[1, 4],
+ [2, 5],
+ [3, 6]])
+ """
+ def __init__(self):
+ concatenator.__init__(self, -1)
+
+c_ = c_class()
class ndenumerate(object):
diff --git a/numpy/lib/polynomial.py b/numpy/lib/polynomial.py
index 5bd393cd5..c0c7c2229 100644
--- a/numpy/lib/polynomial.py
+++ b/numpy/lib/polynomial.py
@@ -493,6 +493,12 @@ class poly1d(object):
other = poly1d(other)
return polydiv(other, self)
+ def __eq__(self, other):
+ return (self.coeffs == other.coeffs).all()
+
+ def __ne__(self, other):
+ return (self.coeffs != other.coeffs).any()
+
def __setattr__(self, key, val):
raise ValueError, "Attributes cannot be changed this way."
diff --git a/numpy/lib/shape_base.py b/numpy/lib/shape_base.py
index 74d763821..cbcfa9e70 100644
--- a/numpy/lib/shape_base.py
+++ b/numpy/lib/shape_base.py
@@ -1,11 +1,11 @@
__all__ = ['atleast_1d','atleast_2d','atleast_3d','vstack','hstack',
'column_stack','dstack','array_split','split','hsplit',
'vsplit','dsplit','apply_over_axes','expand_dims',
- 'apply_along_axis']
+ 'apply_along_axis', 'repmat', 'kron']
import numpy.core.numeric as _nx
from numpy.core.numeric import *
-from numpy.core.oldnumeric import product
+from numpy.core.oldnumeric import product, reshape
def apply_along_axis(func1d,axis,arr,*args):
""" Execute func1d(arr[i],*args) where func1d takes 1-D arrays
@@ -525,3 +525,36 @@ def dsplit(ary,indices_or_sections):
raise ValueError, 'vsplit only works on arrays of 3 or more dimensions'
return split(ary,indices_or_sections,2)
+# should figure out how to generalize this one.
+def repmat(a, m, n):
+ """Repeat a 0-d to 2-d array mxn times
+ """
+ a = asarray(a)
+ ndim = a.ndim
+ if ndim == 0:
+ origrows, origcols = (1,1)
+ elif ndim == 1:
+ origrows, origcols = (1, a.shape[0])
+ else:
+ origrows, origcols = a.shape
+ rows = origrows * m
+ cols = origcols * n
+ c = a.reshape(1,a.size).repeat(m, 0).reshape(rows, origcols).repeat(n,0)
+ return c.reshape(rows, cols)
+
+
+def kron(a,b):
+ """kronecker product of a and b
+
+ Kronecker product of two matrices is block matrix
+ [[ a[ 0 ,0]*b, a[ 0 ,1]*b, ... , a[ 0 ,n-1]*b ],
+ [ ... ... ],
+ [ a[m-1,0]*b, a[m-1,1]*b, ... , a[m-1,n-1]*b ]]
+ """
+ if not a.flags.contiguous:
+ a = reshape(a, a.shape)
+ if not b.flags.contiguous:
+ b = reshape(b, b.shape)
+ o = outerproduct(a,b)
+ o=o.reshape(a.shape + b.shape)
+ return concatenate(concatenate(o, axis=1), axis=1)
diff --git a/numpy/lib/twodim_base.py b/numpy/lib/twodim_base.py
index 5b4574089..39a908268 100644
--- a/numpy/lib/twodim_base.py
+++ b/numpy/lib/twodim_base.py
@@ -12,7 +12,7 @@ def fliplr(m):
""" returns an array m with the rows preserved and columns flipped
in the left/right direction. Works on the first two dimensions of m.
"""
- m = asarray(m)
+ m = asanyarray(m)
if m.ndim < 2:
raise ValueError, "Input must be >= 2-d."
return m[:, ::-1]
@@ -21,17 +21,17 @@ def flipud(m):
""" returns an array with the columns preserved and rows flipped in
the up/down direction. Works on the first dimension of m.
"""
- m = asarray(m)
+ m = asanyarray(m)
if m.ndim < 1:
raise ValueError, "Input must be >= 1-d."
- return m[::-1]
+ return m[::-1,...]
def rot90(m, k=1):
""" returns the array found by rotating m by k*90
degrees in the counterclockwise direction. Works on the first two
dimensions of m.
"""
- m = asarray(m)
+ m = asanyarray(m)
if m.ndim < 2:
raise ValueError, "Input must >= 2-d."
k = k % 4
@@ -92,7 +92,7 @@ def tril(m, k=0):
""" returns the elements on and below the k-th diagonal of m. k=0 is the
main diagonal, k > 0 is above and k < 0 is below the main diagonal.
"""
- m = asarray(m)
+ m = asanyarray(m)
out = multiply(tri(m.shape[0], m.shape[1], k=k, dtype=m.dtype),m)
return out
@@ -100,11 +100,10 @@ def triu(m, k=0):
""" returns the elements on and above the k-th diagonal of m. k=0 is the
main diagonal, k > 0 is above and k < 0 is below the main diagonal.
"""
- m = asarray(m)
+ m = asanyarray(m)
out = multiply((1-tri(m.shape[0], m.shape[1], k-1, m.dtype)),m)
return out
-
# borrowed from John Hunter and matplotlib
def vander(x, N=None):
"""
diff --git a/numpy/linalg/__init__.py b/numpy/linalg/__init__.py
index 42df37663..287b3959e 100644
--- a/numpy/linalg/__init__.py
+++ b/numpy/linalg/__init__.py
@@ -3,5 +3,6 @@ from info import __doc__
from linalg import *
-from numpy.testing import ScipyTest
-test = ScipyTest().test
+def test(level=1, verbosity=1):
+ from numpy.testing import NumpyTest
+ return NumpyTest().test(level, verbosity)
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
index abb65be18..58bc9fbff 100644
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -1,6 +1,7 @@
-"""Lite version of numpy.linalg.
+
+"""Lite version of scipy.linalg.
"""
-# This module is a lite version of LinAlg.py module which contains
+# This module is a lite version of the linalg.py module in SciPy which contains
# high-level Python interface to the LAPACK library. The lite version
# only accesses the following LAPACK functions: dgesv, zgesv, dgeev,
# zgeev, dgesdd, zgesdd, dgelsd, zgelsd, dsyevd, zheevd, dgetrf, dpotrf.
@@ -9,12 +10,12 @@ __all__ = ['LinAlgError', 'solve_linear_equations', 'solve',
'inverse', 'inv', 'cholesky_decomposition', 'cholesky', 'eigenvalues',
'eigvals', 'Heigenvalues', 'eigvalsh', 'generalized_inverse', 'pinv',
'determinant', 'det', 'singular_value_decomposition', 'svd',
- 'eigenvectors', 'eig', 'Heigenvectors', 'eigh','lstsq', 'linear_least_squares'
+ 'eigenvectors', 'eig', 'Heigenvectors', 'eigh','lstsq',
+ 'linear_least_squares'
]
-from numpy import *
+from numpy.core import *
import lapack_lite
-import math
# Error object
class LinAlgError(Exception):
@@ -27,6 +28,11 @@ _array_kind = {'i':0, 'l': 0, 'f': 0, 'd': 0, 'F': 1, 'D': 1}
_array_precision = {'i': 1, 'l': 1, 'f': 0, 'd': 1, 'F': 0, 'D': 1}
_array_type = [['f', 'd'], ['F', 'D']]
+def _makearray(a):
+ new = asarray(a)
+ wrap = getattr(a, "__array_wrap__", new.__array_wrap__)
+ return new, wrap
+
def _commonType(*arrays):
kind = 0
# precision = 0
@@ -227,11 +233,10 @@ def eig(a):
v is a matrix of eigenvectors with vector v[:,i] corresponds to
eigenvalue u[i]. Satisfies the equation dot(a, v[:,i]) = u[i]*v[:,i]
"""
- a = asarray(a)
+ a, wrap = _makearray(a)
_assertRank2(a)
_assertSquareness(a)
a,t = _convertarray(a) # convert to float_ or complex_ type
- wrap = a.__array_wrap__
real_t = 'd'
n = a.shape[0]
dummy = zeros((1,), t)
@@ -281,12 +286,12 @@ eigenvalue u[i]. Satisfies the equation dot(a, v[:,i]) = u[i]*v[:,i]
def eigh(a, UPLO='L'):
+ a, wrap = _makearray(a)
_assertRank2(a)
_assertSquareness(a)
t =_commonType(a)
real_t = _array_type[0][_array_precision[t]]
a = _castCopyAndTranspose(t, a)
- wrap = a.__array_wrap__
n = a.shape[0]
liwork = 5*n+3
iwork = zeros((liwork,),'i')
@@ -319,14 +324,13 @@ def eigh(a, UPLO='L'):
# Singular value decomposition
-def svd(a, full_matrices = 1):
+def svd(a, full_matrices=1):
+ a, wrap = _makearray(a)
_assertRank2(a)
- n = a.shape[1]
- m = a.shape[0]
+ m, n = a.shape
t =_commonType(a)
real_t = _array_type[0][_array_precision[t]]
a = _fastCopyAndTranspose(t, a)
- wrap = a.__array_wrap__
if full_matrices:
nu = m
nvt = n
@@ -369,7 +373,7 @@ def svd(a, full_matrices = 1):
# Generalized inverse
def generalized_inverse(a, rcond = 1.e-10):
- a = array(a, copy=0)
+ a, wrap = _makearray(a)
if a.dtype.char in typecodes['Complex']:
a = conjugate(a)
u, s, vt = svd(a, 0)
@@ -381,13 +385,13 @@ def generalized_inverse(a, rcond = 1.e-10):
s[i] = 1./s[i]
else:
s[i] = 0.;
- wrap = a.__array_wrap__
return wrap(dot(transpose(vt),
multiply(s[:, NewAxis],transpose(u))))
# Determinant
def determinant(a):
+ a = asarray(a)
_assertRank2(a)
_assertSquareness(a)
t =_commonType(a)
@@ -418,8 +422,9 @@ the number of rows, then residuals will be returned as an empty array
otherwise resids = sum((b-dot(A,x)**2).
Singular values less than s[0]*rcond are treated as zero.
"""
+ import math
a = asarray(a)
- b = asarray(b)
+ b, wrap = _makearray(b)
one_eq = len(b.shape) == 1
if one_eq:
b = b[:, NewAxis]
@@ -477,10 +482,10 @@ Singular values less than s[0]*rcond are treated as zero.
x = transpose(bstar)[:n,:].copy()
if (results['rank']==n) and (m>n):
resids = sum((transpose(bstar)[n:,:])**2).copy()
- return x,resids,results['rank'],s[:min(n,m)].copy()
+ return wrap(x),resids,results['rank'],s[:min(n,m)].copy()
def singular_value_decomposition(A, full_matrices=0):
- return svd(A, 0)
+ return svd(A, full_matrices)
def eigenvectors(A):
w, v = eig(A)
diff --git a/numpy/random/__init__.py b/numpy/random/__init__.py
index 8dc354e81..13d0e3a22 100644
--- a/numpy/random/__init__.py
+++ b/numpy/random/__init__.py
@@ -13,5 +13,6 @@ def __RandomState_ctor():
"""
return RandomState()
-from numpy.testing import ScipyTest
-test = ScipyTest().test
+def test(level=1, verbosity=1):
+ from numpy.testing import NumpyTest
+ return NumpyTest().test(level, verbosity)
diff --git a/numpy/testing/info.py b/numpy/testing/info.py
index 9b5caa074..80dc00ddf 100644
--- a/numpy/testing/info.py
+++ b/numpy/testing/info.py
@@ -27,4 +27,4 @@ Utility functions
"""
-global_symbols = ['ScipyTest']
+global_symbols = ['ScipyTest','NumpyTest']
diff --git a/numpy/testing/numpytest.py b/numpy/testing/numpytest.py
index 127a5d3e2..4b43c428e 100644
--- a/numpy/testing/numpytest.py
+++ b/numpy/testing/numpytest.py
@@ -3,6 +3,7 @@ import os
import re
import sys
import imp
+import glob
import types
import unittest
import traceback
@@ -50,7 +51,7 @@ def set_package_path(level=1):
if not os.path.isdir(d1):
d1 = os.path.dirname(d)
if DEBUG:
- print 'Inserting %r to sys.path' % (d1)
+ print 'Inserting %r to sys.path for test_file %r' % (d1, testfile)
sys.path.insert(0,d1)
return
@@ -156,7 +157,8 @@ class NumpyTestCase (unittest.TestCase):
result.stream = save_stream
def warn(self, message):
- print>>sys.stderr,'Warning: %s' % (message)
+ from numpy.distutils.misc_util import yellow_text
+ print>>sys.stderr,yellow_text('Warning: %s' % (message))
sys.stderr.flush()
def info(self, message):
print>>sys.stdout, message
@@ -224,10 +226,30 @@ class NumpyTest:
"""
_check_testcase_name = re.compile(r'test.*').match
def check_testcase_name(self, name):
- return self._check_testcase_name(name) is not None
+ """ Return True if name matches TestCase class.
+ """
+ return not not self._check_testcase_name(name)
- def get_testfile(self, short_module_name):
- return 'test_' + short_module_name + '.py'
+ testfile_patterns = ['test_%(modulename)s.py']
+ def get_testfile(self, module, verbosity = 0):
+ """ Return path to module test file.
+ """
+ mstr = self._module_str
+ short_module_name = self._get_short_module_name(module)
+ d = os.path.split(module.__file__)[0]
+ test_dir = os.path.join(d,'tests')
+ local_test_dir = os.path.join(os.getcwd(),'tests')
+ if os.path.basename(os.path.dirname(local_test_dir)) \
+ == os.path.basename(os.path.dirname(test_dir)):
+ test_dir = local_test_dir
+ for pat in self.testfile_patterns:
+ fn = os.path.join(test_dir, pat % {'modulename':short_module_name})
+ if os.path.isfile(fn):
+ return fn
+ if verbosity>1:
+ self.warn('No test file found in %s for module %s' \
+ % (test_dir, mstr(module)))
+ return
def __init__(self, package=None):
if package is None:
@@ -276,29 +298,25 @@ class NumpyTest:
names.append(n)
return names
- def _get_module_tests(self,module,level,verbosity):
- mstr = self._module_str
+ def _get_short_module_name(self, module):
d,f = os.path.split(module.__file__)
-
short_module_name = os.path.splitext(os.path.basename(f))[0]
if short_module_name=='__init__':
short_module_name = module.__name__.split('.')[-1]
-
short_module_name = self._rename_map.get(short_module_name,short_module_name)
+ return short_module_name
+
+ def _get_module_tests(self,module,level,verbosity):
+ mstr = self._module_str
+
+ short_module_name = self._get_short_module_name(module)
if short_module_name is None:
return []
- full_module_name = module.__name__+'.'+short_module_name
- test_dir = os.path.join(d,'tests')
- fn = self.get_testfile(short_module_name)
- test_file = os.path.join(test_dir,fn)
+ test_file = self.get_testfile(module, verbosity)
- local_test_dir = os.path.join(os.getcwd(),'tests')
- local_test_file = os.path.join(local_test_dir, fn)
- if os.path.basename(os.path.dirname(local_test_dir)) \
- == os.path.basename(os.path.dirname(test_dir)) \
- and os.path.isfile(local_test_file):
- test_file = local_test_file
+ if test_file is None:
+ return []
if not os.path.isfile(test_file):
if short_module_name[:5]=='info_' \
@@ -317,22 +335,34 @@ class NumpyTest:
if test_file in self.test_files:
return []
-
+
+ parent_module_name = '.'.join(module.__name__.split('.')[:-1])
+ test_module_name,ext = os.path.splitext(os.path.basename(test_file))
+ test_dir_module = parent_module_name+'.tests'
+ test_module_name = test_dir_module+'.'+test_module_name
+
+ if not sys.modules.has_key(test_dir_module):
+ sys.modules[test_dir_module] = imp.new_module(test_dir_module)
+
+ old_sys_path = sys.path[:]
try:
f = open(test_file,'r')
- test_module = imp.load_module(full_module_name,
- f, test_file, ('.py', 'r', 1))
+ test_module = imp.load_module(test_module_name, f,
+ test_file, ('.py', 'r', 1))
f.close()
except:
- self.warn(' !! FAILURE importing tests for %s' % mstr(module))
+ sys.path[:] = old_sys_path
+ self.warn('FAILURE importing tests for %s' % (mstr(module)))
output_exception(sys.stderr)
return []
+ sys.path[:] = old_sys_path
self.test_files.append(test_file)
return self._get_suite_list(test_module, level, module.__name__)
- def _get_suite_list(self, test_module, level, module_name='__main__'):
+ def _get_suite_list(self, test_module, level, module_name='__main__',
+ verbosity=1):
mstr = self._module_str
suite_list = []
if hasattr(test_module,'test_suite'):
@@ -347,13 +377,28 @@ class NumpyTest:
suite = obj(mthname)
if getattr(suite,'isrunnable',lambda mthname:1)(mthname):
suite_list.append(suite)
- self.info(' Found %s tests for %s' % (len(suite_list),module_name))
+ if verbosity>=0:
+ self.info(' Found %s tests for %s' % (len(suite_list),module_name))
return suite_list
def test(self,level=1,verbosity=1):
""" Run Numpy module test suite with level and verbosity.
+
+ level:
+ None --- do nothing, return None
+ < 0 --- scan for tests of level=abs(level),
+ don't run them, return TestSuite-list
+ > 0 --- scan for tests of level, run them,
+ return TestRunner
+
+ verbosity:
+ >= 0 --- show information messages
+ > 1 --- show warnings on missing tests
"""
- if type(self.package) is type(''):
+ if level is None: # Do nothing.
+ return
+
+ if isinstance(self.package, str):
exec 'import %s as this_package' % (self.package)
else:
this_package = self.package
@@ -374,14 +419,15 @@ class NumpyTest:
self.test_files = []
suites = []
for module in modules:
- suites.extend(self._get_module_tests(module, level, verbosity))
+ suites.extend(self._get_module_tests(module, abs(level), verbosity))
- suites.extend(self._get_suite_list(sys.modules[package_name], level))
+ suites.extend(self._get_suite_list(sys.modules[package_name],
+ abs(level), verbosity=verbosity))
all_tests = unittest.TestSuite(suites)
- #if hasattr(sys,'getobjects'):
- # runner = SciPyTextTestRunner(verbosity=verbosity)
- #else:
+ if level<0:
+ return all_tests
+
runner = unittest.TextTestRunner(verbosity=verbosity)
# Use the builtin displayhook. If the tests are being run
# under IPython (for instance), any doctest test suites will
@@ -420,7 +466,8 @@ class NumpyTest:
return
def warn(self, message):
- print>>sys.stderr,'Warning: %s' % (message)
+ from numpy.distutils.misc_util import yellow_text
+ print>>sys.stderr,yellow_text('Warning: %s' % (message))
sys.stderr.flush()
def info(self, message):
print>>sys.stdout, message
diff --git a/numpy/testing/utils.py b/numpy/testing/utils.py
index 4ea19c270..fe3a3c093 100644
--- a/numpy/testing/utils.py
+++ b/numpy/testing/utils.py
@@ -4,8 +4,6 @@ Utility function to facilitate testing.
import os
import sys
-import time
-import math
__all__ = ['assert_equal', 'assert_almost_equal','assert_approx_equal',
'assert_array_equal', 'assert_array_less',
@@ -27,16 +25,19 @@ def rand(*args):
if sys.platform[:5]=='linux':
def jiffies(_proc_pid_stat = '/proc/%s/stat'%(os.getpid()),
- _load_time=time.time()):
+ _load_time=[]):
""" Return number of jiffies (1/100ths of a second) that this
process has been scheduled in user mode. See man 5 proc. """
+ import time
+ if not _load_time:
+ _load_time.append(time.time())
try:
f=open(_proc_pid_stat,'r')
l = f.readline().split(' ')
f.close()
return int(l[13])
except:
- return int(100*(time.time()-_load_time))
+ return int(100*(time.time()-_load_time[0]))
def memusage(_proc_pid_stat = '/proc/%s/stat'%(os.getpid())):
""" Return virtual memory size in bytes of the running python.
@@ -52,10 +53,13 @@ else:
# os.getpid is not in all platforms available.
# Using time is safe but inaccurate, especially when process
# was suspended or sleeping.
- def jiffies(_load_time=time.time()):
+ def jiffies(_load_time=[]):
""" Return number of jiffies (1/100ths of a second) that this
process has been scheduled in user mode. [Emulation with time.time]. """
- return int(100*(time.time()-_load_time))
+ import time
+ if not _load_time:
+ _load_time.append(time.time())
+ return int(100*(time.time()-_load_time[0]))
def memusage():
""" Return memory usage of running python. [Not implemented]"""
return
@@ -150,6 +154,7 @@ def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=1):
Approximately equal is defined as the number of significant digits
correct
"""
+ import math
msg = '\nItems are not equal to %d significant digits:\n' % significant
msg += err_msg
actual, desired = map(float, (actual, desired))