[Numpy-discussion] Behavior of array scalars
Sasha
ndarray at mac.com
Fri Feb 17 17:56:05 EST 2006
On 2/17/06, Travis Oliphant <oliphant at ee.byu.edu> wrote:
> Sasha wrote:
>
> >Maybe we can change ufunc logic so that when the output argument is
> >supplied it is returned without scalar conversion.
> >
> >
> That seems sensible.
Attached patch implements this idea. With the patch applied:
>>> from numpy import *
>>> x = array(5)
>>> add(x,5,x)
array(10)
>>> x+=5
>>> x
array(15)
The patch passes all the tests, but I would like to hear from others
before commit. Personally, I am unhappy that I had to change C-API
function.
-------------- next part --------------
Index: numpy/core/src/ufuncobject.c
===================================================================
--- numpy/core/src/ufuncobject.c (revision 2128)
+++ numpy/core/src/ufuncobject.c (working copy)
@@ -846,7 +846,8 @@
#undef _GETATTR_
static int
-construct_matrices(PyUFuncLoopObject *loop, PyObject *args, PyArrayObject **mps)
+construct_matrices(PyUFuncLoopObject *loop, PyObject *args,
+ PyArrayObject **mps, Bool *supplied_output)
{
int nargs, i, maxsize;
int arg_types[MAX_ARGS];
@@ -952,6 +953,7 @@
mps[i] = NULL;
continue;
}
+ supplied_output[i] = TRUE;
Py_INCREF(mps[i]);
if (!PyArray_Check((PyObject *)mps[i])) {
PyObject *new;
@@ -1000,6 +1002,7 @@
NULL, NULL,
0, 0, NULL);
if (mps[i] == NULL) return -1;
+ supplied_output[i] = FALSE;
}
/* reset types for outputs that are equivalent
@@ -1271,7 +1274,8 @@
}
static PyUFuncLoopObject *
-construct_loop(PyUFuncObject *self, PyObject *args, PyArrayObject **mps)
+construct_loop(PyUFuncObject *self, PyObject *args,
+ PyArrayObject **mps, Bool* supplied_output)
{
PyUFuncLoopObject *loop;
int i;
@@ -1299,7 +1303,7 @@
&(loop->errobj)) < 0) goto fail;
/* Setup the matrices */
- if (construct_matrices(loop, args, mps) < 0) goto fail;
+ if (construct_matrices(loop, args, mps, supplied_output) < 0) goto fail;
PyUFunc_clearfperr();
@@ -1381,13 +1385,13 @@
/*UFUNC_API*/
static int
PyUFunc_GenericFunction(PyUFuncObject *self, PyObject *args,
- PyArrayObject **mps)
+ PyArrayObject **mps, Bool* supplied_output)
{
PyUFuncLoopObject *loop;
int i;
BEGIN_THREADS_DEF
- if (!(loop = construct_loop(self, args, mps))) return -1;
+ if (!(loop = construct_loop(self, args, mps, supplied_output))) return -1;
if (loop->notimplemented) {ufuncloop_dealloc(loop); return -2;}
LOOP_BEGIN_THREADS
@@ -2561,6 +2565,7 @@
PyTupleObject *ret;
PyArrayObject *mps[MAX_ARGS];
PyObject *retobj[MAX_ARGS];
+ Bool supplied_output[MAX_ARGS];
PyObject *res;
PyObject *wrap;
int errval;
@@ -2569,7 +2574,7 @@
if something goes wrong. */
for(i=0; i<self->nargs; i++) mps[i] = NULL;
- errval = PyUFunc_GenericFunction(self, args, mps);
+ errval = PyUFunc_GenericFunction(self, args, mps, supplied_output);
if (errval < 0) {
for(i=0; i<self->nargs; i++) Py_XDECREF(mps[i]);
if (errval == -1)
@@ -2619,7 +2624,9 @@
continue;
}
}
- retobj[i] = PyArray_Return(mps[j]);
+ retobj[i] = supplied_output[j]
+ ? (PyObject *)mps[j]
+ : PyArray_Return(mps[j]);
}
if (self->nout == 1) {
More information about the NumPy-Discussion
mailing list