/* * check if in "alhs @op@ orhs" that alhs is a temporary (refcnt == 1) so we * can do in-place operations instead of creating a new temporary * "cannot" is set to true if it cannot be done even with swapped arguments */ static int can_elide_temp(PyArrayObject * alhs, PyObject * orhs, int * cannot) { /* * to be a candidate the array needs to have reference count 1, be an exact * array of a basic type, own its data and size larger than threshold */ if (Py_REFCNT(alhs) != 1 || !PyArray_CheckExact(alhs) || !PyArray_ISNUMBER(alhs) || !PyArray_CHKFLAGS(alhs, NPY_ARRAY_OWNDATA) || !PyArray_ISWRITEABLE(alhs) || PyArray_CHKFLAGS(alhs, NPY_ARRAY_UPDATEIFCOPY) || PyArray_CHKFLAGS(alhs, NPY_ARRAY_WRITEBACKIFCOPY) || PyArray_NBYTES(alhs) < NPY_MIN_ELIDE_BYTES) { return 0; } if (PyArray_CheckExact(orhs) || PyArray_CheckAnyScalar(orhs)) { PyArrayObject * arhs; /* create array from right hand side */ Py_INCREF(orhs); arhs = (PyArrayObject *)PyArray_EnsureArray(orhs); if (arhs == NULL) { return 0; } /* * if rhs is not a scalar dimensions must match * TODO: one could allow broadcasting on equal types */ if (!(PyArray_NDIM(arhs) == 0 || (PyArray_NDIM(arhs) == PyArray_NDIM(alhs) && PyArray_CompareLists(PyArray_DIMS(alhs), PyArray_DIMS(arhs), PyArray_NDIM(arhs))))) { Py_DECREF(arhs); return 0; } /* must be safe to cast (checks values for scalar in rhs) */ if (PyArray_CanCastArrayTo(arhs, PyArray_DESCR(alhs), NPY_SAFE_CASTING)) { Py_DECREF(arhs); return check_callers(cannot); } Py_DECREF(arhs); } return 0; }
NPY_NO_EXPORT int needs_right_binop_forward(PyObject *self, PyObject *other, char *right_name, int inplace_op) { if (other == NULL || self == NULL || Py_TYPE(self) == Py_TYPE(other) || PyArray_CheckExact(other) || PyArray_CheckAnyScalar(other)) { /* * Quick cases */ return 0; } if (!inplace_op && PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self)) || !PyArray_Check(self)) { /* * Bail out if Python would already have called the right-hand * operation. */ return 0; } if (has_ufunc_attr(other) && PyObject_HasAttrString(other, right_name)) { return 1; } else { return 0; } }
static int has_ufunc_attr(PyObject * obj) { /* attribute check is expensive for scalar operations, avoid if possible */ if (PyArray_CheckExact(obj) || _is_basic_python_type(obj)) { return 0; } else { return PyObject_HasAttrString(obj, "__numpy_ufunc__"); } }
static PyObject * array_true_divide(PyArrayObject *m1, PyObject *m2) { PyObject *res; BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_true_divide, array_true_divide); if (PyArray_CheckExact(m1) && (PyArray_ISFLOAT(m1) || PyArray_ISCOMPLEX(m1)) && try_binary_elide(m1, m2, &array_inplace_true_divide, &res, 0)) { return res; } return PyArray_GenericBinaryFunction(m1, m2, n_ops.true_divide); }
/* try elide unary temporary */ NPY_NO_EXPORT int can_elide_temp_unary(PyArrayObject * m1) { int cannot; if (Py_REFCNT(m1) != 1 || !PyArray_CheckExact(m1) || PyArray_DESCR(m1)->type_num == NPY_VOID || !(PyArray_FLAGS(m1) & NPY_ARRAY_OWNDATA) || PyArray_NBYTES(m1) < NPY_MIN_ELIDE_BYTES) { return 0; } if (check_callers(&cannot)) { #if NPY_ELIDE_DEBUG != 0 puts("elided temporary in unary op"); #endif return 1; } else { return 0; } }
/* try elide unary temporary */ NPY_NO_EXPORT int can_elide_temp_unary(PyArrayObject * m1) { int cannot; if (Py_REFCNT(m1) != 1 || !PyArray_CheckExact(m1) || !PyArray_ISNUMBER(m1) || !PyArray_CHKFLAGS(m1, NPY_ARRAY_OWNDATA) || !PyArray_ISWRITEABLE(m1) || PyArray_CHKFLAGS(m1, NPY_ARRAY_UPDATEIFCOPY) || PyArray_NBYTES(m1) < NPY_MIN_ELIDE_BYTES) { return 0; } if (check_callers(&cannot)) { #if NPY_ELIDE_DEBUG != 0 puts("elided temporary in unary op"); #endif return 1; } else { return 0; } }
PyObject* PyThunk_FromArray(PyObject *unused, PyObject *input) { register PyThunkObject *thunk; (void) unused; input = PyArray_FromAny(input, NULL, 0, 0, NPY_ARRAY_ENSURECOPY, NULL); if (input == NULL || !PyArray_CheckExact(input)) { PyErr_SetString(PyExc_TypeError, "Expected a NumPy array as parameter."); return NULL; } thunk = (PyThunkObject *)PyObject_MALLOC(sizeof(PyThunkObject)); if (thunk == NULL) return PyErr_NoMemory(); PyObject_Init((PyObject*)thunk, &PyThunk_Type); thunk->storage = (PyArrayObject*) input; thunk->evaluated = true; thunk->operation = NULL; thunk->cardinality = PyArray_SIZE(thunk->storage); thunk->type = PyArray_TYPE(thunk->storage); thunk->options = THUNK_CARDINALITY_EXACT; thunk->blockmask = NULL; return (PyObject*)thunk; }
NPY_NO_EXPORT PyObject * __New_PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject *out, int variance, int num) { PyObject *obj1 = NULL, *obj2 = NULL, *obj3 = NULL; PyArrayObject *arr1 = NULL, *arr2 = NULL, *arrnew = NULL; PyObject *ret = NULL, *newshape = NULL; int i, n; npy_intp val; arrnew = (PyArrayObject *)PyArray_CheckAxis(self, &axis, 0); if (arrnew == NULL) { return NULL; } /* Compute and reshape mean */ arr1 = (PyArrayObject *)PyArray_EnsureAnyArray( PyArray_Mean(arrnew, axis, rtype, NULL)); if (arr1 == NULL) { Py_DECREF(arrnew); return NULL; } n = PyArray_NDIM(arrnew); newshape = PyTuple_New(n); if (newshape == NULL) { Py_DECREF(arr1); Py_DECREF(arrnew); return NULL; } for (i = 0; i < n; i++) { if (i == axis) { val = 1; } else { val = PyArray_DIM(arrnew,i); } PyTuple_SET_ITEM(newshape, i, PyInt_FromLong((long)val)); } arr2 = (PyArrayObject *)PyArray_Reshape(arr1, newshape); Py_DECREF(arr1); Py_DECREF(newshape); if (arr2 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute x = x - mx */ arr1 = (PyArrayObject *)PyArray_EnsureAnyArray( PyNumber_Subtract((PyObject *)arrnew, (PyObject *)arr2)); Py_DECREF(arr2); if (arr1 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute x * x */ if (PyArray_ISCOMPLEX(arr1)) { obj3 = PyArray_Conjugate(arr1, NULL); } else { obj3 = (PyObject *)arr1; Py_INCREF(arr1); } if (obj3 == NULL) { Py_DECREF(arrnew); return NULL; } arr2 = (PyArrayObject *)PyArray_EnsureAnyArray( PyArray_GenericBinaryFunction(arr1, obj3, n_ops.multiply)); Py_DECREF(arr1); Py_DECREF(obj3); if (arr2 == NULL) { Py_DECREF(arrnew); return NULL; } if (PyArray_ISCOMPLEX(arr2)) { obj3 = PyObject_GetAttrString((PyObject *)arr2, "real"); switch(rtype) { case NPY_CDOUBLE: rtype = NPY_DOUBLE; break; case NPY_CFLOAT: rtype = NPY_FLOAT; break; case NPY_CLONGDOUBLE: rtype = NPY_LONGDOUBLE; break; } } else { obj3 = (PyObject *)arr2; Py_INCREF(arr2); } if (obj3 == NULL) { Py_DECREF(arrnew); return NULL; } /* Compute add.reduce(x*x,axis) */ obj1 = PyArray_GenericReduceFunction((PyArrayObject *)obj3, n_ops.add, axis, rtype, NULL); Py_DECREF(obj3); Py_DECREF(arr2); if (obj1 == NULL) { Py_DECREF(arrnew); return NULL; } n = PyArray_DIM(arrnew,axis); Py_DECREF(arrnew); n = (n-num); if (n == 0) { n = 1; } obj2 = PyFloat_FromDouble(1.0/((double )n)); if (obj2 == NULL) { Py_DECREF(obj1); return NULL; } ret = PyNumber_Multiply(obj1, obj2); Py_DECREF(obj1); Py_DECREF(obj2); if (!variance) { arr1 = (PyArrayObject *)PyArray_EnsureAnyArray(ret); /* sqrt() */ ret = PyArray_GenericUnaryFunction(arr1, n_ops.sqrt); Py_DECREF(arr1); } if (ret == NULL) { return NULL; } if (PyArray_CheckExact(self)) { goto finish; } if (PyArray_Check(self) && Py_TYPE(self) == Py_TYPE(ret)) { goto finish; } arr1 = (PyArrayObject *)PyArray_EnsureArray(ret); if (arr1 == NULL) { return NULL; } ret = PyArray_View(arr1, NULL, Py_TYPE(self)); Py_DECREF(arr1); finish: if (out) { if (PyArray_AssignArray(out, (PyArrayObject *)ret, NULL, NPY_DEFAULT_ASSIGN_CASTING) < 0) { Py_DECREF(ret); return NULL; } Py_DECREF(ret); Py_INCREF(out); return (PyObject *)out; } return ret; }