コード例 #1
0
static PyObject *_histogram1d(PyObject *self, PyObject *args)
{

    long i, n;
    int ix, nx;
    double xmin, xmax, tx, fnx, normx;
    PyObject *x_obj, *x_array, *count_array;
    npy_intp dims[1];
    double *x, *count;

    /* Parse the input tuple */
    if (!PyArg_ParseTuple(args, "Oidd", &x_obj, &nx, &xmin, &xmax)) {
        PyErr_SetString(PyExc_TypeError, "Error parsing input");
        return NULL;
    }

    /* Interpret the input objects as `numpy` arrays. */
    x_array = PyArray_FROM_OTF(x_obj, NPY_DOUBLE, NPY_IN_ARRAY);

    /* If that didn't work, throw an `Exception`. */
    if (x_array == NULL) {
        PyErr_SetString(PyExc_TypeError, "Couldn't parse the input arrays.");
        Py_XDECREF(x_array);
        return NULL;
    }

    /* How many data points are there? */
    n = (long)PyArray_DIM(x_array, 0);

    /* Build the output array */
    dims[0] = nx;
    count_array = PyArray_SimpleNew(1, dims, NPY_DOUBLE);
    if (count_array == NULL) {
        PyErr_SetString(PyExc_TypeError, "Couldn't build output array");
        Py_DECREF(x_array);
        Py_XDECREF(count_array);
        return NULL;
    }

    PyArray_FILLWBYTE(count_array, 0);

    /* Get pointers to the data as C-types. */

    x = (double*)PyArray_DATA(x_array);
    count = (double*)PyArray_DATA(count_array);

    fnx = nx;
    normx = 1. / (xmax - xmin);

    for(i = 0; i < n; i++) {

      tx = x[i];

      if (tx >= xmin && tx < xmax) {
          ix = (tx - xmin) * normx * fnx;
          count[ix] += 1.;
      }

    }

    /* Clean up. */
    Py_DECREF(x_array);

    return count_array;

}
コード例 #2
0
ファイル: fortranobject.c プロジェクト: 7924102/numpy
extern
PyArrayObject* array_from_pyobj(const int type_num,
                                npy_intp *dims,
                                const int rank,
                                const int intent,
                                PyObject *obj) {
    /* Note about reference counting
       -----------------------------
       If the caller returns the array to Python, it must be done with
       Py_BuildValue("N",arr).
       Otherwise, if obj!=arr then the caller must call Py_DECREF(arr).

       Note on intent(cache,out,..)
       ---------------------
       Don't expect correct data when returning intent(cache) array.

    */
    char mess[200];
    PyArrayObject *arr = NULL;
    PyArray_Descr *descr;
    char typechar;
    int elsize;

    if ((intent & F2PY_INTENT_HIDE)
        || ((intent & F2PY_INTENT_CACHE) && (obj==Py_None))
        || ((intent & F2PY_OPTIONAL) && (obj==Py_None))
        ) {
        /* intent(cache), optional, intent(hide) */
        if (count_nonpos(rank,dims)) {
            int i;
            strcpy(mess, "failed to create intent(cache|hide)|optional array"
                   "-- must have defined dimensions but got (");
            for(i=0;i<rank;++i)
                sprintf(mess+strlen(mess),"%" NPY_INTP_FMT ",",dims[i]);
            strcat(mess, ")");
            PyErr_SetString(PyExc_ValueError,mess);
            return NULL;
        }
        arr = (PyArrayObject *)
            PyArray_New(&PyArray_Type, rank, dims, type_num,
                        NULL,NULL,0,
                        !(intent&F2PY_INTENT_C),
                        NULL);
        if (arr==NULL) return NULL;
        if (!(intent & F2PY_INTENT_CACHE))
            PyArray_FILLWBYTE(arr, 0);
        return arr;
    }

    descr = PyArray_DescrFromType(type_num);
    elsize = descr->elsize;
    typechar = descr->type;
    Py_DECREF(descr);
    if (PyArray_Check(obj)) {
        arr = (PyArrayObject *)obj;

        if (intent & F2PY_INTENT_CACHE) {
            /* intent(cache) */
            if (PyArray_ISONESEGMENT(arr)
                && PyArray_ITEMSIZE(arr)>=elsize) {
                if (check_and_fix_dimensions(arr,rank,dims)) {
                    return NULL; /*XXX: set exception */
                }
                if (intent & F2PY_INTENT_OUT)
                    Py_INCREF(arr);
                return arr;
            }
            strcpy(mess, "failed to initialize intent(cache) array");
            if (!PyArray_ISONESEGMENT(arr))
                strcat(mess, " -- input must be in one segment");
            if (PyArray_ITEMSIZE(arr)<elsize)
                sprintf(mess+strlen(mess),
                        " -- expected at least elsize=%d but got %" NPY_INTP_FMT,
                        elsize,
                        (npy_intp)PyArray_ITEMSIZE(arr)
                        );
            PyErr_SetString(PyExc_ValueError,mess);
            return NULL;
        }

        /* here we have always intent(in) or intent(inout) or intent(inplace) */

        if (check_and_fix_dimensions(arr,rank,dims)) {
            return NULL; /*XXX: set exception */
        }
	/*
	printf("intent alignement=%d\n", F2PY_GET_ALIGNMENT(intent));
	printf("alignement check=%d\n", F2PY_CHECK_ALIGNMENT(arr, intent));
	int i;
	for (i=1;i<=16;i++)
	  printf("i=%d isaligned=%d\n", i, ARRAY_ISALIGNED(arr, i));
	*/
        if ((! (intent & F2PY_INTENT_COPY))
            && PyArray_ITEMSIZE(arr)==elsize
            && ARRAY_ISCOMPATIBLE(arr,type_num)
	    && F2PY_CHECK_ALIGNMENT(arr, intent)
            ) {
            if ((intent & F2PY_INTENT_C)?PyArray_ISCARRAY(arr):PyArray_ISFARRAY(arr)) {
                if ((intent & F2PY_INTENT_OUT)) {
                    Py_INCREF(arr);
                }
                /* Returning input array */
                return arr;
            }
        }

        if (intent & F2PY_INTENT_INOUT) {
            strcpy(mess, "failed to initialize intent(inout) array");
            if ((intent & F2PY_INTENT_C) && !PyArray_ISCARRAY(arr))
                strcat(mess, " -- input not contiguous");
            if (!(intent & F2PY_INTENT_C) && !PyArray_ISFARRAY(arr))
                strcat(mess, " -- input not fortran contiguous");
            if (PyArray_ITEMSIZE(arr)!=elsize)
                sprintf(mess+strlen(mess),
                        " -- expected elsize=%d but got %" NPY_INTP_FMT,
                        elsize,
                        (npy_intp)PyArray_ITEMSIZE(arr)
                        );
            if (!(ARRAY_ISCOMPATIBLE(arr,type_num)))
                sprintf(mess+strlen(mess)," -- input '%c' not compatible to '%c'",
                        PyArray_DESCR(arr)->type,typechar);
	    if (!(F2PY_CHECK_ALIGNMENT(arr, intent)))
	      sprintf(mess+strlen(mess)," -- input not %d-aligned", F2PY_GET_ALIGNMENT(intent));
            PyErr_SetString(PyExc_ValueError,mess);
            return NULL;
        }

        /* here we have always intent(in) or intent(inplace) */

        {
            PyArrayObject *retarr = (PyArrayObject *) \
                PyArray_New(&PyArray_Type, PyArray_NDIM(arr), PyArray_DIMS(arr), type_num,
                            NULL,NULL,0,
                            !(intent&F2PY_INTENT_C),
                            NULL);
            if (retarr==NULL)
                return NULL;
            F2PY_REPORT_ON_ARRAY_COPY_FROMARR;
            if (PyArray_CopyInto(retarr, arr)) {
                Py_DECREF(retarr);
                return NULL;
            }
            if (intent & F2PY_INTENT_INPLACE) {
                if (swap_arrays(arr,retarr))
                    return NULL; /* XXX: set exception */
                Py_XDECREF(retarr);
                if (intent & F2PY_INTENT_OUT)
                    Py_INCREF(arr);
            } else {
                arr = retarr;
            }
        }
        return arr;
    }

    if ((intent & F2PY_INTENT_INOUT) ||
            (intent & F2PY_INTENT_INPLACE) ||
            (intent & F2PY_INTENT_CACHE)) {
        PyErr_SetString(PyExc_TypeError,
                        "failed to initialize intent(inout|inplace|cache) "
                        "array, input not an array");
        return NULL;
    }

    {
        F2PY_REPORT_ON_ARRAY_COPY_FROMANY;
        arr = (PyArrayObject *) \
            PyArray_FromAny(obj,PyArray_DescrFromType(type_num), 0,0,
                            ((intent & F2PY_INTENT_C)?NPY_ARRAY_CARRAY:NPY_ARRAY_FARRAY) \
                            | NPY_ARRAY_FORCECAST, NULL);
        if (arr==NULL)
            return NULL;
        if (check_and_fix_dimensions(arr,rank,dims))
            return NULL; /*XXX: set exception */
        return arr;
    }

}
コード例 #3
0
static PyObject *_histogram2d(PyObject *self, PyObject *args)
{

    long i, n;
    int ix, iy, nx, ny;
    double xmin, xmax, tx, fnx, normx, ymin, ymax, ty, fny, normy;
    PyObject *x_obj, *y_obj, *x_array, *y_array, *count_array;
    npy_intp dims[2];
    double *x, *y, *count;

    /* Parse the input tuple */
    if (!PyArg_ParseTuple(args, "OOiddidd", &x_obj, &y_obj, &nx, &xmin, &xmax, &ny, &ymin, &ymax)) {
        PyErr_SetString(PyExc_TypeError, "Error parsing input");
        return NULL;
    }

    /* Interpret the input objects as `numpy` arrays. */
    x_array = PyArray_FROM_OTF(x_obj, NPY_DOUBLE, NPY_IN_ARRAY);
    y_array = PyArray_FROM_OTF(y_obj, NPY_DOUBLE, NPY_IN_ARRAY);

    /* If that didn't work, throw an `Exception`. */
    if (x_array == NULL || y_array == NULL) {
        PyErr_SetString(PyExc_TypeError, "Couldn't parse the input arrays.");
        Py_XDECREF(x_array);
        Py_XDECREF(y_array);
        return NULL;
    }

    /* How many data points are there? */
    n = (long)PyArray_DIM(x_array, 0);

    /* Check the dimensions. */
    if (n != (long)PyArray_DIM(y_array, 0)) {
        PyErr_SetString(PyExc_RuntimeError, "Dimension mismatch between x and y");
        Py_DECREF(x_array);
        Py_DECREF(y_array);
        return NULL;
    }

    /* Build the output array */
    dims[0] = nx;
    dims[1] = ny;

    count_array = PyArray_SimpleNew(2, dims, NPY_DOUBLE);
    if (count_array == NULL) {
        PyErr_SetString(PyExc_TypeError, "Couldn't build output array");
        Py_DECREF(x_array);
        Py_XDECREF(count_array);
        return NULL;
    }

    PyArray_FILLWBYTE(count_array, 0);

    /* Get pointers to the data as C-types. */
    x = (double*)PyArray_DATA(x_array);
    y = (double*)PyArray_DATA(y_array);
    count = (double*)PyArray_DATA(count_array);

    fnx = nx;
    fny = ny;
    normx = 1. / (xmax - xmin);
    normy = 1. / (ymax - ymin);

    for(i = 0; i < n; i++) {

      tx = x[i];
      ty = y[i];

      if (tx >= xmin && tx < xmax && ty >= ymin && ty < ymax) {
          ix = (tx - xmin) * normx * fnx;
          iy = (ty - ymin) * normy * fny;
          count[iy + ny * ix] += 1.;
      }

    }

    /* Clean up. */
    Py_DECREF(x_array);
    Py_DECREF(y_array);

    return count_array;

}