Exemple #1
0
/*
 * 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;
}
Exemple #2
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;
    }
}
Exemple #3
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__");
    }
}
Exemple #4
0
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);
}
Exemple #5
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_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;
    }
}
Exemple #6
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;
    }
}
Exemple #7
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;
}
Exemple #8
0
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;
}