summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2005-12-14 22:03:04 +0000
committerTravis Oliphant <oliphant@enthought.com>2005-12-14 22:03:04 +0000
commit9985d7cc7892effbe9290002ef3613ea33e02179 (patch)
tree3b5cc3f0b3bb1094e420e3a705fa578d2ab006ec
parent9df62b0d2072bfa5809c21a4e181b3a186317422 (diff)
downloadnumpy-9985d7cc7892effbe9290002ef3613ea33e02179.tar.gz
Added newbyteorder methods.
-rw-r--r--scipy/base/chararray.py5
-rw-r--r--scipy/base/code_generators/array_api_order.txt1
-rw-r--r--scipy/base/code_generators/multiarray_api_order.txt1
-rw-r--r--scipy/base/include/scipy/arrayobject.h21
-rw-r--r--scipy/base/src/arraymethods.c22
-rw-r--r--scipy/base/src/arrayobject.c118
-rw-r--r--scipy/base/src/multiarraymodule.c33
-rw-r--r--scipy/base/src/scalartypes.inc.src14
-rw-r--r--scipy/core_version.py2
-rw-r--r--scipy/doc/CAPI.txt18
10 files changed, 198 insertions, 37 deletions
diff --git a/scipy/base/chararray.py b/scipy/base/chararray.py
index 58b874827..c7edcd4bd 100644
--- a/scipy/base/chararray.py
+++ b/scipy/base/chararray.py
@@ -1,6 +1,7 @@
from numerictypes import character, string, unicode_, \
obj2dtype, integer, object_
-from numeric import ndarray, broadcast, empty, array
+from numeric import ndarray, broadcast, empty
+from numeric import array as narray
import sys
__all__ = ['chararray']
@@ -316,7 +317,7 @@ def array(obj, itemlen=7, copy=True, unicode=False, fortran=False):
else:
dtype = "S%d" % itemlen
- val = array(obj, dtype=dtype, fortran=fortran, subok=1)
+ val = narray(obj, dtype=dtype, fortran=fortran, subok=1)
return chararray(val.shape, itemlen, unicode, buffer=val,
strides=val.strides,
diff --git a/scipy/base/code_generators/array_api_order.txt b/scipy/base/code_generators/array_api_order.txt
index c2750ace4..3dfd848a0 100644
--- a/scipy/base/code_generators/array_api_order.txt
+++ b/scipy/base/code_generators/array_api_order.txt
@@ -58,3 +58,4 @@ PyArray_Broadcast
PyArray_FillObjectArray
PyArray_FillWithScalar
PyArray_CheckStrides
+PyArray_DescrNewByteorder
diff --git a/scipy/base/code_generators/multiarray_api_order.txt b/scipy/base/code_generators/multiarray_api_order.txt
index e97dfbd27..65a313428 100644
--- a/scipy/base/code_generators/multiarray_api_order.txt
+++ b/scipy/base/code_generators/multiarray_api_order.txt
@@ -55,6 +55,7 @@ PyArray_IntpConverter
PyArray_BufferConverter
PyArray_AxisConverter
PyArray_BoolConverter
+PyArray_ByteorderConverter
PyArray_EquivalentTypes
PyArray_Zeros
PyArray_Empty
diff --git a/scipy/base/include/scipy/arrayobject.h b/scipy/base/include/scipy/arrayobject.h
index 5023631b0..348027689 100644
--- a/scipy/base/include/scipy/arrayobject.h
+++ b/scipy/base/include/scipy/arrayobject.h
@@ -1212,17 +1212,22 @@ typedef struct {
#define PyArray_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(PyArray_TYPE(obj))
#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj))
+#define PyArray_LITTLE '<'
+#define PyArray_BIG '>'
+#define PyArray_NATIVE '='
+#define PyArray_SWAP 's'
+#define PyArray_IGNORE '|'
+
#ifdef WORDS_BIGENDIAN
-#define PyArray_NATIVEBYTE '>'
-#define PyArray_OPPOSITEBYTE '<'
-#define PyArray_IsNativeByteOrder(byteorder) (byteorder != '<')
-#define PyArray_ISNBO(byteorder) (byteorder != '<')
+#define PyArray_NATBYTE PyArray_BIG
+#define PyArray_OPPBYTE PyArray_LITTLE
#else
-#define PyArray_NATIVEBYTE '<'
-#define PyArray_OPPOSITEBYTE '>'
-#define PyArray_IsNativeByteOrder(byteorder) (byteorder != '>')
-#define PyArray_ISNBO(byteorder) (byteorder != '>')
+#define PyArray_NATBYTE PyArray_LITTLE
+#define PyArray_OPPBYTE PyArray_BIG
#endif
+
+#define PyArray_ISNBO(arg) ((arg) != PyArray_OPPBYTE)
+#define PyArray_IsNativeByteOrder PyArray_ISNBO
#define PyArray_ISNOTSWAPPED(m) PyArray_ISNBO(PyArray_DESCR(m)->byteorder)
#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) && \
diff --git a/scipy/base/src/arraymethods.c b/scipy/base/src/arraymethods.c
index b9548de57..1b597baf1 100644
--- a/scipy/base/src/arraymethods.c
+++ b/scipy/base/src/arraymethods.c
@@ -921,7 +921,7 @@ static intp _array_fill_strides(intp *, intp *, int, intp, int, int *);
static int _IsAligned(PyArrayObject *);
-static PyArray_Descr * _array_typedescr_fromstr(char *, int *);
+static PyArray_Descr * _array_typedescr_fromstr(char *);
static PyObject *
array_setstate(PyArrayObject *self, PyObject *args)
@@ -1503,6 +1503,24 @@ array_setflags(PyArrayObject *self, PyObject *args, PyObject *kwds)
return Py_None;
}
+static char doc_newbyteorder[] = "a.newbyteorder(<byteorder>) is equivalent\n" \
+ " to a.view(a.dtypedescr.newbytorder(<byteorder>))\n";
+
+static PyObject *
+array_newbyteorder(PyArrayObject *self, PyObject *args)
+{
+ char endian = PyArray_SWAP;
+ PyArray_Descr *new;
+
+ if (!PyArg_ParseTuple(args, "|O&", PyArray_ByteorderConverter,
+ &endian)) return NULL;
+
+ new = PyArray_DescrNewByteorder(self->descr, endian);
+ if (!new) return NULL;
+ return _ARET(PyArray_View(self, new));
+
+}
+
static PyMethodDef array_methods[] = {
{"tolist", (PyCFunction)array_tolist, 1, doc_tolist},
{"toscalar", (PyCFunction)array_toscalar, METH_VARARGS, doc_toscalar},
@@ -1612,6 +1630,8 @@ static PyMethodDef array_methods[] = {
METH_VARARGS, doc_ravel},
{"setflags", (PyCFunction)array_setflags,
METH_VARARGS|METH_KEYWORDS, doc_setflags},
+ {"newbyteorder", (PyCFunction)array_newbyteorder,
+ METH_VARARGS, doc_newbyteorder},
{NULL, NULL} /* sentinel */
};
diff --git a/scipy/base/src/arrayobject.c b/scipy/base/src/arrayobject.c
index fce6fd215..24351bb8d 100644
--- a/scipy/base/src/arrayobject.c
+++ b/scipy/base/src/arrayobject.c
@@ -4879,8 +4879,7 @@ _array_find_type(PyObject *op, PyArray_Descr *minitype, int max)
if ((ip=PyObject_GetAttrString(op, "__array_typestr__"))!=NULL) {
if (PyString_Check(ip)) {
- chktype =_array_typedescr_fromstr \
- (PyString_AS_STRING(ip));
+ chktype =_array_typedescr_fromstr(PyString_AS_STRING(ip));
}
Py_DECREF(ip);
if (chktype) goto finish;
@@ -4890,13 +4889,12 @@ _array_find_type(PyObject *op, PyArray_Descr *minitype, int max)
if ((ip=PyObject_GetAttrString(op, "__array_struct__")) != NULL) {
PyArrayInterface *inter;
char buf[40];
- int swap=0;
if (PyCObject_Check(ip)) {
inter=(PyArrayInterface *)PyCObject_AsVoidPtr(ip);
if (inter->version == 2) {
snprintf(buf, 40, "|%c%d", inter->typekind,
inter->itemsize);
- chktype = _array_typedescr_fromstr(buf, &swap);
+ chktype = _array_typedescr_fromstr(buf);
}
}
Py_DECREF(ip);
@@ -5597,11 +5595,10 @@ static PyObject *
array_fromstructinterface(PyObject *input, PyArray_Descr *intype, int flags)
{
PyArray_Descr *thetype;
- int swap;
char buf[40];
PyArrayInterface *inter;
PyObject *attr, *r, *ret;
- char endian = PyArray_NATIVEBYTE;
+ char endian = PyArray_NATBYTE;
attr = PyObject_GetAttrString(input, "__array_struct__");
if (attr == NULL) {
@@ -5617,7 +5614,7 @@ array_fromstructinterface(PyObject *input, PyArray_Descr *intype, int flags)
return NULL;
}
if ((inter->flags & NOTSWAPPED) != NOTSWAPPED) {
- endian = PyArray_OPPOSITEBYTE;
+ endian = PyArray_OPPBYTE;
inter->flags &= ~NOTSWAPPED;
}
@@ -5653,7 +5650,6 @@ array_frominterface(PyObject *input, PyArray_Descr *intype, int flags)
int buffer_len;
int res, i, n;
intp dims[MAX_DIMS], strides[MAX_DIMS];
- int swap;
int dataflags = BEHAVED_FLAGS;
/* Get the memory from __array_data__ and __array_offset__ */
@@ -8123,12 +8119,118 @@ arraydescr_setstate(PyArray_Descr *self, PyObject *args)
}
+/* returns a copy of the PyArray_Descr structure with the byteorder
+ altered:
+ no arguments: The byteorder is swapped (in all subfields as well)
+ single argument: The byteorder is forced to the given state
+ (in all subfields as well)
+
+ Valid states: ('big', '>') or ('little' or '<')
+ ('native', or '=')
+
+ If a descr structure with | is encountered it's own
+ byte-order is not changed but any fields are:
+*/
+
+/*OBJECT_API
+ Deep bytorder change of a data-type descriptor
+*/
+static PyArray_Descr *
+PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian)
+{
+ PyArray_Descr *new;
+ char endian;
+
+ new = PyArray_DescrNew(self);
+ endian = new->byteorder;
+ if (endian != PyArray_IGNORE) {
+ if (newendian == PyArray_SWAP) { /* swap byteorder */
+ if PyArray_ISNBO(endian) endian = PyArray_OPPBYTE;
+ else endian = PyArray_NATBYTE;
+ new->byteorder = endian;
+ }
+ else if (newendian != PyArray_IGNORE) {
+ new->byteorder = newendian;
+ }
+ }
+ if (new->fields) {
+ PyObject *newfields;
+ PyObject *key, *value;
+ PyObject *newvalue;
+ PyObject *old;
+ PyArray_Descr *newdescr;
+ int pos = 0, len, i;
+ newfields = PyDict_New();
+ /* make new dictionary with replaced */
+ /* PyArray_Descr Objects */
+ while(PyDict_Next(self->fields, &pos, &key, &value)) {
+ if (PyInt_Check(key) && \
+ PyInt_AsLong(key) == -1) {
+ PyDict_SetItem(newfields, key, value);
+ continue;
+ }
+ if (!PyString_Check(key) || \
+ !PyTuple_Check(value) || \
+ ((len=PyTuple_GET_SIZE(value)) < 2))
+ continue;
+
+ old = PyTuple_GET_ITEM(value, 0);
+ if (!PyArray_DescrCheck(old)) continue;
+ newdescr = PyArray_DescrNewByteorder \
+ ((PyArray_Descr *)old, newendian);
+ if (newdescr == NULL) {
+ Py_DECREF(newfields); Py_DECREF(new);
+ return NULL;
+ }
+ newvalue = PyTuple_New(len);
+ PyTuple_SET_ITEM(newvalue, 0, \
+ (PyObject *)newdescr);
+ for(i=1; i<len; i++) {
+ old = PyTuple_GET_ITEM(value, i);
+ Py_INCREF(old);
+ PyTuple_SET_ITEM(newvalue, i, old);
+ }
+ PyDict_SetItem(newfields, key, newvalue);
+ Py_DECREF(newvalue);
+ }
+ Py_DECREF(new->fields);
+ new->fields = newfields;
+ }
+ if (new->subarray) {
+ Py_DECREF(new->subarray->base);
+ new->subarray->base = PyArray_DescrNewByteorder \
+ (self->subarray->base, newendian);
+ }
+ return new;
+}
+
+
+static char doc_arraydescr_newbyteorder[] = "self.newbyteorder(<endian>)"
+ " returns a copy of the dtypedescr object\n"
+ " with altered byteorders. If <endian> is not given all byteorders\n"
+ " are swapped. Otherwise endian can be '>', '<', or '=' to force\n"
+ " a byteorder. Descriptors in all fields are also updated in the\n"
+ " new dtypedescr object.";
+
+static PyObject *
+arraydescr_newbyteorder(PyArray_Descr *self, PyObject *args)
+{
+ char endian=PyArray_SWAP;
+
+ if (!PyArg_ParseTuple(args, "|O&", PyArray_ByteorderConverter,
+ &endian)) return NULL;
+
+ return (PyObject *)PyArray_DescrNewByteorder(self, endian);
+}
+
static PyMethodDef arraydescr_methods[] = {
/* for pickling */
{"__reduce__", (PyCFunction)arraydescr_reduce, METH_VARARGS,
doc_arraydescr_reduce},
{"__setstate__", (PyCFunction)arraydescr_setstate, METH_VARARGS,
doc_arraydescr_setstate},
+ {"newbyteorder", (PyCFunction)arraydescr_newbyteorder, METH_VARARGS,
+ doc_arraydescr_newbyteorder},
{NULL, NULL} /* sentinel */
};
diff --git a/scipy/base/src/multiarraymodule.c b/scipy/base/src/multiarraymodule.c
index bd4967371..fcdda0f72 100644
--- a/scipy/base/src/multiarraymodule.c
+++ b/scipy/base/src/multiarraymodule.c
@@ -3453,6 +3453,39 @@ PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at)
return PY_FAIL;
}
+/*MULTIARRAY_API
+ Convert object to endian
+*/
+static int
+PyArray_ByteorderConverter(PyObject *obj, char *endian)
+{
+ char *str;
+ *endian = PyArray_SWAP;
+ str = PyString_AsString(obj);
+ if (!str) return PY_FAIL;
+ if (strlen(str) < 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Byteorder string must be at least length 1");
+ return PY_FAIL;
+ }
+ *endian = str[0];
+ if (str[0] != PyArray_BIG && str[0] != PyArray_LITTLE && \
+ str[0] != PyArray_NATIVE) {
+ if (str[0] == 'b' || str[0] == 'B')
+ *endian = PyArray_BIG;
+ else if (str[0] == 'l' || str[0] == 'L')
+ *endian = PyArray_LITTLE;
+ else if (str[0] == 'n' || str[0] == 'N')
+ *endian = PyArray_NATIVE;
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "%s is an unrecognized byteorder",
+ str);
+ return PY_FAIL;
+ }
+ }
+ return PY_SUCCEED;
+}
/* This function returns true if the two typecodes are
equivalent (same basic kind and same itemsize).
diff --git a/scipy/base/src/scalartypes.inc.src b/scipy/base/src/scalartypes.inc.src
index ac5939450..b127617da 100644
--- a/scipy/base/src/scalartypes.inc.src
+++ b/scipy/base/src/scalartypes.inc.src
@@ -1032,7 +1032,7 @@ gentype_wraparray(PyObject *scalar, PyObject *args)
/**begin repeat
-#name=tolist, toscalar, tostring, astype, copy, resize, __deepcopy__, choose, sort, argsort, searchsorted, argmax, argmin, reshape, view, swapaxes, max, min, ptp, conj, conjugate, nonzero, all, any, flatten, ravel, fill, transpose#
+#name=tolist, toscalar, tostring, astype, copy, resize, __deepcopy__, choose, sort, argsort, searchsorted, argmax, argmin, reshape, view, swapaxes, max, min, ptp, conj, conjugate, nonzero, all, any, flatten, ravel, fill, transpose, newbyteorder#
*/
static PyObject *
@@ -1102,17 +1102,16 @@ gentype_@name@(PyObject *self, PyObject *args, PyObject *kwds)
/**end repeat**/
static PyObject *
-voidtype_getfield(PyObject *self, PyObject *args, PyObject *kwds)
+voidtype_getfield(PyVoidScalarObject *self, PyObject *args, PyObject *kwds)
{
PyObject *ret;
- ret = gentype_generic_method(self, args, kwds, "getfield");
+ ret = gentype_generic_method((PyObject *)self, args, kwds, "getfield");
if (!ret) return ret;
if (PyArray_IsScalar(ret, Generic) && \
(!PyArray_IsScalar(ret, Void))) {
- PyArray_Descr *descr, *new;
- descr = ((PyVoidScalarObject *)self)->descr;
- if (!PyArray_ISNBO(descr->byteorder)) {
+ PyArray_Descr *new;
+ if (!PyArray_ISNBO(self->descr->byteorder)) {
new = PyArray_DescrFromScalar(ret);
new->f->copyswap(_SOFFSET_(ret,
new->type_num),
@@ -1361,7 +1360,8 @@ static PyMethodDef gentype_methods[] = {
METH_VARARGS, NULL},
{"setflags", (PyCFunction)gentype_setflags,
METH_VARARGS|METH_KEYWORDS, NULL},
- /* add other methods!!! */
+ {"newbyteorder", (PyCFunction)gentype_newbyteorder,
+ METH_VARARGS, NULL},
{NULL, NULL} /* sentinel */
};
diff --git a/scipy/core_version.py b/scipy/core_version.py
index 3a1f3887a..754a70e6a 100644
--- a/scipy/core_version.py
+++ b/scipy/core_version.py
@@ -1,4 +1,4 @@
-version='0.8.5'
+version='0.8.6'
import os
svn_version_file = os.path.join(os.path.dirname(__file__),
diff --git a/scipy/doc/CAPI.txt b/scipy/doc/CAPI.txt
index 1142ce7e2..f8bfd3981 100644
--- a/scipy/doc/CAPI.txt
+++ b/scipy/doc/CAPI.txt
@@ -164,7 +164,6 @@ requires can be any of
CONTIGUOUS,
FORTRAN,
ALIGNED,
- NOTSWAPPED,
WRITEABLE,
ENSURECOPY,
ENSUREARRAY,
@@ -178,11 +177,11 @@ requires can be any of
won't guarantee it -- it will depend on the object as to whether or
not it has such features.
- Note that ENSURECOPY is enough to guarantee CONTIGUOUS, ALIGNED, NOTSWAPPED,
+ Note that ENSURECOPY is enough to guarantee CONTIGUOUS, ALIGNED,
and WRITEABLE and therefore it is redundant to include those as well.
- BEHAVED_FLAGS == ALIGNED | NOTSWAPPED | WRITEABLE
- BEHAVED_FLAGS_RO == ALIGNED | NOTSWAPPED
+ BEHAVED_FLAGS == ALIGNED | WRITEABLE
+ BEHAVED_FLAGS_RO == ALIGNED
CARRAY_FLAGS = CONTIGUOUS | BEHAVED_FLAGS
FARRAY_FLAGS = FORTRAN | BEHAVED_FLAGS
@@ -276,9 +275,6 @@ array, or part of some larger record array. But, they may have other uses...
ALIGNED : True if the data buffer is aligned for the type. This
can be checked.
-NOTSWAPPED : True if the data is in machine byte order. Arrays
- can be out of machine byte order and will still
- work (albeit more slowly).
WRITEABLE : True only if the data buffer can be "written" to.
@@ -302,16 +298,18 @@ PyArray_UpdateFlags(obj, FLAGS) will update the obj->flags for FLAGS
Some useful combinations of these flags:
-BEHAVED = ALIGNED | NOTSWAPPED | WRITEABLE
-BEHAVED_RO = ALIGNED | NOTSWAPPED
+BEHAVED = ALIGNED | WRITEABLE
+BEHAVED_RO = ALIGNED
CARRAY_FLAGS = CONTIGUOUS | BEHAVED
FARRAY_FLAGS = FORTRAN | BEHAVED
-
The macro PyArray_CHECKFLAGS(obj, FLAGS) can test any combination of flags.
There are several default combinations defined as macros already
(see arrayobject.h)
+In particular, there are ISBEHAVED, ISBEHAVED_RO, ISCARRAY and ISFARRAY macros
+that also check to make sure the array is in native byte order (as determined)
+by the data-type descriptor.
There are more C-API enhancements which you can discover in the code,
or buy the book (http://www.trelgol.com)