summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2006-06-23 20:09:55 +0000
committerTravis Oliphant <oliphant@enthought.com>2006-06-23 20:09:55 +0000
commit7dd0e2b1bffc4fed6ff4e4ac6160e3f5a714c784 (patch)
tree8d126a60dc28f869e85a10505e93d9de105ceb70
parent696518364d950c63fc64ab026200c172b05342ee (diff)
downloadnumpy-7dd0e2b1bffc4fed6ff4e4ac6160e3f5a714c784.tar.gz
Clean up diag documentation. Clean up PyArray_INCREF and PyArray_XDECREF to use new iterators.
-rw-r--r--numpy/core/src/arrayobject.c262
-rw-r--r--numpy/lib/twodim_base.py5
2 files changed, 96 insertions, 171 deletions
diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c
index a4eca38b6..d19cebe7b 100644
--- a/numpy/core/src/arrayobject.c
+++ b/numpy/core/src/arrayobject.c
@@ -131,153 +131,6 @@ PyArray_One(PyArrayObject *arr)
/* End deprecated */
-static int
-do_sliced_copy(char *dest, intp *dest_strides, intp *dest_dimensions,
- int dest_nd, char *src, intp *src_strides,
- intp *src_dimensions, int src_nd, int elsize,
- int copies) {
- intp i, j;
-
- if (src_nd == 0 && dest_nd == 0) {
- for(j=0; j<copies; j++) {
- memmove(dest, src, elsize);
- dest += elsize;
- }
- return 0;
- }
-
- if (dest_nd > src_nd) {
- for(i=0; i<*dest_dimensions; i++, dest += *dest_strides) {
- if (do_sliced_copy(dest, dest_strides+1,
- dest_dimensions+1, dest_nd-1,
- src, src_strides,
- src_dimensions, src_nd,
- elsize, copies) == -1)
- return -1;
- }
- return 0;
- }
-
- if (dest_nd == 1) {
- if (*dest_dimensions != *src_dimensions) {
- PyErr_SetString(PyExc_ValueError,
- "matrices are not aligned for copy");
- return -1;
- }
- for(i=0; i<*dest_dimensions; i++, src += *src_strides) {
- for(j=0; j<copies; j++) {
- memmove(dest, src, elsize);
- dest += *dest_strides;
- }
- }
- } else {
- for(i=0; i<*dest_dimensions; i++, dest += *dest_strides,
- src += *src_strides) {
- if (do_sliced_copy(dest, dest_strides+1,
- dest_dimensions+1, dest_nd-1,
- src, src_strides+1,
- src_dimensions+1, src_nd-1,
- elsize, copies) == -1)
- return -1;
- }
- }
- return 0;
-}
-
-/* This function reduces a source and destination array until a
- discontiguous segment is found in either the source or
- destination. Thus, an N dimensional array where the last dimension
- is contiguous and has size n while the items are of size elsize,
- will be reduced to an N-1 dimensional array with items of size n *
- elsize.
-
- This process is repeated until a discontiguous section is found.
- Thus, a contiguous array will be reduced to a 0-dimensional array
- with items of size elsize * sizeof(N-dimensional array).
-
- Finally, if a source array has been reduced to a 0-dimensional
- array with large element sizes, the contiguous destination array is
- reduced as well.
-
- The only thing this function changes is the element size, the
- number of copies, and the source and destination number of
- dimensions. The strides and dimensions are not changed.
-*/
-
-static int
-optimize_slices(intp **dest_strides, intp **dest_dimensions,
- int *dest_nd, intp **src_strides,
- intp **src_dimensions, int *src_nd,
- int *elsize, int *copies)
-{
- while (*src_nd > 0) {
- if (((*dest_strides)[*dest_nd-1] == *elsize) &&
- ((*src_strides)[*src_nd-1] == *elsize)) {
- if ((*dest_dimensions)[*dest_nd-1] !=
- (*src_dimensions)[*src_nd-1]) {
- PyErr_SetString(PyExc_ValueError,
- "matrices are not aligned");
- return -1;
- }
- *elsize *= (*dest_dimensions)[*dest_nd-1];
- *dest_nd-=1; *src_nd-=1;
- } else {
- break;
- }
- }
- if (*src_nd == 0) {
- while (*dest_nd > 0) {
- if (((*dest_strides)[*dest_nd-1] == *elsize)) {
- *copies *= (*dest_dimensions)[*dest_nd-1];
- *dest_nd-=1;
- } else {
- break;
- }
- }
- }
- return 0;
-}
-
-static char *
-contiguous_data(PyArrayObject *src)
-{
- intp dest_strides[MAX_DIMS], *dest_strides_ptr;
- intp *dest_dimensions=src->dimensions;
- int dest_nd=src->nd;
- intp *src_strides = src->strides;
- intp *src_dimensions=src->dimensions;
- int src_nd=src->nd;
- int elsize=src->descr->elsize;
- int copies=1;
- int ret, i;
- intp stride=elsize;
- char *new_data;
-
- for(i=dest_nd-1; i>=0; i--) {
- dest_strides[i] = stride;
- stride *= dest_dimensions[i];
- }
-
- dest_strides_ptr = dest_strides;
-
- if (optimize_slices(&dest_strides_ptr, &dest_dimensions, &dest_nd,
- &src_strides, &src_dimensions, &src_nd,
- &elsize, &copies) == -1)
- return NULL;
-
- new_data = (char *)_pya_malloc(stride);
-
- ret = do_sliced_copy(new_data, dest_strides_ptr, dest_dimensions,
- dest_nd, src->data, src_strides,
- src_dimensions, src_nd, elsize, copies);
-
- if (ret != -1) { return new_data; }
- else { _pya_free(new_data); return NULL; }
-}
-
-/* end Helper functions */
-
-
static PyObject *PyArray_New(PyTypeObject *, int nd, intp *,
int, intp *, void *, int, int, PyObject *);
@@ -295,48 +148,119 @@ PyArray_INCREF(PyArrayObject *mp)
PyObject **data, **data2;
- if (mp->descr->type_num != PyArray_OBJECT) return 0;
+ if (mp->descr->hasobject == 0) return 0;
+
+ if (mp->descr->type_num != PyArray_OBJECT) return -1;
+ /* return _incref_rec_wobject(mp); */
if (PyArray_ISONESEGMENT(mp)) {
data = (PyObject **)mp->data;
+ n = PyArray_SIZE(mp);
+ if (PyArray_ISALIGNED(mp)) {
+ for(i=0; i<n; i++, data++) Py_INCREF(*data);
+ }
+ else {
+ PyObject **temp;
+ for (i=0; i<n; i++, data++) {
+ memcpy(temp, data, sizeof(void *));
+ Py_INCREF(*temp);
+ }
+ }
} else {
- if ((data = (PyObject **)contiguous_data(mp)) == NULL)
- return -1;
+ PyArrayIterObject *it;
+ int maxaxis=-1;
+ intp stride;
+ it = (PyArrayIterObject *)\
+ PyArray_IterAllButAxis((PyObject *)mp, &maxaxis);
+ if (it == NULL) return -1;
+ n = mp->dimensions[maxaxis];
+ stride = mp->strides[maxaxis] / sizeof(PyObject **);
+ if (PyArray_ISALIGNED(mp)) {
+ while(it->index < it->size) {
+ data = (PyObject **)(it->dataptr);
+ for (i=0; i<n; i++) {
+ Py_INCREF(*data);
+ data += stride;
+ }
+ PyArray_ITER_NEXT(it);
+ }
+ }
+ else {
+ PyObject **temp;
+ while(it->index < it->size) {
+ data = (PyObject **)(it->dataptr);
+ for (i=0; i<n; i++) {
+ memcpy(temp, data, sizeof(void *));
+ Py_INCREF(*temp);
+ data += stride;
+ }
+ PyArray_ITER_NEXT(it);
+ }
+ }
}
-
- n = PyArray_SIZE(mp);
- data2 = data;
- for(i=0; i<n; i++, data++) Py_XINCREF(*data);
-
- if (!PyArray_ISONESEGMENT(mp)) _pya_free(data2);
-
return 0;
}
/*OBJECT_API
Decrement all internal references for object arrays.
+ (or arrays with object fields)
*/
static int
PyArray_XDECREF(PyArrayObject *mp)
{
intp i, n;
- PyObject **data, **data2;
-
- if (mp->descr->type_num != PyArray_OBJECT) return 0;
+ PyObject **data;
+ if (mp->descr->hasobject == 0) return 0;
+
+ if (mp->descr->type_num != PyArray_OBJECT) return -1;
+ /* return _xdecref_rec_wobject(mp); */
+
if (PyArray_ISONESEGMENT(mp)) {
data = (PyObject **)mp->data;
+ n = PyArray_SIZE(mp);
+ if (PyArray_ISALIGNED(mp)) {
+ for(i=0; i<n; i++, data++) Py_XDECREF(*data);
+ }
+ else {
+ PyObject **temp;
+ for (i=0; i<n; i++, data++) {
+ memcpy(temp, data, sizeof(void *));
+ Py_XDECREF(*temp);
+ }
+ }
} else {
- if ((data = (PyObject **)contiguous_data(mp)) == NULL)
- return -1;
+ PyArrayIterObject *it;
+ int maxaxis=-1;
+ intp stride;
+ it = (PyArrayIterObject *)\
+ PyArray_IterAllButAxis((PyObject *)mp, &maxaxis);
+ if (it == NULL) return -1;
+ n = mp->dimensions[maxaxis];
+ stride = mp->strides[maxaxis] / sizeof(PyObject **);
+ if (PyArray_ISALIGNED(mp)) {
+ while(it->index < it->size) {
+ data = (PyObject **)(it->dataptr);
+ for (i=0; i<n; i++) {
+ Py_XDECREF(*data);
+ data += stride;
+ }
+ PyArray_ITER_NEXT(it);
+ }
+ }
+ else {
+ PyObject **temp;
+ while(it->index < it->size) {
+ data = (PyObject **)(it->dataptr);
+ for (i=0; i<n; i++) {
+ memcpy(temp, data, sizeof(void *));
+ Py_XDECREF(*temp);
+ data += stride;
+ }
+ PyArray_ITER_NEXT(it);
+ }
+ }
}
-
- n = PyArray_SIZE(mp);
- data2 = data;
- for(i=0; i<n; i++, data++) Py_XDECREF(*data);
-
- if (!PyArray_ISONESEGMENT(mp)) _pya_free(data2);
-
return 0;
}
diff --git a/numpy/lib/twodim_base.py b/numpy/lib/twodim_base.py
index c1ba018d5..832d3f576 100644
--- a/numpy/lib/twodim_base.py
+++ b/numpy/lib/twodim_base.py
@@ -49,8 +49,9 @@ def eye(N, M=None, k=0, dtype=int_):
return m.astype(dtype)
def diag(v, k=0):
- """ returns the k-th diagonal if v is a array or returns a array
- with v as the k-th diagonal if v is a vector.
+ """ returns a copy of the the k-th diagonal if v is a 2-d array
+ or returns a 2-d array with v as the k-th diagonal if v is a
+ 1-d array.
"""
v = asarray(v)
s = v.shape