Esempio n. 1
0
File: common.c Progetto: Dapid/numpy
NPY_NO_EXPORT int
PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
                              PyArray_Descr **out_dtype, int string_type)
{
    int i, size;
    PyArray_Descr *dtype = NULL;
    PyObject *ip;
    Py_buffer buffer_view;
    /* types for sequence handling */
    PyObject ** objects;
    PyObject * seq;
    PyTypeObject * common_type;

    /* Check if it's an ndarray */
    if (PyArray_Check(obj)) {
        dtype = PyArray_DESCR((PyArrayObject *)obj);
        Py_INCREF(dtype);
        goto promote_types;
    }

    /* See if it's a python None */
    if (obj == Py_None) {
        dtype = PyArray_DescrFromType(NPY_OBJECT);
        if (dtype == NULL) {
            goto fail;
        }
        Py_INCREF(dtype);
        goto promote_types;
    }
    /* Check if it's a NumPy scalar */
    else if (PyArray_IsScalar(obj, Generic)) {
        if (!string_type) {
            dtype = PyArray_DescrFromScalar(obj);
            if (dtype == NULL) {
                goto fail;
            }
        }
        else {
            int itemsize;
            PyObject *temp;

            if (string_type == NPY_STRING) {
                if ((temp = PyObject_Str(obj)) == NULL) {
                    return -1;
                }
#if defined(NPY_PY3K)
    #if PY_VERSION_HEX >= 0x03030000
                itemsize = PyUnicode_GetLength(temp);
    #else
                itemsize = PyUnicode_GET_SIZE(temp);
    #endif
#else
                itemsize = PyString_GET_SIZE(temp);
#endif
            }
            else if (string_type == NPY_UNICODE) {
#if defined(NPY_PY3K)
                if ((temp = PyObject_Str(obj)) == NULL) {
#else
                if ((temp = PyObject_Unicode(obj)) == NULL) {
#endif
                    return -1;
                }
                itemsize = PyUnicode_GET_DATA_SIZE(temp);
#ifndef Py_UNICODE_WIDE
                itemsize <<= 1;
#endif
            }
            else {
                goto fail;
            }
            Py_DECREF(temp);
            if (*out_dtype != NULL &&
                    (*out_dtype)->type_num == string_type &&
                    (*out_dtype)->elsize >= itemsize) {
                return 0;
            }
            dtype = PyArray_DescrNewFromType(string_type);
            if (dtype == NULL) {
                goto fail;
            }
            dtype->elsize = itemsize;
        }
        goto promote_types;
    }

    /* Check if it's a Python scalar */
    dtype = _array_find_python_scalar_type(obj);
    if (dtype != NULL) {
        if (string_type) {
            int itemsize;
            PyObject *temp;

            if (string_type == NPY_STRING) {
                if ((temp = PyObject_Str(obj)) == NULL) {
                    return -1;
                }
#if defined(NPY_PY3K)
    #if PY_VERSION_HEX >= 0x03030000
                itemsize = PyUnicode_GetLength(temp);
    #else
                itemsize = PyUnicode_GET_SIZE(temp);
    #endif
#else
                itemsize = PyString_GET_SIZE(temp);
#endif
            }
            else if (string_type == NPY_UNICODE) {
#if defined(NPY_PY3K)
                if ((temp = PyObject_Str(obj)) == NULL) {
#else
                if ((temp = PyObject_Unicode(obj)) == NULL) {
#endif
                    return -1;
                }
                itemsize = PyUnicode_GET_DATA_SIZE(temp);
#ifndef Py_UNICODE_WIDE
                itemsize <<= 1;
#endif
            }
            else {
                goto fail;
            }
            Py_DECREF(temp);
            if (*out_dtype != NULL &&
                    (*out_dtype)->type_num == string_type &&
                    (*out_dtype)->elsize >= itemsize) {
                return 0;
            }
            dtype = PyArray_DescrNewFromType(string_type);
            if (dtype == NULL) {
                goto fail;
            }
            dtype->elsize = itemsize;
        }
        goto promote_types;
    }

    /* Check if it's an ASCII string */
    if (PyBytes_Check(obj)) {
        int itemsize = PyString_GET_SIZE(obj);

        /* If it's already a big enough string, don't bother type promoting */
        if (*out_dtype != NULL &&
                        (*out_dtype)->type_num == NPY_STRING &&
                        (*out_dtype)->elsize >= itemsize) {
            return 0;
        }
        dtype = PyArray_DescrNewFromType(NPY_STRING);
        if (dtype == NULL) {
            goto fail;
        }
        dtype->elsize = itemsize;
        goto promote_types;
    }

    /* Check if it's a Unicode string */
    if (PyUnicode_Check(obj)) {
        int itemsize = PyUnicode_GET_DATA_SIZE(obj);
#ifndef Py_UNICODE_WIDE
        itemsize <<= 1;
#endif

        /*
         * If it's already a big enough unicode object,
         * don't bother type promoting
         */
        if (*out_dtype != NULL &&
                        (*out_dtype)->type_num == NPY_UNICODE &&
                        (*out_dtype)->elsize >= itemsize) {
            return 0;
        }
        dtype = PyArray_DescrNewFromType(NPY_UNICODE);
        if (dtype == NULL) {
            goto fail;
        }
        dtype->elsize = itemsize;
        goto promote_types;
    }

    /* PEP 3118 buffer interface */
    if (PyObject_CheckBuffer(obj) == 1) {
        memset(&buffer_view, 0, sizeof(Py_buffer));
        if (PyObject_GetBuffer(obj, &buffer_view,
                               PyBUF_FORMAT|PyBUF_STRIDES) == 0 ||
            PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) {

            PyErr_Clear();
            dtype = _descriptor_from_pep3118_format(buffer_view.format);
            PyBuffer_Release(&buffer_view);
            if (dtype) {
                goto promote_types;
            }
        }
        else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 ||
                 PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) {

            PyErr_Clear();
            dtype = PyArray_DescrNewFromType(NPY_VOID);
            dtype->elsize = buffer_view.itemsize;
            PyBuffer_Release(&buffer_view);
            goto promote_types;
        }
        else {
            PyErr_Clear();
        }
    }

    /* The array interface */
    ip = PyArray_GetAttrString_SuppressException(obj, "__array_interface__");
    if (ip != NULL) {
        if (PyDict_Check(ip)) {
            PyObject *typestr;
#if defined(NPY_PY3K)
            PyObject *tmp = NULL;
#endif
            typestr = PyDict_GetItemString(ip, "typestr");
#if defined(NPY_PY3K)
            /* Allow unicode type strings */
            if (PyUnicode_Check(typestr)) {
                tmp = PyUnicode_AsASCIIString(typestr);
                typestr = tmp;
            }
#endif
            if (typestr && PyBytes_Check(typestr)) {
                dtype =_array_typedescr_fromstr(PyBytes_AS_STRING(typestr));
#if defined(NPY_PY3K)
                if (tmp == typestr) {
                    Py_DECREF(tmp);
                }
#endif
                Py_DECREF(ip);
                if (dtype == NULL) {
                    goto fail;
                }
                goto promote_types;
            }
        }
        Py_DECREF(ip);
    }

    /* The array struct interface */
    ip = PyArray_GetAttrString_SuppressException(obj, "__array_struct__");
    if (ip != NULL) {
        PyArrayInterface *inter;
        char buf[40];

        if (NpyCapsule_Check(ip)) {
            inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip);
            if (inter->two == 2) {
                PyOS_snprintf(buf, sizeof(buf),
                        "|%c%d", inter->typekind, inter->itemsize);
                dtype = _array_typedescr_fromstr(buf);
                Py_DECREF(ip);
                if (dtype == NULL) {
                    goto fail;
                }
                goto promote_types;
            }
        }
        Py_DECREF(ip);
    }

    /* The old buffer interface */
#if !defined(NPY_PY3K)
    if (PyBuffer_Check(obj)) {
        dtype = PyArray_DescrNewFromType(NPY_VOID);
        if (dtype == NULL) {
            goto fail;
        }
        dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj);
        PyErr_Clear();
        goto promote_types;
    }
#endif

    /* The __array__ attribute */
    ip = PyArray_GetAttrString_SuppressException(obj, "__array__");
    if (ip != NULL) {
        Py_DECREF(ip);
        ip = PyObject_CallMethod(obj, "__array__", NULL);
        if(ip && PyArray_Check(ip)) {
            dtype = PyArray_DESCR((PyArrayObject *)ip);
            Py_INCREF(dtype);
            Py_DECREF(ip);
            goto promote_types;
        }
        Py_XDECREF(ip);
        if (PyErr_Occurred()) {
            goto fail;
        }
    }

    /* Not exactly sure what this is about... */
#if !defined(NPY_PY3K)
    if (PyInstance_Check(obj)) {
        dtype = _use_default_type(obj);
        if (dtype == NULL) {
            goto fail;
        }
        else {
            goto promote_types;
        }
    }
#endif

    /*
     * If we reached the maximum recursion depth without hitting one
     * of the above cases, the output dtype should be OBJECT
     */
    if (maxdims == 0 || !PySequence_Check(obj)) {
        if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) {
            Py_XDECREF(*out_dtype);
            *out_dtype = PyArray_DescrFromType(NPY_OBJECT);
            if (*out_dtype == NULL) {
                return -1;
            }
        }
        return 0;
    }

    /*
     * fails if convertable to list but no len is defined which some libraries
     * require to get object arrays
     */
    size = PySequence_Size(obj);
    if (size < 0) {
        goto fail;
    }

    /* Recursive case, first check the sequence contains only one type */
    seq = PySequence_Fast(obj, "Could not convert object to sequence");
    if (seq == NULL) {
        goto fail;
    }
    objects = PySequence_Fast_ITEMS(seq);
    common_type = size > 0 ? Py_TYPE(objects[0]) : NULL;
    for (i = 1; i < size; ++i) {
        if (Py_TYPE(objects[i]) != common_type) {
            common_type = NULL;
            break;
        }
    }

    /* all types are the same and scalar, one recursive call is enough */
    if (common_type != NULL && !string_type &&
            (common_type == &PyFloat_Type ||
/* TODO: we could add longs if we add a range check */
#if !defined(NPY_PY3K)
             common_type == &PyInt_Type ||
#endif
             common_type == &PyBool_Type ||
             common_type == &PyComplex_Type)) {
        size = 1;
    }

    /* Recursive call for each sequence item */
    for (i = 0; i < size; ++i) {
        int res = PyArray_DTypeFromObjectHelper(objects[i], maxdims - 1,
                                                out_dtype, string_type);
        if (res < 0) {
            Py_DECREF(seq);
            goto fail;
        }
        else if (res > 0) {
            Py_DECREF(seq);
            return res;
        }
    }

    Py_DECREF(seq);

    return 0;


promote_types:
    /* Set 'out_dtype' if it's NULL */
    if (*out_dtype == NULL) {
        if (!string_type && dtype->type_num == NPY_STRING) {
            Py_DECREF(dtype);
            return RETRY_WITH_STRING;
        }
        if (!string_type && dtype->type_num == NPY_UNICODE) {
            Py_DECREF(dtype);
            return RETRY_WITH_UNICODE;
        }
        *out_dtype = dtype;
        return 0;
    }
    /* Do type promotion with 'out_dtype' */
    else {
        PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype);
        Py_DECREF(dtype);
        if (res_dtype == NULL) {
            return -1;
        }
        if (!string_type &&
                res_dtype->type_num == NPY_UNICODE &&
                (*out_dtype)->type_num != NPY_UNICODE) {
            Py_DECREF(res_dtype);
            return RETRY_WITH_UNICODE;
        }
        if (!string_type &&
                res_dtype->type_num == NPY_STRING &&
                (*out_dtype)->type_num != NPY_STRING) {
            Py_DECREF(res_dtype);
            return RETRY_WITH_STRING;
        }
        Py_DECREF(*out_dtype);
        *out_dtype = res_dtype;
        return 0;
    }

fail:
    Py_XDECREF(*out_dtype);
    *out_dtype = NULL;
    return -1;
}

#undef RETRY_WITH_STRING
#undef RETRY_WITH_UNICODE

/* new reference */
NPY_NO_EXPORT PyArray_Descr *
_array_typedescr_fromstr(char *c_str)
{
    PyArray_Descr *descr = NULL;
    PyObject *stringobj = PyString_FromString(c_str);

    if (stringobj == NULL) {
        return NULL;
    }
    if (PyArray_DescrConverter(stringobj, &descr) != NPY_SUCCEED) {
        Py_DECREF(stringobj);
        return NULL;
    }
    Py_DECREF(stringobj);
    return descr;
}


NPY_NO_EXPORT char *
index2ptr(PyArrayObject *mp, npy_intp i)
{
    npy_intp dim0;

    if (PyArray_NDIM(mp) == 0) {
        PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed");
        return NULL;
    }
    dim0 = PyArray_DIMS(mp)[0];
    if (check_and_adjust_index(&i, dim0, 0, NULL) < 0)
        return NULL;
    if (i == 0) {
        return PyArray_DATA(mp);
    }
    return PyArray_BYTES(mp)+i*PyArray_STRIDES(mp)[0];
}
Esempio n. 2
0
int NI_FindObjects(PyArrayObject* input, npy_intp max_label,
                                     npy_intp* regions)
{
    npy_intp size, jj;
    NI_Iterator ii;
    char *pi;
    NPY_BEGIN_THREADS_DEF;

    NPY_BEGIN_THREADS;

    /* get input data, size and iterator: */
    pi = (void *)PyArray_DATA(input);
    size = PyArray_SIZE(input);
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    if (PyArray_NDIM(input) > 0) {
        for (jj = 0; jj < 2 * PyArray_NDIM(input) * max_label; jj++) {
            regions[jj] = -1;
        }
    } else {
        for(jj = 0; jj < max_label; jj++)
            regions[jj] = -1;
    }
    /* iterate over all points: */
    for(jj = 0 ; jj < size; jj++) {
        switch (PyArray_TYPE(input)) {
            CASE_FIND_OBJECT_POINT(NPY_BOOL, npy_bool,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_UBYTE, npy_ubyte,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_USHORT, npy_ushort,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_UINT, npy_uint,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_ULONG, npy_ulong,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_ULONGLONG, npy_ulonglong,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_BYTE, npy_byte,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_SHORT, npy_short,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_INT, npy_int,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_LONG, npy_long,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_LONGLONG, npy_longlong,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_FLOAT, npy_float,
                                   pi, regions, input, max_label, ii);
            CASE_FIND_OBJECT_POINT(NPY_DOUBLE, npy_double,
                                   pi, regions, input, max_label, ii);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT(ii, pi);
    }
 exit:
    NPY_END_THREADS;
    return PyErr_Occurred() ? 0 : 1;
}
Esempio n. 3
0
int NI_Correlate(PyArrayObject* input, PyArrayObject* weights,
                 PyArrayObject* output, NI_ExtendMode mode,
                 double cvalue, npy_intp *origins)
{
    npy_bool *pf = NULL;
    npy_intp fsize, jj, kk, filter_size = 0, border_flag_value;
    npy_intp *offsets = NULL, *oo, size;
    NI_FilterIterator fi;
    NI_Iterator ii, io;
    char *pi, *po;
    npy_double *pw;
    npy_double *ww = NULL;
    int err = 0;
    NPY_BEGIN_THREADS_DEF;

    /* get the the footprint: */
    fsize = PyArray_SIZE(weights);
    pw = (npy_double*)PyArray_DATA(weights);
    pf = malloc(fsize * sizeof(npy_bool));
    if (!pf) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < fsize; jj++) {
        if (fabs(pw[jj]) > DBL_EPSILON) {
            pf[jj] = 1;
            ++filter_size;
        } else {
            pf[jj] = 0;
        }
    }
    /* copy the weights to contiguous memory: */
    ww = malloc(filter_size * sizeof(npy_double));
    if (!ww) {
        PyErr_NoMemory();
        goto exit;
    }
    jj = 0;
    for(kk = 0; kk < fsize; kk++) {
        if (pf[kk]) {
            ww[jj++] = pw[kk];
        }
    }
    /* initialize filter offsets: */
    if (!NI_InitFilterOffsets(input, pf, PyArray_DIMS(weights), origins,
                              mode, &offsets, &border_flag_value, NULL)) {
        goto exit;
    }
    /* initialize filter iterator: */
    if (!NI_InitFilterIterator(PyArray_NDIM(input), PyArray_DIMS(weights),
                               filter_size, PyArray_DIMS(input), origins,
                               &fi)) {
        goto exit;
    }
    /* initialize input element iterator: */
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* initialize output element iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    NPY_BEGIN_THREADS;
    /* get data pointers an array size: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);
    size = PyArray_SIZE(input);
    /* iterator over the elements: */
    oo = offsets;
    for(jj = 0; jj < size; jj++) {
        double tmp = 0.0;
        switch (PyArray_TYPE(input)) {
            CASE_CORRELATE_POINT(NPY_BOOL, npy_bool,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_UBYTE, npy_ubyte,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_USHORT, npy_ushort,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_UINT, npy_uint,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_ULONG, npy_ulong,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_ULONGLONG, npy_ulonglong,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_BYTE, npy_byte,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_SHORT, npy_short,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_INT, npy_int,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_LONG, npy_long,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_LONGLONG, npy_longlong,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_FLOAT, npy_float,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            CASE_CORRELATE_POINT(NPY_DOUBLE, npy_double,
                                 pi, ww, oo, filter_size, cvalue, tmp,
                                 border_flag_value);
            default:
                err = 1;
                goto exit;
        }
        switch (PyArray_TYPE(output)) {
            CASE_FILTER_OUT(NPY_BOOL, npy_bool, po, tmp);
            CASE_FILTER_OUT(NPY_UBYTE, npy_ubyte, po, tmp);
            CASE_FILTER_OUT(NPY_USHORT, npy_ushort, po, tmp);
            CASE_FILTER_OUT(NPY_UINT, npy_uint, po, tmp);
            CASE_FILTER_OUT(NPY_ULONG, npy_ulong, po, tmp);
            CASE_FILTER_OUT(NPY_ULONGLONG, npy_ulonglong, po, tmp);
            CASE_FILTER_OUT(NPY_BYTE, npy_byte, po, tmp);
            CASE_FILTER_OUT(NPY_SHORT, npy_short, po, tmp);
            CASE_FILTER_OUT(NPY_INT, npy_int, po, tmp);
            CASE_FILTER_OUT(NPY_LONG, npy_long, po, tmp);
            CASE_FILTER_OUT(NPY_LONGLONG, npy_longlong, po, tmp);
            CASE_FILTER_OUT(NPY_FLOAT, npy_float, po, tmp);
            CASE_FILTER_OUT(NPY_DOUBLE, npy_double, po, tmp);
            default:
                err = 1;
                goto exit;
        }
        NI_FILTER_NEXT2(fi, ii, io, oo, pi, po);
    }
exit:
    NPY_END_THREADS;
    if (err == 1) {
        PyErr_SetString(PyExc_RuntimeError, "array type not supported");
    }
    free(offsets);
    free(ww);
    free(pf);
    return PyErr_Occurred() ? 0 : 1;
}
Esempio n. 4
0
static PyObject *inverse_division_inplace(PyObject *self, PyObject *args)
{
  PyObject* a = NULL;
  PyObject* b = NULL;
  npy_intp sz = 0, i;
  npy_complex64* tmp_sp = NULL;
  npy_float32 tmp2_sp;
  npy_complex64* a_data_sp = NULL;
  npy_float32* b_data_sp = NULL;
  npy_complex128* tmp_dp = NULL;
  npy_float64 tmp2_dp;
  npy_complex128* a_data_dp = NULL;
  npy_float64* b_data_dp = NULL;
  if (!PyArg_ParseTuple(args, "OO", &a, &b))
    return NULL;
  if (!(PyArray_Check(a) && PyArray_Check(b)))
    {
      PyErr_SetString(PyExc_TypeError,"arguments must be array objects");
      return NULL;
    }
  sz = PyArray_SIZE(a);

  if (sz != PyArray_SIZE(b))
    {
      PyErr_SetString(PyExc_TypeError,"argument sizes must be equal");
      return NULL;
    }
  if ((PyArray_TYPE(a) == PyArray_COMPLEX64) && (PyArray_TYPE(b) == PyArray_FLOAT32))
    {
      a_data_sp = (npy_complex64*)PyArray_DATA(a);
      b_data_sp = (npy_float32*)PyArray_DATA(b);
      for (i=0; i<sz; ++i)
	{
	  tmp_sp = a_data_sp + i;
	  if (tmp_sp->real==0.0 || (b_data_sp[i]==0.0))
	    {
	      tmp_sp->real = tmp_sp->imag = 0.0;
	    }
	  else
	    {
	      tmp2_sp = b_data_sp[i] / (tmp_sp->real * tmp_sp->real + tmp_sp->imag * tmp_sp->imag);
	      tmp_sp->real *= tmp2_sp;
	      tmp_sp->imag *= -tmp2_sp;
	    }
	}
    }
  else if ((PyArray_TYPE(a) == PyArray_COMPLEX128) && (PyArray_TYPE(b) == PyArray_FLOAT64))
    {
      a_data_dp = (npy_complex128*)PyArray_DATA(a);
      b_data_dp = (npy_float64*)PyArray_DATA(b);
      for (i=0; i<sz; ++i)
	{
	  tmp_dp = a_data_dp + i;
	  if (tmp_dp->real==0.0 || (b_data_dp[i]==0.0))
	    {
	      tmp_dp->real = tmp_dp->imag = 0.0;
	    }
	  else
	    {
	      tmp2_dp = b_data_dp[i] / (tmp_dp->real * tmp_dp->real + tmp_dp->imag * tmp_dp->imag);
	      tmp_dp->real *= tmp2_dp;
	      tmp_dp->imag *= -tmp2_dp;
	    }
	}
    }
  else
    {
      PyErr_SetString(PyExc_TypeError,"argument types must be complex64 and float32");
      return NULL;
    }
  return Py_BuildValue("");
}
Esempio n. 5
0
static PyObject *div_unit_grad1(PyObject *self, PyObject *args)
{
  PyObject* f = NULL;
  npy_intp Nx;
  int i, im1, im2, ip1;
  npy_float64* f_data_dp = NULL;
  npy_float64* r_data_dp = NULL;
  double hx;
  double hx2;
  PyArrayObject* r = NULL;
  double fip, fim, fijk;
  double aim, aijk;
  double Dxpf, Dxmf;
  double Dxma;
  if (!PyArg_ParseTuple(args, "Od", &f, &hx))
    return NULL;
  hx2 = 2*hx;
  if (!PyArray_Check(f))
    {
      PyErr_SetString(PyExc_TypeError,"first argument must be array");
      return NULL;
    }
  if (PyArray_NDIM(f) != 1)
    {
      PyErr_SetString(PyExc_TypeError,"array argument must have rank 1");
      return NULL;
    }
  Nx = PyArray_DIM(f, 0);
  r = (PyArrayObject*)PyArray_SimpleNew(1, PyArray_DIMS(f), PyArray_TYPE(f));

  if (PyArray_TYPE(f) == PyArray_FLOAT64)
    {
      f_data_dp = (npy_float64*)PyArray_DATA(f);
      r_data_dp = (npy_float64*)PyArray_DATA(r);
      for (i=0; i<Nx; ++i)
	{
	  im1 = (i?i-1:0);
      	  ip1 = (i+1==Nx?i:i+1);
	  fim = *((npy_float64*)PyArray_GETPTR1(f, im1));
	  fijk = *((npy_float64*)PyArray_GETPTR1(f, i));
	  fip = *((npy_float64*)PyArray_GETPTR1(f, ip1));
	  Dxpf = (fip - fijk) / hx;
	  //if (Dxpf==0.0) aijk = 0.0;
	  //else if (Dxpf<0.0) aijk = -1.0;
	  //else aijk = 1.0;
	  aijk = sqrt(Dxpf*Dxpf);
	  aijk = (aijk>FLOAT64_EPS?Dxpf / aijk:0.0);
	  //aijk = abs(Dxpf);
	  //aijk = (aijk>FLOAT64_EPS?Dxpf / aijk:0.0);
	  Dxpf = (fijk - fim) / hx;
	  //if (Dxpf==0.0) aim = 0.0;
	  //else if (Dxpf<0.0) aim = -1.0;
	  //else aim = 1.0;
	  //aim = abs(Dxpf);
	  //aim = (aim>FLOAT64_EPS?Dxpf/aim:0.0); 		  
	  aim = sqrt(Dxpf*Dxpf);
	  aim = (aim>FLOAT64_EPS?Dxpf/aim:0.0);
	  Dxma = (aijk - aim) / hx;
	  *((npy_float64*)PyArray_GETPTR1(r, i)) = Dxma;
	}
    }
  else
    {
      PyErr_SetString(PyExc_TypeError,"array argument type must be float64");
      return NULL;
    }
  return Py_BuildValue("N", r);
}
Esempio n. 6
0
static PyObject*
libtfr_stft(PyObject *self, PyObject *args)
{
        /* arguments */
        PyObject *o = NULL;
        PyArrayObject *signal = NULL;
        PyArrayObject *signal_cast = NULL;
        PyObject *o2 = NULL;
        PyArrayObject *window = NULL;
        int step;
        int N = 0;
        int Npoints, Ntapers;

        /* output data */
        npy_intp out_shape[3];
        PyArrayObject *outdata = NULL;
        int do_complex = 0;
        double *spec;
        complex double *zspec_tmp;
        npy_cdouble *zspec;

        /* internal stuff */
        mfft *mtmh;
        double *samples = NULL;
        double *windowp;

        /* parse arguments */
        if (!PyArg_ParseTuple(args, "OOi|ii", &o, &o2, &step, &N, &do_complex))
                return NULL;
        signal = (PyArrayObject*) PyArray_FromAny(o, NULL, 1, 1, NPY_CONTIGUOUS, NULL);
        if (signal==NULL) {
                PyErr_SetString(PyExc_TypeError, "Input signal must be an ndarray");
                return NULL;
        }
        window = (PyArrayObject*) PyArray_FromAny(o2, NULL, 1, 2, NPY_CONTIGUOUS, NULL);
        if (window==NULL) {
                PyErr_SetString(PyExc_TypeError, "Window must be a 1D or 2D ndarray");
                goto fail;
        }
        /* determine dimensions of window */
        if (PyArray_NDIM(window)==1) {
                Ntapers = 1;
                Npoints = PyArray_DIM(window, 0);
        }
        else {
                Ntapers = PyArray_DIM(window, 0);
                Npoints = PyArray_DIM(window, 1);
        }

        /* coerce data to proper type */
        samples = coerce_ndarray_double(signal, &signal_cast);
        if (samples==NULL) {
                PyErr_SetString(PyExc_TypeError, "Unable to cast signal to supported data type");
                goto fail;
        }
        /* need to copy the window function b/c mtm_destroy() will demalloc it */
        if (PyArray_TYPE(window)!=NPY_DOUBLE) {
                PyErr_SetString(PyExc_TypeError, "Window function must be double precision float");
                goto fail;
        }
        windowp = malloc(Npoints * Ntapers * sizeof(double));
        memcpy(windowp, PyArray_DATA(window), Npoints * Ntapers * sizeof(double));

        /* allocate outputs and do the transform */
        if (N < 1)
                N = Npoints;
        mtmh = mtm_init(N, Npoints, Ntapers, windowp, NULL);
        out_shape[0] = N/2+1;
        if (do_complex) {
                out_shape[1] = Ntapers;
                out_shape[2] = SPEC_NFRAMES(mtmh, PyArray_SIZE(signal), step);
                outdata  = (PyArrayObject*) PyArray_ZEROS(3,out_shape,NPY_CDOUBLE,1); // fortran-order
                zspec = (npy_cdouble*) PyArray_DATA(outdata);
                //printf("output dimensions: %d, %d, %d\n", out_shape[0], out_shape[1], out_shape[2]);
                zspec_tmp = (complex double*)malloc(PyArray_SIZE(outdata) * sizeof(complex double));
                mtm_zspec(mtmh, zspec_tmp, samples, PyArray_SIZE(signal), step);
                cmplx_c99tonpy(zspec_tmp, zspec, PyArray_SIZE(outdata));
                free(zspec_tmp);
        }
        else {
                out_shape[1] = SPEC_NFRAMES(mtmh, PyArray_SIZE(signal), step);
                outdata  = (PyArrayObject*) PyArray_ZEROS(2,out_shape,NPY_DOUBLE,1); // fortran-order
                spec = (double*) PyArray_DATA(outdata);
                mtm_spec(mtmh, spec, samples, PyArray_SIZE(signal), step, 0);
        }
        mtm_destroy(mtmh);

        Py_DECREF(signal);
        Py_DECREF(window);
        Py_XDECREF(signal_cast);
        return PyArray_Return(outdata);
fail:
        Py_XDECREF(signal_cast);
        Py_XDECREF(signal);
        Py_XDECREF(window);
        Py_XDECREF(outdata);
        return NULL;
}
Esempio n. 7
0
static PyObject *update_estimate_poisson(PyObject *self, PyObject *args)
{
  PyObject* a = NULL;
  PyObject* b = NULL;
  npy_intp sz = 0, i;
  double tmp, tmp2;
  npy_float32* a_data_sp = NULL;
  npy_float32* b_data_sp = NULL;
  npy_complex64* b_data_csp = NULL;
  npy_float64* a_data_dp = NULL;
  npy_float64* b_data_dp = NULL;
  npy_complex128* b_data_cdp = NULL;
  double c, c0, c1, c2;
  double unstable = 0.0, stable = 0.0, negative = 0.0, exact = 0.0;
  if (!PyArg_ParseTuple(args, "OOd", &a, &b, &c))
    return NULL;
  if (c<0 || c>0.5)
    {
      PyErr_SetString(PyExc_TypeError,"third argument must be non-negative and less than 0.5");
      return NULL;
    }
  if (!(PyArray_Check(a) && PyArray_Check(b)))
    {
      PyErr_SetString(PyExc_TypeError,"first two arguments must be array objects");
      return NULL;
    }
  sz = PyArray_SIZE(a);
  if (sz != PyArray_SIZE(b))
    {
      PyErr_SetString(PyExc_TypeError,"array argument sizes must be equal");
      return NULL;
    }
  c0 = -c;
  c1 = 1.0+c;
  c2 = 1.0-c;
  if ((PyArray_TYPE(a) == PyArray_FLOAT32) && (PyArray_TYPE(b) == PyArray_FLOAT32))
    {
      a_data_sp = (npy_float32*)PyArray_DATA(a);
      b_data_sp = (npy_float32*)PyArray_DATA(b);
      for (i=0; i<sz; ++i)
	{
	  tmp = b_data_sp[i];
	  tmp2 = (a_data_sp[i] *= (tmp>0?tmp:0.0));
	  if (tmp==0.0 || tmp==1.0)
	    exact += tmp2;
	  else if (((tmp>c0) && (tmp<c)) || ((tmp<c1) && (tmp>c2)))
	    stable += tmp2;
	  else
	    unstable += tmp2;
	  if (tmp2<0)
	    negative += tmp2;
	}
    }
  else if ((PyArray_TYPE(a) == PyArray_FLOAT32) && (PyArray_TYPE(b) == PyArray_COMPLEX64))
    {
      a_data_sp = (npy_float32*)PyArray_DATA(a);
      b_data_csp = (npy_complex64*)PyArray_DATA(b);
      for (i=0; i<sz; ++i)
	{
	  tmp = b_data_csp[i].real;
	  tmp2 = (a_data_sp[i] *= (tmp>0?tmp:0.0));
	  if (tmp==0.0 || tmp==1.0)
	    exact += tmp2;
	  else if (((tmp>c0) && (tmp<c)) || ((tmp<c1) && (tmp>c2)))
	    stable += tmp2;
	  else
	    unstable += tmp2;
	  if (tmp2<0)
	    negative += tmp2;
	}
    }
  else if ((PyArray_TYPE(a) == PyArray_FLOAT64) && (PyArray_TYPE(b) == PyArray_FLOAT64))
    {
      a_data_dp = (npy_float64*)PyArray_DATA(a);
      b_data_dp = (npy_float64*)PyArray_DATA(b);
      for (i=0; i<sz; ++i)
	{
	  tmp = b_data_dp[i];
	  tmp2 = (a_data_dp[i] *= (tmp>0?tmp:0.0));
	  if (tmp==0.0 || tmp==1.0)
	    exact += tmp2;
	  else if (((tmp>c0) && (tmp<c)) || ((tmp<c1) && (tmp>c2)))
	    stable += tmp2;
	  else
	    unstable += tmp2;
	  if (tmp2<0)
	    negative += tmp2;
	}
    }
  else if ((PyArray_TYPE(a) == PyArray_FLOAT64) && (PyArray_TYPE(b) == PyArray_COMPLEX128))
    {
      a_data_dp = (npy_float64*)PyArray_DATA(a);
      b_data_cdp = (npy_complex128*)PyArray_DATA(b);
      for (i=0; i<sz; ++i)
	{
	  tmp = (b_data_cdp[i]).real;
	  tmp2 = (a_data_dp[i] *= (tmp>0?tmp:0.0));
	  if (tmp==0.0 || tmp==1.0)
	    exact += tmp2;
	  else if (((tmp>c0) && (tmp<c)) || ((tmp<c1) && (tmp>c2)))
	    stable += tmp2;
	  else
	    unstable += tmp2;
	  if (tmp2<0)
	    negative += tmp2;
	}
    }
  else
    {
      PyErr_SetString(PyExc_TypeError,"array argument types must be either float32 or float64");
      return NULL;
    }
  return Py_BuildValue("dddd", exact, stable, unstable, negative);
}
Esempio n. 8
0
static PyObject * oscillAnglesOfHKLs(PyObject * self, PyObject * args)
{
  PyArrayObject *hkls, *rMat_c, *bMat,
                *vInv_s, *beamVec, *etaVec;
  PyFloatObject *chi, *wavelength;
  PyArrayObject *oangs0, *oangs1;

  int dhkls, drc, dbm, dvi, dbv, dev;
  npy_intp npts, dims[2];

  double *hkls_Ptr, chi_d,
         *rMat_c_Ptr, *bMat_Ptr, wavelen_d,
         *vInv_s_Ptr, *beamVec_Ptr, *etaVec_Ptr;
  double *oangs0_Ptr, *oangs1_Ptr;

  /* Parse arguments */
  if ( !PyArg_ParseTuple(args,"OOOOOOOO",
			 &hkls, &chi,
			 &rMat_c, &bMat, &wavelength,
			 &vInv_s, &beamVec, &etaVec)) return(NULL);
  if ( hkls    == NULL || chi == NULL ||
       rMat_c  == NULL || bMat == NULL || wavelength == NULL ||
       vInv_s  == NULL || beamVec == NULL || etaVec == NULL ) return(NULL);

  /* Verify shape of input arrays */
  dhkls = PyArray_NDIM(hkls);
  drc   = PyArray_NDIM(rMat_c);
  dbm   = PyArray_NDIM(bMat);
  dvi   = PyArray_NDIM(vInv_s);
  dbv   = PyArray_NDIM(beamVec);
  dev   = PyArray_NDIM(etaVec);
  assert( dhkls == 2 && drc == 2 && dbm == 2 &&
	  dvi   == 1 && dbv == 1 && dev == 1);

  /* Verify dimensions of input arrays */
  npts = PyArray_DIMS(hkls)[0];

  assert( PyArray_DIMS(hkls)[1]    == 3 );
  assert( PyArray_DIMS(rMat_c)[0]  == 3 && PyArray_DIMS(rMat_c)[1] == 3 );
  assert( PyArray_DIMS(bMat)[0]    == 3 && PyArray_DIMS(bMat)[1]   == 3 );
  assert( PyArray_DIMS(vInv_s)[0]  == 6 );
  assert( PyArray_DIMS(beamVec)[0] == 3 );
  assert( PyArray_DIMS(etaVec)[0]  == 3 );

  /* Allocate arrays for return values */
  dims[0] = npts; dims[1] = 3;
  oangs0 = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0);
  oangs1 = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0);

  /* Grab data pointers into various arrays */
  hkls_Ptr    = (double*)PyArray_DATA(hkls);

  chi_d       = PyFloat_AsDouble((PyObject*)chi);
  wavelen_d   = PyFloat_AsDouble((PyObject*)wavelength);

  rMat_c_Ptr  = (double*)PyArray_DATA(rMat_c);
  bMat_Ptr    = (double*)PyArray_DATA(bMat);

  vInv_s_Ptr  = (double*)PyArray_DATA(vInv_s);

  beamVec_Ptr = (double*)PyArray_DATA(beamVec);
  etaVec_Ptr  = (double*)PyArray_DATA(etaVec);

  oangs0_Ptr  = (double*)PyArray_DATA(oangs0);
  oangs1_Ptr  = (double*)PyArray_DATA(oangs1);

  /* Call the computational routine */
  oscillAnglesOfHKLs_cfunc(npts, hkls_Ptr, chi_d,
			   rMat_c_Ptr, bMat_Ptr, wavelen_d,
			   vInv_s_Ptr, beamVec_Ptr, etaVec_Ptr,
			   oangs0_Ptr, oangs1_Ptr);

  // printf("chi = %g, wavelength = %g\n",PyFloat_AsDouble((PyObject*)chi),PyFloat_AsDouble((PyObject*)wavelength));
  /*
np.ascontiguousarray(hkls),chi,rMat_c,bMat,wavelength,
                                               beamVec.flatten(),etaVec.flatten()
  */
  /* Build and return the list data structure */
  return(Py_BuildValue("OO",oangs0,oangs1));
}
Esempio n. 9
0
/*
    Takes a list of unit reciprocal lattice vectors in crystal frame to the
    specified detector-relative frame, subject to the conditions:

    1) the reciprocal lattice vector must be able to satisfy a bragg condition
    2) the associated diffracted beam must intersect the detector plane

    Required Arguments:
    gVec_c -- (n, 3) ndarray of n reciprocal lattice vectors in the CRYSTAL FRAME
    rMat_d -- (3, 3) ndarray, the COB taking DETECTOR FRAME components to LAB FRAME
    rMat_s -- (3, 3) ndarray, the COB taking SAMPLE FRAME components to LAB FRAME
    rMat_c -- (3, 3) ndarray, the COB taking CRYSTAL FRAME components to SAMPLE FRAME
    tVec_d -- (3, 1) ndarray, the translation vector connecting LAB to DETECTOR
    tVec_s -- (3, 1) ndarray, the translation vector connecting LAB to SAMPLE
    tVec_c -- (3, 1) ndarray, the translation vector connecting SAMPLE to CRYSTAL

    Outputs:
    (m, 2) ndarray containing the intersections of m <= n diffracted beams
    associated with gVecs
*/
static PyObject * gvecToDetectorXY(PyObject * self, PyObject * args)
{
  PyArrayObject *gVec_c,
                *rMat_d, *rMat_s, *rMat_c,
                *tVec_d, *tVec_s, *tVec_c, 
                *beamVec;
  PyArrayObject *result;

  int dgc, drd, drs, drc, dtd, dts, dtc, dbv;
  npy_intp npts, dims[2];

  double *gVec_c_Ptr,
         *rMat_d_Ptr, *rMat_s_Ptr, *rMat_c_Ptr,
         *tVec_d_Ptr, *tVec_s_Ptr, *tVec_c_Ptr,
         *beamVec_Ptr;
  double *result_Ptr;

  /* Parse arguments */
  if ( !PyArg_ParseTuple(args,"OOOOOOOO",
			 &gVec_c,
			 &rMat_d, &rMat_s, &rMat_c,
			 &tVec_d, &tVec_s, &tVec_c,
			 &beamVec)) return(NULL);
  if ( gVec_c  == NULL ||
       rMat_d  == NULL || rMat_s == NULL || rMat_c == NULL ||
       tVec_d  == NULL || tVec_s == NULL || tVec_c == NULL ||
       beamVec == NULL ) return(NULL);

  /* Verify shape of input arrays */
  dgc = PyArray_NDIM(gVec_c);
  drd = PyArray_NDIM(rMat_d);
  drs = PyArray_NDIM(rMat_s);
  drc = PyArray_NDIM(rMat_c);
  dtd = PyArray_NDIM(tVec_d);
  dts = PyArray_NDIM(tVec_s);
  dtc = PyArray_NDIM(tVec_c);
  dbv = PyArray_NDIM(beamVec);
  assert( dgc == 2 );
  assert( drd == 2 && drs == 2 && drc == 2 );
  assert( dtd == 1 && dts == 1 && dtc == 1 );
  assert( dbv == 1 );

  /* Verify dimensions of input arrays */
  npts = PyArray_DIMS(gVec_c)[0];

  assert( PyArray_DIMS(gVec_c)[1]  == 3 );
  assert( PyArray_DIMS(rMat_d)[0]  == 3 && PyArray_DIMS(rMat_d)[1] == 3 );
  assert( PyArray_DIMS(rMat_s)[0]  == 3 && PyArray_DIMS(rMat_s)[1] == 3 );
  assert( PyArray_DIMS(rMat_c)[0]  == 3 && PyArray_DIMS(rMat_c)[1] == 3 );
  assert( PyArray_DIMS(tVec_d)[0]  == 3 );
  assert( PyArray_DIMS(tVec_s)[0]  == 3 );
  assert( PyArray_DIMS(tVec_c)[0]  == 3 );
  assert( PyArray_DIMS(beamVec)[0] == 3 );

  /* Allocate C-style array for return data */
  // result_Ptr  = malloc(2*npts*sizeof(double));
  dims[0] = npts; dims[1] = 2;
  result = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0);

  /* Grab data pointers into various arrays */
  gVec_c_Ptr  = (double*)PyArray_DATA(gVec_c);

  rMat_d_Ptr  = (double*)PyArray_DATA(rMat_d);
  rMat_s_Ptr  = (double*)PyArray_DATA(rMat_s);
  rMat_c_Ptr  = (double*)PyArray_DATA(rMat_c);

  tVec_d_Ptr  = (double*)PyArray_DATA(tVec_d);
  tVec_s_Ptr  = (double*)PyArray_DATA(tVec_s);
  tVec_c_Ptr  = (double*)PyArray_DATA(tVec_c);

  beamVec_Ptr = (double*)PyArray_DATA(beamVec);

  result_Ptr     = (double*)PyArray_DATA(result);

  /* Call the computational routine */
  gvecToDetectorXY_cfunc(npts, gVec_c_Ptr,
			 rMat_d_Ptr, rMat_s_Ptr, rMat_c_Ptr,
			 tVec_d_Ptr, tVec_s_Ptr, tVec_c_Ptr,
			 beamVec_Ptr,
			 result_Ptr);

  /* Use the returned pointer to build the result object */
  /* We do this since nadm may be less than npts and the result_Ptr
     may not be the same as the one allocated earlier. */

  /* if ( nadm < npts ) { */
  /*   new_result_Ptr = (double*)realloc(result_Ptr,2*nadm*sizeof(double)); */
  /*   if ( new_result_Ptr != NULL ) result_Ptr = new_result_Ptr; */
  /*   else */
  /*     assert( false ); /\* This really should never happen *\/ */
  /* } */

  /* dims[0] = nadm; */
  /* dims[1] = 2; */
  /* result = (PyArrayObject*)PyArray_SimpleNewFromData(2,dims,NPY_DOUBLE,result_Ptr); */

  /* Build and return the nested data structure */
  return((PyObject*)result);
}
Esempio n. 10
0
 BaseType* data() {
     return reinterpret_cast<BaseType*>PyArray_DATA(this->array_);
 }
Esempio n. 11
0
/*
    Takes a list cartesian (x, y) pairs in the detector coordinates and calculates
    the associated reciprocal lattice (G) vectors and (bragg angle, azimuth) pairs
    with respect to the specified beam and azimth (eta) reference directions

    Required Arguments:
    xy_det -- (n, 2) ndarray or list-like input of n detector (x, y) points
    rMat_d -- (3, 3) ndarray, the COB taking DETECTOR FRAME components to LAB FRAME
    rMat_s -- (3, 3) ndarray, the COB taking SAMPLE FRAME components to LAB FRAME
    tVec_d -- (3, 1) ndarray, the translation vector connecting LAB to DETECTOR
    tVec_s -- (3, 1) ndarray, the translation vector connecting LAB to SAMPLE
    tVec_c -- (3, 1) ndarray, the translation vector connecting SAMPLE to CRYSTAL

    Optional Keyword Arguments:
    beamVec -- (1, 3) mdarray containing the incident beam direction components in the LAB FRAME
    etaVec  -- (1, 3) mdarray containing the reference azimuth direction components in the LAB FRAME

    Outputs:
    (n, 2) ndarray containing the (tTh, eta) pairs associated with each (x, y)
    (n, 3) ndarray containing the associated G vector directions in the LAB FRAME
    associated with gVecs
*/
static PyObject * detectorXYToGvec(PyObject * self, PyObject * args)
{
  PyArrayObject *xy_det, *rMat_d, *rMat_s,
		*tVec_d, *tVec_s, *tVec_c,
                *beamVec, *etaVec;
  PyArrayObject *tTh, *eta, *gVec_l;

  int dxy, drd, drs, dtd, dts, dtc, dbv, dev;
  npy_intp npts, dims[2];

  double *xy_Ptr, *rMat_d_Ptr, *rMat_s_Ptr,
         *tVec_d_Ptr, *tVec_s_Ptr, *tVec_c_Ptr,
         *beamVec_Ptr, *etaVec_Ptr;
  double *tTh_Ptr, *eta_Ptr, *gVec_l_Ptr;

  /* Parse arguments */
  if ( !PyArg_ParseTuple(args,"OOOOOOOO",
			 &xy_det,
			 &rMat_d, &rMat_s,
			 &tVec_d, &tVec_s, &tVec_c,
			 &beamVec, &etaVec)) return(NULL);
  if ( xy_det  == NULL || rMat_d == NULL || rMat_s == NULL ||
       tVec_d  == NULL || tVec_s == NULL || tVec_c == NULL ||
       beamVec == NULL || etaVec == NULL ) return(NULL);

  /* Verify shape of input arrays */
  dxy = PyArray_NDIM(xy_det);
  drd = PyArray_NDIM(rMat_d);
  drs = PyArray_NDIM(rMat_s);
  dtd = PyArray_NDIM(tVec_d);
  dts = PyArray_NDIM(tVec_s);
  dtc = PyArray_NDIM(tVec_c);
  dbv = PyArray_NDIM(beamVec);
  dev = PyArray_NDIM(etaVec);
  assert( dxy == 2 && drd == 2 && drs == 2 &&
	  dtd == 1 && dts == 1 && dtc == 1 &&
	  dbv == 1 && dev == 1);

  /* Verify dimensions of input arrays */
  npts = PyArray_DIMS(xy_det)[0];

  assert( PyArray_DIMS(xy_det)[1]  == 2 );
  assert( PyArray_DIMS(rMat_d)[0]  == 3 && PyArray_DIMS(rMat_d)[1] == 3 );
  assert( PyArray_DIMS(rMat_s)[0]  == 3 && PyArray_DIMS(rMat_s)[1] == 3 );
  assert( PyArray_DIMS(tVec_d)[0]  == 3 );
  assert( PyArray_DIMS(tVec_s)[0]  == 3 );
  assert( PyArray_DIMS(tVec_c)[0]  == 3 );
  assert( PyArray_DIMS(beamVec)[0] == 3 );
  assert( PyArray_DIMS(etaVec)[0]  == 3 );

  /* Allocate arrays for return values */
  dims[0] = npts; dims[1] = 3;
  gVec_l = (PyArrayObject*)PyArray_EMPTY(2,dims,NPY_DOUBLE,0);

  tTh    = (PyArrayObject*)PyArray_EMPTY(1,&npts,NPY_DOUBLE,0);
  eta    = (PyArrayObject*)PyArray_EMPTY(1,&npts,NPY_DOUBLE,0);

  /* Grab data pointers into various arrays */
  xy_Ptr      = (double*)PyArray_DATA(xy_det);
  gVec_l_Ptr  = (double*)PyArray_DATA(gVec_l);

  tTh_Ptr     = (double*)PyArray_DATA(tTh);
  eta_Ptr     = (double*)PyArray_DATA(eta);

  rMat_d_Ptr  = (double*)PyArray_DATA(rMat_d);
  rMat_s_Ptr  = (double*)PyArray_DATA(rMat_s);

  tVec_d_Ptr  = (double*)PyArray_DATA(tVec_d);
  tVec_s_Ptr  = (double*)PyArray_DATA(tVec_s);
  tVec_c_Ptr  = (double*)PyArray_DATA(tVec_c);

  beamVec_Ptr = (double*)PyArray_DATA(beamVec);
  etaVec_Ptr  = (double*)PyArray_DATA(etaVec);

  /* Call the computational routine */
  detectorXYToGvec_cfunc(npts, xy_Ptr,
			 rMat_d_Ptr, rMat_s_Ptr,
			 tVec_d_Ptr, tVec_s_Ptr, tVec_c_Ptr,
			 beamVec_Ptr, etaVec_Ptr,
			 tTh_Ptr, eta_Ptr, gVec_l_Ptr);

  /* Build and return the nested data structure */
  return(Py_BuildValue("OO",Py_BuildValue("OO",tTh,eta),gVec_l));
}
Esempio n. 12
0
 void* raw_data() const { return PyArray_DATA(array_); }
Esempio n. 13
0
PyObject * vdw(PyObject* self, PyObject *args)
{
  PyArrayObject* n_obj;
  PyArrayObject* q0_obj;
  PyArrayObject* R_obj;
  PyArrayObject* cell_obj;
  PyArrayObject* pbc_obj;
  PyArrayObject* repeat_obj;
  PyArrayObject* phi_obj;
  double ddelta;
  double dD;
  int iA;
  int iB;
  PyArrayObject* rhistogram_obj;
  double drhist;
  PyArrayObject* Dhistogram_obj;
  double dDhist;
  if (!PyArg_ParseTuple(args, "OOOOOOOddiiOdOd", &n_obj, &q0_obj, &R_obj,
                        &cell_obj, &pbc_obj, &repeat_obj,
                        &phi_obj, &ddelta, &dD, &iA, &iB,
                        &rhistogram_obj, &drhist,
                        &Dhistogram_obj, &dDhist))
    return NULL;

  int ndelta = PyArray_DIMS(phi_obj)[0];
  int nD = PyArray_DIMS(phi_obj)[1];
  const double* n = (const double*)DOUBLEP(n_obj);
  const int ni = PyArray_SIZE(n_obj);
  const double* q0 = (const double*)DOUBLEP(q0_obj);
  const double (*R)[3] = (const double (*)[3])DOUBLEP(R_obj);
  const double* cell = (const double*)DOUBLEP(cell_obj);
  const char* pbc = (const char*)(PyArray_DATA(pbc_obj));
  const long* repeat = (const long*)(PyArray_DATA(repeat_obj));
  const double (*phi)[nD] = (const double (*)[nD])DOUBLEP(phi_obj);
  double* rhistogram = (double*)DOUBLEP(rhistogram_obj);
  double* Dhistogram = (double*)DOUBLEP(Dhistogram_obj);

  int nbinsr = PyArray_DIMS(rhistogram_obj)[0];
  int nbinsD = PyArray_DIMS(Dhistogram_obj)[0];

  double energy = 0.0;
  if (repeat[0] == 0 && repeat[1] == 0 && repeat[2] == 0)
    for (int i1 = iA; i1 < iB; i1++)
      {
        const double* R1 = R[i1];
        double q01 = q0[i1];
        for (int i2 = 0; i2 <= i1; i2++)
          {
            double rr = 0.0;
            for (int c = 0; c < 3; c++)
              {
                double f = R[i2][c] - R1[c];
                if (pbc[c])
                  f = fmod(f + 1.5 * cell[c], cell[c]) - 0.5 * cell[c];
                rr += f * f;
              }
            double r = sqrt(rr);
            double d1 = r * q01;
            double d2 = r * q0[i2];
            double D = 0.5 * (d1 + d2);
            double e12 = (vdwkernel(D, d1, d2, nD, ndelta, dD, ddelta, phi) *
                          n[i1] * n[i2]);
            if (i1 == i2)
              e12 /= 2.0;
            int bin = (int)(r / drhist);
            if (bin < nbinsr)
              rhistogram[bin] += e12; 
            bin = (int)(D / dDhist);
            if (bin < nbinsD)
              Dhistogram[bin] += e12; 
            energy += e12;
          }
      }
  else
    for (int i1 = iA; i1 < iB; i1++)
      {
        const double* R1 = R[i1];
        double q01 = q0[i1];
        for (int a1 = -repeat[0]; a1 <= repeat[0]; a1++)
          for (int a2 = -repeat[1]; a2 <= repeat[1]; a2++)
            for (int a3 = -repeat[2]; a3 <= repeat[2]; a3++)
              {
                double x = 0.5;
                int i2max = ni-1;
                if (a1 == 0 && a2 == 0 && a3 == 0)
                  {
                    i2max = i1;
                    x = 1.0;
                  }
                double R1a[3] = {R1[0] + a1 * cell[0],
                                 R1[1] + a2 * cell[1],
                                 R1[2] + a3 * cell[2]};
                for (int i2 = 0; i2 <= i2max; i2++)
                  {
                    double rr = 0.0;
                    for (int c = 0; c < 3; c++)
                      {
                        double f = R[i2][c] - R1a[c];
                        rr += f * f;
                      }
                    double r = sqrt(rr);
                    double d1 = r * q01;
                    double d2 = r * q0[i2];
                    double D = 0.5 * (d1 + d2);
                    double e12 = (vdwkernel(D, d1, d2,
                                            nD, ndelta, dD, ddelta, phi) *
                                  n[i1] * n[i2] * x);
                    int bin = (int)(r / drhist);
                    if (bin < nbinsr)
                      rhistogram[bin] += e12; 
                    bin = (int)(D / dDhist);
                    if (bin < nbinsD)
                      Dhistogram[bin] += e12; 
                    energy += e12;
                  }
              }
      }
  return PyFloat_FromDouble(energy);
}
Esempio n. 14
0
PyObject *embedBoundsMatrix(python::object boundsMatArg, int maxIters = 10,
                            bool randomizeOnFailure = false,
                            int numZeroFail = 2,
                            python::list weights = python::list(),
                            int randomSeed = -1) {
  PyObject *boundsMatObj = boundsMatArg.ptr();
  if (!PyArray_Check(boundsMatObj))
    throw_value_error("Argument isn't an array");

  PyArrayObject *boundsMat = reinterpret_cast<PyArrayObject *>(boundsMatObj);
  // get the dimensions of the array
  unsigned int nrows = PyArray_DIM(boundsMat, 0);
  unsigned int ncols = PyArray_DIM(boundsMat, 1);
  if (nrows != ncols) throw_value_error("The array has to be square");
  if (nrows <= 0) throw_value_error("The array has to have a nonzero size");
  if (PyArray_DESCR(boundsMat)->type_num != NPY_DOUBLE)
    throw_value_error("Only double arrays are currently supported");

  unsigned int dSize = nrows * nrows;
  auto *cData = new double[dSize];
  double *inData = reinterpret_cast<double *>(PyArray_DATA(boundsMat));
  memcpy(static_cast<void *>(cData), static_cast<const void *>(inData),
         dSize * sizeof(double));

  DistGeom::BoundsMatrix::DATA_SPTR sdata(cData);
  DistGeom::BoundsMatrix bm(nrows, sdata);

  auto *positions = new RDGeom::Point3D[nrows];
  std::vector<RDGeom::Point *> posPtrs;
  for (unsigned int i = 0; i < nrows; i++) {
    posPtrs.push_back(&positions[i]);
  }

  RDNumeric::DoubleSymmMatrix distMat(nrows, 0.0);

  // ---- ---- ---- ---- ---- ---- ---- ---- ----
  // start the embedding:
  bool gotCoords = false;
  for (int iter = 0; iter < maxIters && !gotCoords; iter++) {
    // pick a random distance matrix
    DistGeom::pickRandomDistMat(bm, distMat, randomSeed);

    // and embed it:
    gotCoords = DistGeom::computeInitialCoords(
        distMat, posPtrs, randomizeOnFailure, numZeroFail, randomSeed);

    // update the seed:
    if (randomSeed >= 0) randomSeed += iter * 999;
  }

  if (gotCoords) {
    std::map<std::pair<int, int>, double> weightMap;
    unsigned int nElems = PySequence_Size(weights.ptr());
    for (unsigned int entryIdx = 0; entryIdx < nElems; entryIdx++) {
      PyObject *entry = PySequence_GetItem(weights.ptr(), entryIdx);
      if (!PySequence_Check(entry) || PySequence_Size(entry) != 3) {
        throw_value_error("weights argument must be a sequence of 3-sequences");
      }
      int idx1 = PyInt_AsLong(PySequence_GetItem(entry, 0));
      int idx2 = PyInt_AsLong(PySequence_GetItem(entry, 1));
      double w = PyFloat_AsDouble(PySequence_GetItem(entry, 2));
      weightMap[std::make_pair(idx1, idx2)] = w;
    }
    DistGeom::VECT_CHIRALSET csets;
    ForceFields::ForceField *field =
        DistGeom::constructForceField(bm, posPtrs, csets, 0.0, 0.0, &weightMap);
    CHECK_INVARIANT(field, "could not build dgeom force field");
    field->initialize();
    if (field->calcEnergy() > 1e-5) {
      int needMore = 1;
      while (needMore) {
        needMore = field->minimize();
      }
    }
    delete field;
  } else {
    throw_value_error("could not embed matrix");
  }

  // ---- ---- ---- ---- ---- ---- ---- ---- ----
  // construct the results matrix:
  npy_intp dims[2];
  dims[0] = nrows;
  dims[1] = 3;
  PyArrayObject *res = (PyArrayObject *)PyArray_SimpleNew(2, dims, NPY_DOUBLE);
  double *resData = reinterpret_cast<double *>(PyArray_DATA(res));
  for (unsigned int i = 0; i < nrows; i++) {
    unsigned int iTab = i * 3;
    for (unsigned int j = 0; j < 3; ++j) {
      resData[iTab + j] = positions[i][j];  //.x;
    }
  }
  delete[] positions;

  return PyArray_Return(res);
}
static PyObject* find_changes(PyObject* self, PyObject* args) {
    PyObject* arg1 = NULL;
    PyObject* arg2 = NULL;
    if (!PyArg_ParseTuple(args, "OO", &arg1, &arg2)) return NULL;
    PyObject* np_data = PyArray_FROM_OTF(arg1, NPY_FLOAT32, NPY_IN_ARRAY);
    PyObject* np_penalties = PyArray_FROM_OTF(arg2, NPY_FLOAT32, NPY_IN_ARRAY);
    if (np_data == NULL || np_penalties == NULL) {
        Py_XDECREF(np_data);
        Py_XDECREF(np_penalties);
        return NULL;
    }
    int T = PyArray_DIM(np_data, 0);
    if (T != PyArray_DIM(np_penalties, 0) + 1) {
        PyErr_SetString(PyExc_ValueError, "Dimensions of data and penalty are not compatible");
        Py_DECREF(np_data);
        Py_DECREF(np_penalties);
        return NULL;
    }
    float* data = (float*) PyArray_DATA(np_data);
    float* penalties = (float*) PyArray_DATA(np_penalties);
    double* vals = new double[T];
    int* prev = new int[T];
    std::list<SuffStat> checks;
    checks.push_back(SuffStat(0));
    for (int t = 0; t < MIN_SEP - 1; ++t)
        checks.back().add(data[t]);
    for (int t = MIN_SEP - 1; t < T; ++t) {
        double max_val = -std::numeric_limits<double>::max();
        int max_ind = -1;
        for (std::list<SuffStat>::iterator iter = checks.begin(); iter != checks.end(); ++iter) {
            if (iter->prune_t == t) {
                iter = checks.erase(iter);
                --iter;
                continue;
            }
            iter->add(data[t]);
            double val = iter->ll();
            if (iter->t > 0)
                val += vals[iter->t - 1] - penalties[iter->t - 1];
            iter->cost = val;
            if (val > max_val) {
                max_val = val;
                max_ind = iter->t;
            }
        }
        vals[t] = max_val;
        prev[t] = max_ind;
        for (std::list<SuffStat>::iterator iter = checks.begin(); iter != checks.end(); ++iter) {
            if (t < T-1 && iter->prune_t == -1 && iter->cost < vals[t] - penalties[t])
                iter->prune_t = t + MIN_SEP;
        }
        if (t - MIN_SEP + 2 >= MIN_SEP) {
            checks.push_back(SuffStat(t-MIN_SEP+2));
            for (int s = t - MIN_SEP + 2; s <= t; ++s)
                checks.back().add(data[s]);
        }
    }
    PyObject* changes = PyList_New(0);
    int ind = prev[T-1];
    while (ind > 1) {
        PyObject* num = PyInt_FromLong(ind);
        PyList_Append(changes, num);
        Py_DECREF(num);
        ind = prev[ind-1];
    }
    PyList_Reverse(changes);
    delete[] vals;
    delete[] prev;
    Py_DECREF(np_data);
    Py_DECREF(np_penalties);
    return changes;
}
static PyObject* w_parstack(PyObject *module, PyObject *args) {

    PyObject *arrays, *offsets, *shifts, *weights, *arr;
    PyObject *result;
    int method, nparallel;
    size_t narrays, nshifts, nweights;
    size_t *clengths;
    size_t lengthout;
    int32_t offsetout;
    int lengthout_arg;
    int32_t *coffsets, *cshifts;
    double *cweights, *cresult;
    double **carrays;
    npy_intp array_dims[1];
    size_t i;
    int err;

    carrays = NULL;
    clengths = NULL;
    struct module_state *st = GETSTATE(module);

    if (!PyArg_ParseTuple(args, "OOOOiiiOi", &arrays, &offsets, &shifts,
                          &weights, &method, &lengthout_arg, &offsetout, &result, &nparallel)) {

        PyErr_SetString(
            st->error,
            "usage parstack(arrays, offsets, shifts, weights, method, lengthout, offsetout, result, nparallel)" );

        return NULL;
    }
    if (!good_array(offsets, NPY_INT32)) return NULL;
    if (!good_array(shifts, NPY_INT32)) return NULL;
    if (!good_array(weights, NPY_DOUBLE)) return NULL;
    if (result != Py_None && !good_array(result, NPY_DOUBLE)) return NULL;

    coffsets = PyArray_DATA((PyArrayObject*)offsets);
    narrays = PyArray_SIZE((PyArrayObject*)offsets);

    cshifts = PyArray_DATA((PyArrayObject*)shifts);
    nshifts = PyArray_SIZE((PyArrayObject*)shifts);

    cweights = PyArray_DATA((PyArrayObject*)weights);
    nweights = PyArray_SIZE((PyArrayObject*)weights);

    nshifts /= narrays;
    nweights /= narrays;

    if (nshifts != nweights) {
        PyErr_SetString(st->error, "weights.size != shifts.size" );
        return NULL;
    }

    if (!PyList_Check(arrays)) {
        PyErr_SetString(st->error, "arg #1 must be a list of NumPy arrays.");
        return NULL;
    }

    if ((size_t)PyList_Size(arrays) != narrays) {
        PyErr_SetString(st->error, "len(offsets) != len(arrays)");
        return NULL;
    }

    carrays = (double**)calloc(narrays, sizeof(double*));
    if (carrays == NULL) {
        PyErr_SetString(st->error, "alloc failed");
        return NULL;
    }

    clengths = (size_t*)calloc(narrays, sizeof(size_t));
    if (clengths == NULL) {
        PyErr_SetString(st->error, "alloc failed");
        free(carrays);
        return NULL;
    }

    for (i=0; i<narrays; i++) {
        arr = PyList_GetItem(arrays, i);
        if (!good_array(arr, NPY_DOUBLE)) {
            free(carrays);
            free(clengths);
            return NULL;
        }
        carrays[i] = PyArray_DATA((PyArrayObject*)arr);
        clengths[i] = PyArray_SIZE((PyArrayObject*)arr);
    }
    if (lengthout_arg < 0) {
        err = parstack_config(narrays, coffsets, clengths, nshifts, cshifts,
                              cweights, method, &lengthout, &offsetout);

        if (err != 0) {
            PyErr_SetString(st->error, "parstack_config() failed");
            free(carrays);
            free(clengths);
            return NULL;
        }
    } else {
        lengthout = (size_t)lengthout_arg;
    }

    if (method == 0) {
        array_dims[0] = nshifts * lengthout;
    } else {
        array_dims[0] = nshifts;
    }

    if (result != Py_None) {
        if (PyArray_SIZE((PyArrayObject*)result) != array_dims[0]) {
            free(carrays);
            free(clengths);
            return NULL;
        }
        Py_INCREF(result);
    } else {
        result = PyArray_SimpleNew(1, array_dims, NPY_FLOAT64);
        cresult = PyArray_DATA((PyArrayObject*)result);

        for (i=0; i<(size_t)array_dims[0]; i++) {
            cresult[i] = 0.0;
        }

        if (result == NULL) {
            free(carrays);
            free(clengths);
            return NULL;
        }
    }
    cresult = PyArray_DATA((PyArrayObject*)result);

    err = parstack(narrays, carrays, coffsets, clengths, nshifts, cshifts,
                   cweights, method, lengthout, offsetout, cresult, nparallel);

    if (err != 0) {
        PyErr_SetString(st->error, "parstack() failed");
        free(carrays);
        free(clengths);
        Py_DECREF(result);
        return NULL;
    }

    free(carrays);
    free(clengths);
    return Py_BuildValue("Ni", (PyObject *)result, offsetout);
}
Esempio n. 17
0
static int
array_getbuffer(PyObject *obj, Py_buffer *view, int flags)
{
    PyArrayObject *self;
    _buffer_info_t *info = NULL;

    self = (PyArrayObject*)obj;

    /* Check whether we can provide the wanted properties */
    if ((flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS &&
            !PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) {
        PyErr_SetString(PyExc_ValueError, "ndarray is not C-contiguous");
        goto fail;
    }
    if ((flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS &&
            !PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)) {
        PyErr_SetString(PyExc_ValueError, "ndarray is not Fortran contiguous");
        goto fail;
    }
    if ((flags & PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS
            && !PyArray_ISONESEGMENT(self)) {
        PyErr_SetString(PyExc_ValueError, "ndarray is not contiguous");
        goto fail;
    }
    if ((flags & PyBUF_STRIDES) != PyBUF_STRIDES &&
            !PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) {
        /* Non-strided N-dim buffers must be C-contiguous */
        PyErr_SetString(PyExc_ValueError, "ndarray is not C-contiguous");
        goto fail;
    }
    if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) {
        if (PyArray_FailUnlessWriteable(self, "buffer source array") < 0) {
            goto fail;
        }
    }
    /*
     * If a read-only buffer is requested on a read-write array, we return a
     * read-write buffer, which is dubious behavior. But that's why this call
     * is guarded by PyArray_ISWRITEABLE rather than (flags &
     * PyBUF_WRITEABLE).
     */
    if (PyArray_ISWRITEABLE(self)) {
        if (array_might_be_written(self) < 0) {
            goto fail;
        }
    }

    if (view == NULL) {
        PyErr_SetString(PyExc_ValueError, "NULL view in getbuffer");
        goto fail;
    }

    /* Fill in information */
    info = _buffer_get_info(obj);
    if (info == NULL) {
        goto fail;
    }

    view->buf = PyArray_DATA(self);
    view->suboffsets = NULL;
    view->itemsize = PyArray_ITEMSIZE(self);
    view->readonly = !PyArray_ISWRITEABLE(self);
    view->internal = NULL;
    view->len = PyArray_NBYTES(self);
    if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
        view->format = info->format;
    } else {
        view->format = NULL;
    }
    if ((flags & PyBUF_ND) == PyBUF_ND) {
        view->ndim = info->ndim;
        view->shape = info->shape;
    }
    else {
        view->ndim = 0;
        view->shape = NULL;
    }
    if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
        view->strides = info->strides;
    }
    else {
        view->strides = NULL;
    }
    view->obj = (PyObject*)self;

    Py_INCREF(self);
    return 0;

fail:
    return -1;
}
Esempio n. 18
0
int
NI_GeometricTransform(PyArrayObject *input, int (*map)(npy_intp*, double*,
                int, int, void*), void* map_data, PyArrayObject* matrix_ar,
                PyArrayObject* shift_ar, PyArrayObject *coordinates,
                PyArrayObject *output, int order, int mode, double cval)
{
    char *po, *pi, *pc = NULL;
    npy_intp **edge_offsets = NULL, **data_offsets = NULL, filter_size;
    npy_intp ftmp[MAXDIM], *fcoordinates = NULL, *foffsets = NULL;
    npy_intp cstride = 0, kk, hh, ll, jj;
    npy_intp size;
    double **splvals = NULL, icoor[MAXDIM];
    npy_intp idimensions[MAXDIM], istrides[MAXDIM];
    NI_Iterator io, ic;
    Float64 *matrix = matrix_ar ? (Float64*)PyArray_DATA(matrix_ar) : NULL;
    Float64 *shift = shift_ar ? (Float64*)PyArray_DATA(shift_ar) : NULL;
    int irank = 0, orank, qq;

    for(kk = 0; kk < input->nd; kk++) {
        idimensions[kk] = input->dimensions[kk];
        istrides[kk] = input->strides[kk];
    }
    irank = input->nd;
    orank = output->nd;

    /* if the mapping is from array coordinates: */
    if (coordinates) {
        /* initialze a line iterator along the first axis: */
        if (!NI_InitPointIterator(coordinates, &ic))
            goto exit;
        cstride = ic.strides[0];
        if (!NI_LineIterator(&ic, 0))
            goto exit;
        pc = (void *)(PyArray_DATA(coordinates));
    }

    /* offsets used at the borders: */
    edge_offsets = (npy_intp**)malloc(irank * sizeof(npy_intp*));
    data_offsets = (npy_intp**)malloc(irank * sizeof(npy_intp*));
    if (!edge_offsets || !data_offsets) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        data_offsets[jj] = NULL;
    for(jj = 0; jj < irank; jj++) {
        data_offsets[jj] = (npy_intp*)malloc((order + 1) * sizeof(npy_intp));
        if (!data_offsets[jj]) {
            PyErr_NoMemory();
            goto exit;
        }
    }
    /* will hold the spline coefficients: */
    splvals = (double**)malloc(irank * sizeof(double*));
    if (!splvals) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        splvals[jj] = NULL;
    for(jj = 0; jj < irank; jj++) {
        splvals[jj] = (double*)malloc((order + 1) * sizeof(double));
        if (!splvals[jj]) {
            PyErr_NoMemory();
            goto exit;
        }
    }

    filter_size = 1;
    for(jj = 0; jj < irank; jj++)
        filter_size *= order + 1;

    /* initialize output iterator: */
    if (!NI_InitPointIterator(output, &io))
        goto exit;

    /* get data pointers: */
    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);

    /* make a table of all possible coordinates within the spline filter: */
    fcoordinates = (npy_intp*)malloc(irank * filter_size * sizeof(npy_intp));
    /* make a table of all offsets within the spline filter: */
    foffsets = (npy_intp*)malloc(filter_size * sizeof(npy_intp));
    if (!fcoordinates || !foffsets) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < irank; jj++)
        ftmp[jj] = 0;
    kk = 0;
    for(hh = 0; hh < filter_size; hh++) {
        for(jj = 0; jj < irank; jj++)
            fcoordinates[jj + hh * irank] = ftmp[jj];
        foffsets[hh] = kk;
        for(jj = irank - 1; jj >= 0; jj--) {
            if (ftmp[jj] < order) {
                ftmp[jj]++;
                kk += istrides[jj];
                break;
            } else {
                ftmp[jj] = 0;
                kk -= istrides[jj] * order;
            }
        }
    }

    size = 1;
    for(qq = 0; qq < output->nd; qq++)
        size *= output->dimensions[qq];
    for(kk = 0; kk < size; kk++) {
        double t = 0.0;
        int constant = 0, edge = 0, offset = 0;
        if (map) {
            /* call mappint functions: */
            if (!map(io.coordinates, icoor, orank, irank, map_data)) {
                if (!PyErr_Occurred())
                    PyErr_SetString(PyExc_RuntimeError,
                                                    "unknown error in mapping function");
                goto exit;
            }
        } else if (matrix) {
            /* do an affine transformation: */
            Float64 *p = matrix;
            for(hh = 0; hh < irank; hh++) {
                icoor[hh] = 0.0;
                for(ll = 0; ll < orank; ll++)
                    icoor[hh] += io.coordinates[ll] * *p++;
                icoor[hh] += shift[hh];
            }
        } else if (coordinates) {
            /* mapping is from an coordinates array: */
            char *p = pc;
            switch (NI_NormalizeType(coordinates->descr->type_num)) {
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Bool);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, UInt8);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, UInt16);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, UInt32);
#if HAS_UINT64
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, UInt64);
#endif
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Int8);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Int16);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Int32);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Int64);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Float32);
                CASE_MAP_COORDINATES(p, icoor, irank, cstride, Float64);
            default:
                PyErr_SetString(PyExc_RuntimeError,
                                                "coordinate array data type not supported");
                goto exit;
            }
        }
        /* iterate over axes: */
        for(hh = 0; hh < irank; hh++) {
            /* if the input coordinate is outside the borders, map it: */
            double cc = map_coordinate(icoor[hh], idimensions[hh], mode);
            if (cc > -1.0) {
                /* find the filter location along this axis: */
                int start;
                if (order & 1) {
                    start = (int)floor(cc) - order / 2;
                } else {
                    start = (int)floor(cc + 0.5) - order / 2;
                }
                /* get the offset to the start of the filter: */
                offset += istrides[hh] * start;
                if (start < 0 || start + order >= idimensions[hh]) {
                    /* implement border mapping, if outside border: */
                    edge = 1;
                    edge_offsets[hh] = data_offsets[hh];
                    for(ll = 0; ll <= order; ll++) {
                        int idx = start + ll;
                        int len = idimensions[hh];
                        if (len <= 1) {
                            idx = 0;
                        } else {
                            int s2 = 2 * len - 2;
                            if (idx < 0) {
                                idx = s2 * (int)(-idx / s2) + idx;
                                idx = idx <= 1 - len ? idx + s2 : -idx;
                            } else if (idx >= len) {
                                idx -= s2 * (int)(idx / s2);
                                if (idx >= len)
                                    idx = s2 - idx;
                            }
                        }
                        /* calculate and store the offests at this edge: */
                        edge_offsets[hh][ll] = istrides[hh] * (idx - start);
                    }
                } else {
                    /* we are not at the border, use precalculated offsets: */
                    edge_offsets[hh] = NULL;
                }
                spline_coefficients(cc, order, splvals[hh]);
            } else {
                /* we use the constant border condition: */
                constant = 1;
                break;
            }
        }

        if (!constant) {
            npy_intp *ff = fcoordinates;
            const int type_num = NI_NormalizeType(input->descr->type_num);
            t = 0.0;
            for(hh = 0; hh < filter_size; hh++) {
                double coeff = 0.0;
                int idx = 0;

                if (NI_UNLIKELY(edge)) {
                    for(ll = 0; ll < irank; ll++) {
                        if (edge_offsets[ll])
                            idx += edge_offsets[ll][ff[ll]];
                        else
                            idx += ff[ll] * istrides[ll];
                    }
                } else {
                    idx = foffsets[hh];
                }
                idx += offset;
                switch (type_num) {
                    CASE_INTERP_COEFF(coeff, pi, idx, Bool);
                    CASE_INTERP_COEFF(coeff, pi, idx, UInt8);
                    CASE_INTERP_COEFF(coeff, pi, idx, UInt16);
                    CASE_INTERP_COEFF(coeff, pi, idx, UInt32);
#if HAS_UINT64
                    CASE_INTERP_COEFF(coeff, pi, idx, UInt64);
#endif
                    CASE_INTERP_COEFF(coeff, pi, idx, Int8);
                    CASE_INTERP_COEFF(coeff, pi, idx, Int16);
                    CASE_INTERP_COEFF(coeff, pi, idx, Int32);
                    CASE_INTERP_COEFF(coeff, pi, idx, Int64);
                    CASE_INTERP_COEFF(coeff, pi, idx, Float32);
                    CASE_INTERP_COEFF(coeff, pi, idx, Float64);
                default:
                    PyErr_SetString(PyExc_RuntimeError,
                                                    "data type not supported");
                    goto exit;
                }
                /* calculate the interpolated value: */
                for(ll = 0; ll < irank; ll++)
                    if (order > 0)
                        coeff *= splvals[ll][ff[ll]];
                t += coeff;
                ff += irank;
            }
        } else {
            t = cval;
        }
        /* store output value: */
        switch (NI_NormalizeType(output->descr->type_num)) {
            CASE_INTERP_OUT(po, t, Bool);
            CASE_INTERP_OUT_UINT(po, t, UInt8, 0, MAX_UINT8);
            CASE_INTERP_OUT_UINT(po, t, UInt16, 0, MAX_UINT16);
            CASE_INTERP_OUT_UINT(po, t, UInt32, 0, MAX_UINT32);
#if HAS_UINT64
            /* There was a bug in numpy as of (at least) <= 1.6.1 such that
             * MAX_UINT64 was incorrectly defined, leading to a compiler error.
             * NPY_MAX_UINT64 is correctly defined
             */
            CASE_INTERP_OUT_UINT(po, t, UInt64, 0, NPY_MAX_UINT64);
#endif
            CASE_INTERP_OUT_INT(po, t, Int8, MIN_INT8, MAX_INT8);
            CASE_INTERP_OUT_INT(po, t, Int16, MIN_INT16, MAX_INT16);
            CASE_INTERP_OUT_INT(po, t, Int32, MIN_INT32, MAX_INT32);
            CASE_INTERP_OUT_INT(po, t, Int64, MIN_INT64, MAX_INT64);
            CASE_INTERP_OUT(po, t, Float32);
            CASE_INTERP_OUT(po, t, Float64);
        default:
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        if (coordinates) {
            NI_ITERATOR_NEXT2(io, ic, po, pc);
        } else {
            NI_ITERATOR_NEXT(io, po);
        }
    }

 exit:
    if (edge_offsets)
        free(edge_offsets);
    if (data_offsets) {
        for(jj = 0; jj < irank; jj++)
            free(data_offsets[jj]);
        free(data_offsets);
    }
    if (splvals) {
        for(jj = 0; jj < irank; jj++)
            free(splvals[jj]);
        free(splvals);
    }
    if (foffsets)
        free(foffsets);
    if (fcoordinates)
        free(fcoordinates);
    return PyErr_Occurred() ? 0 : 1;
}
Esempio n. 19
0
/* methods */
static PyObject*
libtfr_tfr_spec(PyObject *self, PyObject *args)
{
        /* arguments */
        PyObject *o = NULL;
        PyArrayObject *signal = NULL;
        PyArrayObject *signal_cast = NULL;
        PyObject *o2 = NULL;
        PyArrayObject *fgrid = NULL;
        PyArrayObject *fgrid_cast = NULL;
        int N;
        int step;
        int Np;
        int K = 6;
        double tm = 6.0;
        double flock = 0.01;
        int tlock = 5;

        /* output data */
        npy_intp out_shape[2];
        PyArrayObject *outdata = NULL;
        double *spec;

        /* internal stuff */
        mfft *mtmh;
        double *samples;
        double *fgridp = NULL;

        /* parse arguments */
        if (!PyArg_ParseTuple(args, "Oiii|iddiO", &o, &N, &step, &Np, &K, &tm, &flock, &tlock, &o2))
                return NULL;
        signal = (PyArrayObject*) PyArray_FromAny(o, NULL, 1, 1, NPY_CONTIGUOUS, NULL);
        if (signal==NULL) {
                PyErr_SetString(PyExc_TypeError, "Input signal must be an ndarray");
                return NULL;
        }
        int nfreq = N/2+1;

        if (o2!=NULL && o2!=Py_None) {
                fgrid = (PyArrayObject*) PyArray_FromAny(o2, NULL, 1, 1, NPY_CONTIGUOUS, NULL);
                if (fgrid!=NULL) {
                        fgridp = coerce_ndarray_double(fgrid, &fgrid_cast);
                        if (fgridp==NULL) {
                                PyErr_SetString(PyExc_TypeError, "Unable to cast frequency grid to supported data type");
                                goto fail;
                        }
                        nfreq = PyArray_SIZE(fgrid);
                }
        }

        /* coerce input data to proper type */
        samples = coerce_ndarray_double(signal, &signal_cast);
        if (samples==NULL) {
                PyErr_SetString(PyExc_TypeError, "Unable to cast signal to supported data type");
                goto fail;
        }

	/* initialize transform object - window size may be adjusted */
        mtmh = mtm_init_herm(N, Np, K, tm);

        /* allocate output array  */
        out_shape[0] = nfreq;
        out_shape[1] = SPEC_NFRAMES(mtmh,PyArray_SIZE(signal),step);
        outdata  = (PyArrayObject*) PyArray_ZEROS(2,out_shape,NPY_DOUBLE,1); // last arg give fortran-order
        spec = (double*) PyArray_DATA(outdata);


        /* do the transform */
        tfr_spec(mtmh, spec, samples, PyArray_SIZE(signal),
                 -1, step, flock, tlock, nfreq, fgridp);
        mtm_destroy(mtmh);

        Py_DECREF(signal);
        Py_XDECREF(signal_cast);
        Py_XDECREF(fgrid);
        Py_XDECREF(fgrid_cast);
        return PyArray_Return(outdata);
fail:
        Py_XDECREF(fgrid_cast);
        Py_XDECREF(fgrid);
        Py_XDECREF(signal_cast);
        Py_XDECREF(signal);
        return NULL;
}
Esempio n. 20
0
int NI_ZoomShift(PyArrayObject *input, PyArrayObject* zoom_ar,
                                 PyArrayObject* shift_ar, PyArrayObject *output,
                                 int order, int mode, double cval)
{
    char *po, *pi;
    npy_intp **zeros = NULL, **offsets = NULL, ***edge_offsets = NULL;
    npy_intp ftmp[MAXDIM], *fcoordinates = NULL, *foffsets = NULL;
    npy_intp jj, hh, kk, filter_size, odimensions[MAXDIM];
    npy_intp idimensions[MAXDIM], istrides[MAXDIM];
    npy_intp size;
    double ***splvals = NULL;
    NI_Iterator io;
    Float64 *zooms = zoom_ar ? (Float64*)PyArray_DATA(zoom_ar) : NULL;
    Float64 *shifts = shift_ar ? (Float64*)PyArray_DATA(shift_ar) : NULL;
    int rank = 0, qq;

    for(kk = 0; kk < input->nd; kk++) {
        idimensions[kk] = input->dimensions[kk];
        istrides[kk] = input->strides[kk];
        odimensions[kk] = output->dimensions[kk];
    }
    rank = input->nd;

    /* if the mode is 'constant' we need some temps later: */
    if (mode == NI_EXTEND_CONSTANT) {
        zeros = (npy_intp**)malloc(rank * sizeof(npy_intp*));
        if (!zeros) {
            PyErr_NoMemory();
            goto exit;
        }
        for(jj = 0; jj < rank; jj++)
            zeros[jj] = NULL;
        for(jj = 0; jj < rank; jj++) {
            zeros[jj] = (npy_intp*)malloc(odimensions[jj] * sizeof(npy_intp));
            if(!zeros[jj]) {
                PyErr_NoMemory();
                goto exit;
            }
        }
    }

    /* store offsets, along each axis: */
    offsets = (npy_intp**)malloc(rank * sizeof(npy_intp*));
    /* store spline coefficients, along each axis: */
    splvals = (double***)malloc(rank * sizeof(double**));
    /* store offsets at all edges: */
    edge_offsets = (npy_intp***)malloc(rank * sizeof(npy_intp**));
    if (!offsets || !splvals || !edge_offsets) {
        PyErr_NoMemory();
        goto exit;
    }
    for(jj = 0; jj < rank; jj++) {
        offsets[jj] = NULL;
        splvals[jj] = NULL;
        edge_offsets[jj] = NULL;
    }
    for(jj = 0; jj < rank; jj++) {
        offsets[jj] = (npy_intp*)malloc(odimensions[jj] * sizeof(npy_intp));
        splvals[jj] = (double**)malloc(odimensions[jj] * sizeof(double*));
        edge_offsets[jj] = (npy_intp**)malloc(odimensions[jj] * sizeof(npy_intp*));
        if (!offsets[jj] || !splvals[jj] || !edge_offsets[jj]) {
            PyErr_NoMemory();
            goto exit;
        }
        for(hh = 0; hh < odimensions[jj]; hh++) {
            splvals[jj][hh] = NULL;
            edge_offsets[jj][hh] = NULL;
        }
    }

    /* precalculate offsets, and offsets at the edge: */
    for(jj = 0; jj < rank; jj++) {
        double shift = 0.0, zoom = 0.0;
        if (shifts)
            shift = shifts[jj];
        if (zooms)
            zoom = zooms[jj];
        for(kk = 0; kk < odimensions[jj]; kk++) {
            double cc = (double)kk;
            if (shifts)
                cc += shift;
            if (zooms)
                cc *= zoom;
            cc = map_coordinate(cc, idimensions[jj], mode);
            if (cc > -1.0) {
                int start;
                if (zeros && zeros[jj])
                    zeros[jj][kk] = 0;
                if (order & 1) {
                    start = (int)floor(cc) - order / 2;
                } else {
                    start = (int)floor(cc + 0.5) - order / 2;
                }
                offsets[jj][kk] = istrides[jj] * start;
                if (start < 0 || start + order >= idimensions[jj]) {
                    edge_offsets[jj][kk] = (npy_intp*)malloc((order + 1) * sizeof(npy_intp));
                    if (!edge_offsets[jj][kk]) {
                        PyErr_NoMemory();
                        goto exit;
                    }
                    for(hh = 0; hh <= order; hh++) {
                        int idx = start + hh;
                         int len = idimensions[jj];
                        if (len <= 1) {
                            idx = 0;
                        } else {
                            int s2 = 2 * len - 2;
                            if (idx < 0) {
                                idx = s2 * (int)(-idx / s2) + idx;
                                idx = idx <= 1 - len ? idx + s2 : -idx;
                            } else if (idx >= len) {
                                idx -= s2 * (int)(idx / s2);
                                if (idx >= len)
                                    idx = s2 - idx;
                            }
                        }
                        edge_offsets[jj][kk][hh] = istrides[jj] * (idx - start);
                    }
                }
                if (order > 0) {
                    splvals[jj][kk] = (double*)malloc((order + 1) * sizeof(double));
                    if (!splvals[jj][kk]) {
                        PyErr_NoMemory();
                        goto exit;
                    }
                    spline_coefficients(cc, order, splvals[jj][kk]);
                }
            } else {
                zeros[jj][kk] = 1;
            }
        }
    }

    filter_size = 1;
    for(jj = 0; jj < rank; jj++)
        filter_size *= order + 1;

    if (!NI_InitPointIterator(output, &io))
        goto exit;

    pi = (void *)PyArray_DATA(input);
    po = (void *)PyArray_DATA(output);

    /* store all coordinates and offsets with filter: */
    fcoordinates = (npy_intp*)malloc(rank * filter_size * sizeof(npy_intp));
    foffsets = (npy_intp*)malloc(filter_size * sizeof(npy_intp));
    if (!fcoordinates || !foffsets) {
        PyErr_NoMemory();
        goto exit;
    }

    for(jj = 0; jj < rank; jj++)
        ftmp[jj] = 0;
    kk = 0;
    for(hh = 0; hh < filter_size; hh++) {
        for(jj = 0; jj < rank; jj++)
            fcoordinates[jj + hh * rank] = ftmp[jj];
        foffsets[hh] = kk;
        for(jj = rank - 1; jj >= 0; jj--) {
            if (ftmp[jj] < order) {
                ftmp[jj]++;
                kk += istrides[jj];
                break;
            } else {
                ftmp[jj] = 0;
                kk -= istrides[jj] * order;
            }
        }
    }
    size = 1;
    for(qq = 0; qq < output->nd; qq++)
        size *= output->dimensions[qq];
    for(kk = 0; kk < size; kk++) {
        double t = 0.0;
        int edge = 0, oo = 0, zero = 0;

        for(hh = 0; hh < rank; hh++) {
            if (zeros && zeros[hh][io.coordinates[hh]]) {
                /* we use constant border condition */
                zero = 1;
                break;
            }
            oo += offsets[hh][io.coordinates[hh]];
            if (edge_offsets[hh][io.coordinates[hh]])
                edge = 1;
        }

        if (!zero) {
            npy_intp *ff = fcoordinates;
            const int type_num = NI_NormalizeType(input->descr->type_num);
            t = 0.0;
            for(hh = 0; hh < filter_size; hh++) {
                int idx = 0;
                double coeff = 0.0;

                if (NI_UNLIKELY(edge)) {
                        /* use precalculated edge offsets: */
                    for(jj = 0; jj < rank; jj++) {
                        if (edge_offsets[jj][io.coordinates[jj]])
                            idx += edge_offsets[jj][io.coordinates[jj]][ff[jj]];
                        else
                            idx += ff[jj] * istrides[jj];
                    }
                    idx += oo;
                } else {
                    /* use normal offsets: */
                    idx += oo + foffsets[hh];
                }
                switch (type_num) {
                    CASE_INTERP_COEFF(coeff, pi, idx, Bool);
                    CASE_INTERP_COEFF(coeff, pi, idx, UInt8);
                    CASE_INTERP_COEFF(coeff, pi, idx, UInt16);
                    CASE_INTERP_COEFF(coeff, pi, idx, UInt32);
#if HAS_UINT64
                    CASE_INTERP_COEFF(coeff, pi, idx, UInt64);
#endif
                    CASE_INTERP_COEFF(coeff, pi, idx, Int8);
                    CASE_INTERP_COEFF(coeff, pi, idx, Int16);
                    CASE_INTERP_COEFF(coeff, pi, idx, Int32);
                    CASE_INTERP_COEFF(coeff, pi, idx, Int64);
                    CASE_INTERP_COEFF(coeff, pi, idx, Float32);
                    CASE_INTERP_COEFF(coeff, pi, idx, Float64);
                default:
                    PyErr_SetString(PyExc_RuntimeError,
                                                    "data type not supported");
                    goto exit;
                }
                /* calculate interpolated value: */
                for(jj = 0; jj < rank; jj++)
                    if (order > 0)
                        coeff *= splvals[jj][io.coordinates[jj]][ff[jj]];
                t += coeff;
                ff += rank;
            }
        } else {
            t = cval;
        }
        /* store output: */
        switch (NI_NormalizeType(output->descr->type_num)) {
            CASE_INTERP_OUT(po, t, Bool);
            CASE_INTERP_OUT_UINT(po, t, UInt8, 0, MAX_UINT8);
            CASE_INTERP_OUT_UINT(po, t, UInt16, 0, MAX_UINT16);
            CASE_INTERP_OUT_UINT(po, t, UInt32, 0, MAX_UINT32);
#if HAS_UINT64
            /* There was a bug in numpy as of (at least) <= 1.6.1 such that
             * MAX_UINT64 was incorrectly defined, leading to a compiler error.
             * NPY_MAX_UINT64 is correctly defined
             */
            CASE_INTERP_OUT_UINT(po, t, UInt64, 0, NPY_MAX_UINT64);
#endif
            CASE_INTERP_OUT_INT(po, t, Int8, MIN_INT8, MAX_INT8);
            CASE_INTERP_OUT_INT(po, t, Int16, MIN_INT16, MAX_INT16);
            CASE_INTERP_OUT_INT(po, t, Int32, MIN_INT32, MAX_INT32);
            CASE_INTERP_OUT_INT(po, t, Int64, MIN_INT64, MAX_INT64);
            CASE_INTERP_OUT(po, t, Float32);
            CASE_INTERP_OUT(po, t, Float64);
        default:
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT(io, po);
    }

 exit:
    if (zeros) {
        for(jj = 0; jj < rank; jj++)
            if (zeros[jj])
                free(zeros[jj]);
        free(zeros);
    }
    if (offsets) {
        for(jj = 0; jj < rank; jj++)
            if (offsets[jj])
                free(offsets[jj]);
        free(offsets);
    }
    if (splvals) {
        for(jj = 0; jj < rank; jj++) {
            if (splvals[jj]) {
                for(hh = 0; hh < odimensions[jj]; hh++)
                    if (splvals[jj][hh])
                        free(splvals[jj][hh]);
                free(splvals[jj]);
            }
        }
        free(splvals);
    }
    if (edge_offsets) {
        for(jj = 0; jj < rank; jj++) {
            if (edge_offsets[jj]) {
                for(hh = 0; hh < odimensions[jj]; hh++)
                    if (edge_offsets[jj][hh])
                        free(edge_offsets[jj][hh]);
                free(edge_offsets[jj]);
            }
        }
        free(edge_offsets);
    }
    if (foffsets)
        free(foffsets);
    if (fcoordinates)
        free(fcoordinates);
    return PyErr_Occurred() ? 0 : 1;
}
Esempio n. 21
0
// kldiv(f,f0)=E(f0-f+f*log(f/f0)) f0,f>=level
static PyObject* kullback_leibler_divergence(PyObject *self, PyObject *args)
{
  PyObject* a = NULL;
  PyObject* b = NULL;
  npy_float64 f,f0, level = 1.0;
  npy_intp sz = 0, i, count=0;
  if (!PyArg_ParseTuple(args, "OO|f", &a, &b, &level))
    return NULL; 
  if (!(PyArray_Check(a) && PyArray_Check(b)))
    {
      PyErr_SetString(PyExc_TypeError,"arguments must be array objects");
      return NULL;
    }
  sz = PyArray_SIZE(a);

  if (sz != PyArray_SIZE(b))
    {
      PyErr_SetString(PyExc_TypeError,"argument sizes must be equal");
      return NULL;
    }
  if (PyArray_TYPE(a) != PyArray_TYPE(b))
    {
      PyErr_SetString(PyExc_TypeError,"argument types must be same");
      return NULL;
    }
  level = (level<0? 0.0 : level);
  switch(PyArray_TYPE(a))
    {
    case PyArray_FLOAT64:
      {
	npy_float64 result=0.0;
	for (i=0; i<sz; ++i)
	  {
	    f = *((npy_float64*)PyArray_DATA(a) + i);
	    f0 = *((npy_float64*)PyArray_DATA(b) + i);
	    if (f0<=level || f<level)
	      continue;
	    if (f==0.0)
	      result += f0;
	    else
	      result += f0 - f + f*log(f/f0);
	    count ++;
	  }
	return Py_BuildValue("f", result/count);
      }
      break;
    case PyArray_FLOAT32:
      {
	npy_float64 result=0.0;
	for (i=0; i<sz; ++i)
	  {
	    f = *((npy_float32*)PyArray_DATA(a) + i);
	    f0 = *((npy_float32*)PyArray_DATA(b) + i);
	    if (f0<=level || f<level)
	      continue;
	    if (f==0.0)
	      result += f0;
	    else
	      result += f0 - f + f*log(f/f0);
	    count ++;
	  }
	return Py_BuildValue("f", result/count);
      }
      break;
    default:
      PyErr_SetString(PyExc_TypeError,"argument types must be float64");
      return NULL;
    }
}
Esempio n. 22
0
/* Delaunay implementation methyod.  If hide_qhull_errors is 1 then qhull error
 * messages are discarded; if it is 0 then they are written to stderr. */
static PyObject*
delaunay_impl(int npoints, const double* x, const double* y,
              int hide_qhull_errors)
{
    coordT* points = NULL;
    facetT* facet;
    int i, ntri, max_facet_id;
    FILE* error_file = NULL;    /* qhull expects a FILE* to write errors to. */
    int exitcode;               /* Value returned from qh_new_qhull(). */
    int* tri_indices = NULL;    /* Maps qhull facet id to triangle index. */
    int indices[3];
    int curlong, totlong;       /* Memory remaining after qh_memfreeshort. */
    PyObject* tuple;            /* Return tuple (triangles, neighbors). */
    const int ndim = 2;
    npy_intp dims[2];
    PyArrayObject* triangles = NULL;
    PyArrayObject* neighbors = NULL;
    int* triangles_ptr;
    int* neighbors_ptr;

    /* Allocate points. */
    points = (coordT*)malloc(npoints*ndim*sizeof(coordT));
    if (points == NULL) {
        PyErr_SetString(PyExc_MemoryError,
                        "Could not allocate points array in qhull.delaunay");
        goto error_before_qhull;
    }

    /* Prepare points array to pass to qhull. */
    for (i = 0; i < npoints; ++i) {
        points[2*i  ] = x[i];
        points[2*i+1] = y[i];
    }

    /* qhull expects a FILE* to write errors to. */
    if (hide_qhull_errors) {
        /* qhull errors are ignored by writing to OS-equivalent of /dev/null.
         * Rather than have OS-specific code here, instead it is determined by
         * setupext.py and passed in via the macro MPL_DEVNULL. */
        error_file = fopen(STRINGIFY(MPL_DEVNULL), "w");
        if (error_file == NULL) {
            PyErr_SetString(PyExc_RuntimeError,
                            "Could not open devnull in qhull.delaunay");
            goto error_before_qhull;
        }
    }
    else {
        /* qhull errors written to stderr. */
        error_file = stderr;
    }

    /* Perform Delaunay triangulation. */
    exitcode = qh_new_qhull(ndim, npoints, points, False,
                            "qhull d Qt Qbb Qc Qz", NULL, error_file);
    if (exitcode != qh_ERRnone) {
        PyErr_Format(PyExc_RuntimeError,
                     "Error in qhull Delaunay triangulation calculation: %s (exitcode=%d)%s",
                     qhull_error_msg[exitcode], exitcode,
                     hide_qhull_errors ? "; use python verbose option (-v) to see original qhull error." : "");
        goto error;
    }

    /* Split facets so that they only have 3 points each. */
    qh_triangulate();

    /* Determine ntri and max_facet_id.
       Note that libqhull uses macros to iterate through collections. */
    ntri = 0;
    FORALLfacets {
        if (!facet->upperdelaunay)
            ++ntri;
    }

    max_facet_id = qh facet_id - 1;

    /* Create array to map facet id to triangle index. */
    tri_indices = (int*)malloc((max_facet_id+1)*sizeof(int));
    if (tri_indices == NULL) {
        PyErr_SetString(PyExc_MemoryError,
                        "Could not allocate triangle map in qhull.delaunay");
        goto error;
    }

    /* Allocate python arrays to return. */
    dims[0] = ntri;
    dims[1] = 3;
    triangles = (PyArrayObject*)PyArray_SimpleNew(ndim, dims, PyArray_INT);
    if (triangles == NULL) {
        PyErr_SetString(PyExc_MemoryError,
                        "Could not allocate triangles array in qhull.delaunay");
        goto error;
    }

    neighbors = (PyArrayObject*)PyArray_SimpleNew(ndim, dims, PyArray_INT);
    if (neighbors == NULL) {
        PyErr_SetString(PyExc_MemoryError,
                        "Could not allocate neighbors array in qhull.delaunay");
        goto error;
    }

    triangles_ptr = (int*)PyArray_DATA(triangles);
    neighbors_ptr = (int*)PyArray_DATA(neighbors);

    /* Determine triangles array and set tri_indices array. */
    i = 0;
    FORALLfacets {
        if (!facet->upperdelaunay) {
            tri_indices[facet->id] = i++;
            get_facet_vertices(facet, indices);
            *triangles_ptr++ = (facet->toporient ? indices[0] : indices[2]);
            *triangles_ptr++ = indices[1];
            *triangles_ptr++ = (facet->toporient ? indices[2] : indices[0]);
        }
        else
            tri_indices[facet->id] = -1;
    }

    /* Determine neighbors array. */
    FORALLfacets {
        if (!facet->upperdelaunay) {
            get_facet_neighbours(facet, tri_indices, indices);
            *neighbors_ptr++ = (facet->toporient ? indices[2] : indices[0]);
            *neighbors_ptr++ = (facet->toporient ? indices[0] : indices[2]);
            *neighbors_ptr++ = indices[1];
        }
    }

    /* Clean up. */
    qh_freeqhull(!qh_ALL);
    qh_memfreeshort(&curlong, &totlong);
    if (curlong || totlong)
        PyErr_WarnEx(PyExc_RuntimeWarning,
                     "Qhull could not free all allocated memory", 1);
    if (hide_qhull_errors)
        fclose(error_file);
    free(tri_indices);
    free(points);

    tuple = PyTuple_New(2);
    PyTuple_SetItem(tuple, 0, (PyObject*)triangles);
    PyTuple_SetItem(tuple, 1, (PyObject*)neighbors);
    return tuple;

error:
    /* Clean up. */
    Py_XDECREF(triangles);
    Py_XDECREF(neighbors);
    qh_freeqhull(!qh_ALL);
    qh_memfreeshort(&curlong, &totlong);
    /* Don't bother checking curlong and totlong as raising error anyway. */
    if (hide_qhull_errors)
        fclose(error_file);
    free(tri_indices);

error_before_qhull:
    free(points);

    return NULL;
}
Esempio n. 23
0
static PyObject *div_unit_grad(PyObject *self, PyObject *args)
{
  PyObject* f = NULL;
  npy_intp Nx, Ny, Nz;
  int i, j, k, im1, im2, ip1, jm1, jm2, jp1, km1, km2, kp1;
  npy_float64* f_data_dp = NULL;
  npy_float64* r_data_dp = NULL;
  npy_float32* f_data_sp = NULL;
  npy_float32* r_data_sp = NULL;
  double hx, hy, hz;
  double hx2, hy2, hz2;
  PyArrayObject* r = NULL;
  double fip, fim, fjp, fjm, fkp, fkm, fijk;
  double fimkm, fipkm, fjmkm, fjpkm, fimjm, fipjm, fimkp, fjmkp, fimjp;
  double aim, bjm, ckm, aijk, bijk, cijk;
  double Dxpf, Dxmf, Dypf, Dymf, Dzpf, Dzmf;
  double Dxma, Dymb, Dzmc;
  if (!PyArg_ParseTuple(args, "O(ddd)", &f, &hx, &hy, &hz))
    return NULL;
  hx2 = 2*hx;  hy2 = 2*hy;  hz2 = 2*hz;
  if (!PyArray_Check(f))
    {
      PyErr_SetString(PyExc_TypeError,"first argument must be array");
      return NULL;
    }
  if (PyArray_NDIM(f) != 3)
    {
      PyErr_SetString(PyExc_TypeError,"array argument must have rank 3");
      return NULL;
    }
  Nx = PyArray_DIM(f, 0);
  Ny = PyArray_DIM(f, 1);
  Nz = PyArray_DIM(f, 2);
  r = (PyArrayObject*)PyArray_SimpleNew(3, PyArray_DIMS(f), PyArray_TYPE(f));

  if (PyArray_TYPE(f) == PyArray_FLOAT32)
    {
      f_data_sp = (npy_float32*)PyArray_DATA(f);
      r_data_sp = (npy_float32*)PyArray_DATA(r);
      for (i=0; i<Nx; ++i)
	{
	  im1 = (i?i-1:0);
	  im2 = (im1?im1-1:0);
      	  ip1 = (i+1==Nx?i:i+1);
	  for (j=0; j<Ny; ++j)
	    {
	      jm1 = (j?j-1:0);
	      jm2 = (jm1?jm1-1:0);
	      jp1 = (j+1==Ny?j:j+1);
	      for (k=0; k<Nz; ++k)
		{
		  km1 = (k?k-1:0);
		  km2 = (km1?km1-1:0);
		  kp1 = (k+1==Nz?k:k+1);

		  fimjm = *((npy_float32*)PyArray_GETPTR3(f, im1, jm1, k));
		  fim = *((npy_float32*)PyArray_GETPTR3(f, im1, j, k));
		  fimkm = *((npy_float32*)PyArray_GETPTR3(f, im1, j, km1));
		  fimkp = *((npy_float32*)PyArray_GETPTR3(f, im1, j, kp1));
		  fimjp = *((npy_float32*)PyArray_GETPTR3(f, im1, jp1, k));

		  fjmkm = *((npy_float32*)PyArray_GETPTR3(f, i, jm1, km1));
		  fjm = *((npy_float32*)PyArray_GETPTR3(f, i, jm1, k));
		  fjmkp = *((npy_float32*)PyArray_GETPTR3(f, i, jm1, kp1));

		  fkm = *((npy_float32*)PyArray_GETPTR3(f, i, j, km1));
		  fijk = *((npy_float32*)PyArray_GETPTR3(f, i, j, k));
		  fkp = *((npy_float32*)PyArray_GETPTR3(f, i, j, kp1));

		  fjpkm = *((npy_float32*)PyArray_GETPTR3(f, i, jp1, km1));
		  fjp = *((npy_float32*)PyArray_GETPTR3(f, i, jp1, k));

		  fipjm = *((npy_float32*)PyArray_GETPTR3(f, ip1, jm1, k));
		  fipkm = *((npy_float32*)PyArray_GETPTR3(f, ip1, j, km1));
		  fip = *((npy_float32*)PyArray_GETPTR3(f, ip1, j, k));

		  Dxpf = (fip - fijk) / hx;
		  Dxmf = (fijk - fim) / hx;
		  Dypf = (fjp - fijk) / hy;
		  Dymf = (fijk - fjm) / hy;
		  Dzpf = (fkp - fijk) / hz;
		  Dzmf = (fijk - fkm) / hz;
		  aijk = hypot3(Dxpf, m(Dypf, Dymf), m(Dzpf, Dzmf));
		  bijk = hypot3(Dypf, m(Dxpf, Dxmf), m(Dzpf, Dzmf));
		  cijk = hypot3(Dzpf, m(Dypf, Dymf), m(Dxpf, Dxmf));

		  aijk = (aijk>FLOAT32_EPS?Dxpf / aijk:0.0);
		  bijk = (bijk>FLOAT32_EPS?Dypf / bijk: 0.0);
		  cijk = (cijk>FLOAT32_EPS?Dzpf / cijk:0.0); 
		  

		  Dxpf = (fijk - fim) / hx;
		  Dypf = (fimjp - fim) / hy;
		  Dymf = (fim - fimjm) / hy;
		  Dzpf = (fimkp - fim) / hz;
		  Dzmf = (fim - fimkm) / hz;
		  aim = hypot3(Dxpf, m(Dypf, Dymf), m(Dzpf, Dzmf));

		  aim = (aim>FLOAT32_EPS?Dxpf/aim:0.0); 


		  Dxpf = (fipjm - fjm) / hx;
		  Dxmf = (fjm - fimjm) / hx;
		  Dypf = (fijk - fjm) / hy;
		  Dzpf = (fjmkp - fjm) / hz;
		  Dzmf = (fjm - fjmkm) / hz;
		  bjm = hypot3(Dypf, m(Dxpf, Dxmf), m(Dzpf, Dzmf));

		  bjm = (bjm>FLOAT32_EPS?Dypf/bjm:0.0);
		  

		  Dxpf = (fipkm - fkm) / hx;
		  Dxmf = (fjm - fimkm) / hx;
		  Dypf = (fjpkm - fkm) / hy;
		  Dymf = (fkm - fjmkm) / hy;
		  Dzpf = (fijk - fkm) / hz;
		  ckm = hypot3(Dzpf, m(Dypf, Dymf), m(Dxpf, Dxmf));

		  ckm = (ckm>FLOAT32_EPS?Dzpf/ckm:0.0); 

		  Dxma = (aijk - aim) / hx;
		  Dymb = (bijk - bjm) / hy;
		  Dzmc = (cijk - ckm) / hz;
		  
		  //*((npy_float32*)PyArray_GETPTR3(r, i, j, k)) = Dxma/hx + Dymb/hy + Dzmc/hz;
		  *((npy_float32*)PyArray_GETPTR3(r, i, j, k)) = Dxma + Dymb + Dzmc;
		}
	    }
	}      
    }
  else if (PyArray_TYPE(f) == PyArray_FLOAT64)
    {
      f_data_dp = (npy_float64*)PyArray_DATA(f);
      r_data_dp = (npy_float64*)PyArray_DATA(r);
      for (i=0; i<Nx; ++i)
	{
	  im1 = (i?i-1:0);
	  im2 = (im1?im1-1:0);
      	  ip1 = (i+1==Nx?i:i+1);
	  for (j=0; j<Ny; ++j)
	    {
	      jm1 = (j?j-1:0);
	      jm2 = (jm1?jm1-1:0);
	      jp1 = (j+1==Ny?j:j+1);
	      for (k=0; k<Nz; ++k)
		{
		  km1 = (k?k-1:0);
		  km2 = (km1?km1-1:0);
		  kp1 = (k+1==Nz?k:k+1);

		  fimjm = *((npy_float64*)PyArray_GETPTR3(f, im1, jm1, k));
		  fim = *((npy_float64*)PyArray_GETPTR3(f, im1, j, k));
		  fimkm = *((npy_float64*)PyArray_GETPTR3(f, im1, j, km1));
		  fimkp = *((npy_float64*)PyArray_GETPTR3(f, im1, j, kp1));
		  fimjp = *((npy_float64*)PyArray_GETPTR3(f, im1, jp1, k));

		  fjmkm = *((npy_float64*)PyArray_GETPTR3(f, i, jm1, km1));
		  fjm = *((npy_float64*)PyArray_GETPTR3(f, i, jm1, k));
		  fjmkp = *((npy_float64*)PyArray_GETPTR3(f, i, jm1, kp1));

		  fkm = *((npy_float64*)PyArray_GETPTR3(f, i, j, km1));
		  fijk = *((npy_float64*)PyArray_GETPTR3(f, i, j, k));
		  fkp = *((npy_float64*)PyArray_GETPTR3(f, i, j, kp1));

		  fjpkm = *((npy_float64*)PyArray_GETPTR3(f, i, jp1, km1));
		  fjp = *((npy_float64*)PyArray_GETPTR3(f, i, jp1, k));

		  fipjm = *((npy_float64*)PyArray_GETPTR3(f, ip1, jm1, k));
		  fipkm = *((npy_float64*)PyArray_GETPTR3(f, ip1, j, km1));
		  fip = *((npy_float64*)PyArray_GETPTR3(f, ip1, j, k));

		  Dxpf = (fip - fijk) / hx;
		  Dxmf = (fijk - fim) / hx;
		  Dypf = (fjp - fijk) / hy;
		  Dymf = (fijk - fjm) / hy;
		  Dzpf = (fkp - fijk) / hz;
		  Dzmf = (fijk - fkm) / hz;
		  aijk = hypot3(Dxpf, m(Dypf, Dymf), m(Dzpf, Dzmf));
		  aijk = (aijk>FLOAT64_EPS?Dxpf / aijk:0.0);
		  bijk = hypot3(Dypf, m(Dxpf, Dxmf), m(Dzpf, Dzmf));
		  bijk = (bijk>FLOAT64_EPS?Dypf / bijk: 0.0);
		  cijk = hypot3(Dzpf, m(Dypf, Dymf), m(Dxpf, Dxmf));
		  cijk = (cijk>FLOAT64_EPS?Dzpf/cijk:0.0);

		  Dxpf = (fijk - fim) / hx;
		  Dypf = (fimjp - fim) / hy;
		  Dymf = (fim - fimjm) / hy;
		  Dzpf = (fimkp - fim) / hz;
		  Dzmf = (fim - fimkm) / hz;
		  aim = hypot3(Dxpf, m(Dypf, Dymf), m(Dzpf, Dzmf));
		  aim = (aim>FLOAT64_EPS?Dxpf/aim:0.0); 

		  Dxpf = (fipjm - fjm) / hx;
		  Dxmf = (fjm - fimjm) / hx;
		  Dypf = (fijk - fjm) / hy;
		  Dzpf = (fjmkp - fjm) / hz;
		  Dzmf = (fjm - fjmkm) / hz;
		  bjm = hypot3(Dypf, m(Dxpf, Dxmf), m(Dzpf, Dzmf));
		  bjm = (bjm>FLOAT64_EPS?Dypf/bjm:0.0);
		  


		  Dxpf = (fipkm - fkm) / hx;
		  Dxmf = (fjm - fimkm) / hx;
		  Dypf = (fjpkm - fkm) / hy;
		  Dymf = (fkm - fjmkm) / hy;
		  Dzpf = (fijk - fkm) / hz;
		  ckm = hypot3(Dzpf, m(Dypf, Dymf), m(Dxpf, Dxmf));
		  ckm = (ckm>FLOAT64_EPS?Dzpf/ckm:0.0); 
		  
		  Dxma = (aijk - aim) / hx;
		  Dymb = (bijk - bjm) / hy;
		  Dzmc = (cijk - ckm) / hz;

		  //*((npy_float64*)PyArray_GETPTR3(r, i, j, k)) = Dxma/hx + Dymb/hy + Dzmc/hz;
		  *((npy_float64*)PyArray_GETPTR3(r, i, j, k)) = Dxma + Dymb + Dzmc;
		}
	    }
	}
    }
  else
    {
      PyErr_SetString(PyExc_TypeError,"array argument type must be float64");
      return NULL;
    }
  return Py_BuildValue("N", r);
}
Esempio n. 24
0
Py::Object
_path_module::cleanup_path(const Py::Tuple& args)
{
    args.verify_length(8);

    PathIterator path(args[0]);
    agg::trans_affine trans = py_to_agg_transformation_matrix(args[1].ptr(), false);
    bool remove_nans = args[2].isTrue();

    Py::Object clip_obj = args[3];
    bool do_clip;
    agg::rect_base<double> clip_rect;
    if (clip_obj.isNone())
    {
        do_clip = false;
    }
    else
    {
        double x1, y1, x2, y2;
        Py::Tuple clip_tuple(clip_obj);
        x1 = Py::Float(clip_tuple[0]);
        y1 = Py::Float(clip_tuple[1]);
        x2 = Py::Float(clip_tuple[2]);
        y2 = Py::Float(clip_tuple[3]);
        clip_rect.init(x1, y1, x2, y2);
        do_clip = true;
    }

    Py::Object snap_obj = args[4];
    e_snap_mode snap_mode;
    if (snap_obj.isNone())
    {
        snap_mode = SNAP_AUTO;
    }
    else if (snap_obj.isTrue())
    {
        snap_mode = SNAP_TRUE;
    }
    else
    {
        snap_mode = SNAP_FALSE;
    }

    double stroke_width = Py::Float(args[5]);

    bool simplify;
    Py::Object simplify_obj = args[6];
    if (simplify_obj.isNone())
    {
        simplify = path.should_simplify();
    }
    else
    {
        simplify = simplify_obj.isTrue();
    }

    bool return_curves = args[7].isTrue();

    std::vector<double> vertices;
    std::vector<npy_uint8> codes;

    _cleanup_path(path, trans, remove_nans, do_clip, clip_rect, snap_mode,
                  stroke_width, simplify, return_curves, vertices, codes);

    npy_intp length = codes.size();
    npy_intp dims[] = { length, 2, 0 };

    PyArrayObject* vertices_obj = NULL;
    PyArrayObject* codes_obj = NULL;
    Py::Tuple result(2);
    try
    {
        vertices_obj = (PyArrayObject*)PyArray_SimpleNew
                       (2, dims, PyArray_DOUBLE);
        if (vertices_obj == NULL)
        {
            throw Py::MemoryError("Could not allocate result array");
        }

        codes_obj = (PyArrayObject*)PyArray_SimpleNew
                    (1, dims, PyArray_UINT8);
        if (codes_obj == NULL)
        {
            throw Py::MemoryError("Could not allocate result array");
        }

        memcpy(PyArray_DATA(vertices_obj), &vertices[0], sizeof(double) * 2 * length);
        memcpy(PyArray_DATA(codes_obj), &codes[0], sizeof(npy_uint8) * length);

        result[0] = Py::Object((PyObject*)vertices_obj, true);
        result[1] = Py::Object((PyObject*)codes_obj, true);
    }
    catch (...)
    {
        Py_XDECREF(vertices_obj);
        Py_XDECREF(codes_obj);
        throw;
    }

    return result;
}
Esempio n. 25
0
int NI_WatershedIFT(PyArrayObject* input, PyArrayObject* markers,
                                        PyArrayObject* strct, PyArrayObject* output)
{
    char *pl, *pm, *pi;
    int ll;
    npy_intp size, jj, hh, kk, maxval;
    npy_intp strides[WS_MAXDIM], coordinates[WS_MAXDIM];
    npy_intp *nstrides = NULL, nneigh, ssize;
    int i_contiguous, o_contiguous;
    NI_WatershedElement *temp = NULL, **first = NULL, **last = NULL;
    npy_bool *ps = NULL;
    NI_Iterator mi, ii, li;
    NPY_BEGIN_THREADS_DEF;

    i_contiguous = PyArray_ISCONTIGUOUS(input);
    o_contiguous = PyArray_ISCONTIGUOUS(output);
    ssize = PyArray_SIZE(strct);
    if (PyArray_NDIM(input) > WS_MAXDIM) {
        PyErr_SetString(PyExc_RuntimeError, "too many dimensions");
        goto exit;
    }
    size = PyArray_SIZE(input);
    /* Storage for the temporary queue data. */
    temp = malloc(size * sizeof(NI_WatershedElement));
    if (!temp) {
        PyErr_NoMemory();
        goto exit;
    }

    NPY_BEGIN_THREADS;

    pi = (void *)PyArray_DATA(input);
    if (!NI_InitPointIterator(input, &ii))
        goto exit;
    /* Initialization and find the maximum of the input. */
    maxval = 0;
    for(jj = 0; jj < size; jj++) {
        npy_intp ival = 0;
        switch (PyArray_TYPE(input)) {
            CASE_GET_INPUT(NPY_UINT8, npy_uint8, ival, pi);
            CASE_GET_INPUT(NPY_UINT16, npy_uint16, ival, pi);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        temp[jj].index = jj;
        temp[jj].done = 0;
        if (ival > maxval)
            maxval = ival;
        NI_ITERATOR_NEXT(ii, pi);
    }
    pi = (void *)PyArray_DATA(input);
    /* Allocate and initialize the storage for the queue. */
    first = malloc((maxval + 1) * sizeof(NI_WatershedElement*));
    last = malloc((maxval + 1) * sizeof(NI_WatershedElement*));
    if (NPY_UNLIKELY(!first || !last)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    for(hh = 0; hh <= maxval; hh++) {
        first[hh] = NULL;
        last[hh] = NULL;
    }
    if (!NI_InitPointIterator(markers, &mi))
        goto exit;
    if (!NI_InitPointIterator(output, &li))
        goto exit;
    pm = (void *)PyArray_DATA(markers);
    pl = (void *)PyArray_DATA(output);
    /* initialize all nodes */
    for (ll = 0; ll < PyArray_NDIM(input); ll++) {
        coordinates[ll] = 0;
    }
    for(jj = 0; jj < size; jj++) {
        /* get marker */
        int label = 0;
        switch (PyArray_TYPE(markers)) {
            CASE_GET_LABEL(NPY_UBYTE, npy_ubyte, label, pm);
            CASE_GET_LABEL(NPY_USHORT, npy_ushort, label, pm);
            CASE_GET_LABEL(NPY_UINT, npy_uint, label, pm);
            CASE_GET_LABEL(NPY_ULONG, npy_ulong, label, pm);
            CASE_GET_LABEL(NPY_ULONGLONG, npy_ulonglong, label, pm);
            CASE_GET_LABEL(NPY_BYTE, npy_byte, label, pm);
            CASE_GET_LABEL(NPY_SHORT, npy_short, label, pm);
            CASE_GET_LABEL(NPY_INT, npy_int, label, pm);
            CASE_GET_LABEL(NPY_LONG, npy_long, label, pm);
            CASE_GET_LABEL(NPY_LONGLONG, npy_longlong, label, pm);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        switch (PyArray_TYPE(output)) {
            CASE_PUT_LABEL(NPY_UBYTE, npy_ubyte, label, pl);
            CASE_PUT_LABEL(NPY_USHORT, npy_ushort, label, pl);
            CASE_PUT_LABEL(NPY_UINT, npy_uint, label, pl);
            CASE_PUT_LABEL(NPY_ULONG, npy_ulong, label, pl);
            CASE_PUT_LABEL(NPY_ULONGLONG, npy_ulonglong, label, pl);
            CASE_PUT_LABEL(NPY_BYTE, npy_byte, label, pl);
            CASE_PUT_LABEL(NPY_SHORT, npy_short, label, pl);
            CASE_PUT_LABEL(NPY_INT, npy_int, label, pl);
            CASE_PUT_LABEL(NPY_LONG, npy_long, label, pl);
            CASE_PUT_LABEL(NPY_LONGLONG, npy_longlong, label, pl);
        default:
            NPY_END_THREADS;
            PyErr_SetString(PyExc_RuntimeError, "data type not supported");
            goto exit;
        }
        NI_ITERATOR_NEXT2(mi, li, pm, pl);
        if (label != 0) {
            /* This node is a marker */
            temp[jj].cost = 0;
            if (!first[0]) {
                first[0] = &(temp[jj]);
                first[0]->next = NULL;
                first[0]->prev = NULL;
                last[0] = first[0];
            } else {
                if (label > 0) {
                    /* object markers are enqueued at the beginning, so they
                       are processed first. */
                    temp[jj].next = first[0];
                    temp[jj].prev = NULL;
                    first[0]->prev = &(temp[jj]);
                    first[0] = &(temp[jj]);
                } else {
                    /* background markers are enqueued at the end, so they are
                         processed after the object markers. */
                    temp[jj].next = NULL;
                    temp[jj].prev = last[0];
                    last[0]->next = &(temp[jj]);
                    last[0] = &(temp[jj]);
                }
            }
        } else {
            /* This node is not a marker */
            temp[jj].cost = maxval + 1;
            temp[jj].next = NULL;
            temp[jj].prev = NULL;
        }
        for (ll = PyArray_NDIM(input) - 1; ll >= 0; ll--) {
            if (coordinates[ll] < PyArray_DIMS(input)[ll] - 1) {
                coordinates[ll]++;
                break;
            } else {
                coordinates[ll] = 0;
            }
        }
    }

    pl = (void *)PyArray_DATA(output);
    ps = (npy_bool*)PyArray_DATA(strct);
    nneigh = 0;
    for (kk = 0; kk < ssize; kk++)
        if (ps[kk] && kk != (ssize / 2))
            ++nneigh;
    nstrides = malloc(nneigh * sizeof(npy_intp));
    if (NPY_UNLIKELY(!nstrides)) {
        NPY_END_THREADS;
        PyErr_NoMemory();
        goto exit;
    }
    strides[PyArray_NDIM(input) - 1] = 1;
    for (ll = PyArray_NDIM(input) - 2; ll >= 0; ll--) {
        strides[ll] = PyArray_DIM(input, ll + 1) * strides[ll + 1];
    }
    for (ll = 0; ll < PyArray_NDIM(input); ll++) {
        coordinates[ll] = -1;
    }
    for(kk = 0; kk < nneigh; kk++)
        nstrides[kk] = 0;
    jj = 0;
    for(kk = 0; kk < ssize; kk++) {
        if (ps[kk]) {
            int offset = 0;
            for (ll = 0; ll < PyArray_NDIM(input); ll++) {
                offset += coordinates[ll] * strides[ll];
            }
            if (offset != 0)
                nstrides[jj++] += offset;
        }
        for (ll = PyArray_NDIM(input) - 1; ll >= 0; ll--) {
            if (coordinates[ll] < 1) {
                coordinates[ll]++;
                break;
            } else {
                coordinates[ll] = -1;
            }
        }
    }
    /* Propagation phase: */
    for(jj = 0; jj <= maxval; jj++) {
        while (first[jj]) {
            /* dequeue first element: */
            NI_WatershedElement *v = first[jj];
            first[jj] = first[jj]->next;
            if (first[jj])
                first[jj]->prev = NULL;
            v->prev = NULL;
            v->next = NULL;
            /* Mark element as done: */
            v->done = 1;
            /* Iterate over the neighbors of the element: */
            for(hh = 0; hh < nneigh; hh++) {
                npy_intp v_index = v->index, p_index = v->index, idx, cc;
                int qq, outside = 0;
                p_index += nstrides[hh];
                /* check if the neighbor is within the extent of the array: */
                idx = p_index;
                for (qq = 0; qq < PyArray_NDIM(input); qq++) {
                    cc = idx / strides[qq];
                    if (cc < 0 || cc >= PyArray_DIM(input, qq)) {
                        outside = 1;
                        break;
                    }
                    idx -= cc * strides[qq];
                }
                if (!outside) {
                    NI_WatershedElement *p = &(temp[p_index]);
                    if (!(p->done)) {
                        /* If the neighbor was not processed yet: */
                        int max, pval, vval, wvp, pcost, label, p_idx, v_idx;
                        switch (PyArray_TYPE(input)) {
                            CASE_WINDEX1(NPY_UBYTE, npy_ubyte,
                                v_index, p_index, strides,
                                PyArray_STRIDES(input), PyArray_NDIM(input),
                                i_contiguous, p_idx, v_idx, pi, vval, pval);
                            CASE_WINDEX1(NPY_USHORT, npy_ushort,
                                v_index, p_index, strides,
                                PyArray_STRIDES(input), PyArray_NDIM(input),
                                i_contiguous, p_idx, v_idx, pi, vval, pval);
                        default:
                            NPY_END_THREADS;
                            PyErr_SetString(PyExc_RuntimeError,
                                            "data type not supported");
                            goto exit;
                        }
                        /* Calculate cost: */
                        wvp = pval - vval;
                        if (wvp < 0)
                            wvp = -wvp;
                        /* Find the maximum of this cost and the current
                             element cost: */
                        pcost = p->cost;
                        max = v->cost > wvp ? v->cost : wvp;
                        if (max < pcost) {
                            /* If this maximum is less than the neighbors cost,
                                 adapt the cost and the label of the neighbor: */
                            int idx;
                            p->cost = max;
                            switch (PyArray_TYPE(output)) {
                                CASE_WINDEX2(NPY_UBYTE, npy_ubyte,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_USHORT, npy_ushort,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_UINT, npy_uint,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_ULONG, npy_ulong,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_ULONGLONG, npy_ulonglong,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_BYTE, npy_byte,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_SHORT, npy_short,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_INT, npy_int,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_LONG, npy_long,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX2(NPY_LONGLONG, npy_longlong,
                                             v_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                            default:
                                NPY_END_THREADS;
                                PyErr_SetString(PyExc_RuntimeError,
                                                "data type not supported");
                                goto exit;
                            }
                            switch (PyArray_TYPE(output)) {
                                CASE_WINDEX3(NPY_UBYTE, npy_ubyte,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_USHORT, npy_ushort,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_UINT, npy_uint,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_ULONG, npy_ulong,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_ULONGLONG, npy_ulonglong,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_BYTE, npy_byte,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_SHORT, npy_short,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_INT, npy_int,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_LONG, npy_long,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                                CASE_WINDEX3(NPY_LONGLONG, npy_longlong,
                                             p_index, strides,
                                             PyArray_STRIDES(output),
                                             PyArray_NDIM(input),
                                             idx, o_contiguous, label, pl);
                            default:
                                NPY_END_THREADS;
                                PyErr_SetString(PyExc_RuntimeError,
                                                "data type not supported");
                                goto exit;
                            }
                            /* If the neighbor is in a queue, remove it: */
                            if (p->next || p->prev) {
                                NI_WatershedElement *prev = p->prev, *next = p->next;
                                if (first[pcost] == p)
                                    first[pcost] = next;
                                if (last[pcost] == p)
                                    last[pcost] = prev;
                                if (prev)
                                    prev->next = next;
                                if (next)
                                    next->prev = prev;
                            }
                            /* Insert the neighbor in the appropriate queue: */
                            if (label < 0) {
                                p->prev = last[max];
                                p->next = NULL;
                                if (last[max])
                                    last[max]->next = p;
                                last[max] = p;
                                if (!first[max])
                                    first[max] = p;
                            } else {
                                p->next = first[max];
                                p->prev = NULL;
                                if (first[max])
                                    first[max]->prev = p;
                                first[max] = p;
                                if (!last[max])
                                    last[max] = p;
                            }
                        }
                    }
                }
            }
        }
    }
 exit:
    NPY_END_THREADS;
    free(temp);
    free(first);
    free(last);
    free(nstrides);
    return PyErr_Occurred() ? 0 : 1;
}
Esempio n. 26
0
Py::Object
_path_module::update_path_extents(const Py::Tuple& args)
{
    args.verify_length(5);

    double x0, y0, x1, y1;
    PathIterator path(args[0]);
    agg::trans_affine trans = py_to_agg_transformation_matrix(
        args[1].ptr(), false);

    if (!py_convert_bbox(args[2].ptr(), x0, y0, x1, y1))
    {
        throw Py::ValueError(
            "Must pass Bbox object as arg 3 of update_path_extents");
    }
    Py::Object minpos_obj = args[3];
    bool ignore = Py::Boolean(args[4]);

    double xm, ym;
    PyArrayObject* input_minpos = NULL;
    try
    {
        input_minpos = (PyArrayObject*)PyArray_FromObject(
            minpos_obj.ptr(), PyArray_DOUBLE, 1, 1);
        if (!input_minpos || PyArray_DIM(input_minpos, 0) != 2)
        {
            throw Py::TypeError(
                "Argument 4 to update_path_extents must be a length-2 numpy array.");
        }
        xm = *(double*)PyArray_GETPTR1(input_minpos, 0);
        ym = *(double*)PyArray_GETPTR1(input_minpos, 1);
    }
    catch (...)
    {
        Py_XDECREF(input_minpos);
        throw;
    }
    Py_XDECREF(input_minpos);

    npy_intp extent_dims[] = { 2, 2, 0 };
    double* extents_data = NULL;
    npy_intp minpos_dims[] = { 2, 0 };
    double* minpos_data = NULL;
    PyArrayObject* extents = NULL;
    PyArrayObject* minpos = NULL;
    bool changed = false;

    try
    {
        extents = (PyArrayObject*)PyArray_SimpleNew
                  (2, extent_dims, PyArray_DOUBLE);
        if (extents == NULL)
        {
            throw Py::MemoryError("Could not allocate result array");
        }
        minpos = (PyArrayObject*)PyArray_SimpleNew
                 (1, minpos_dims, PyArray_DOUBLE);
        if (minpos == NULL)
        {
            throw Py::MemoryError("Could not allocate result array");
        }

        extents_data = (double*)PyArray_DATA(extents);
        minpos_data = (double*)PyArray_DATA(minpos);

        if (ignore)
        {
            extents_data[0] = std::numeric_limits<double>::infinity();
            extents_data[1] = std::numeric_limits<double>::infinity();
            extents_data[2] = -std::numeric_limits<double>::infinity();
            extents_data[3] = -std::numeric_limits<double>::infinity();
            minpos_data[0] = std::numeric_limits<double>::infinity();
            minpos_data[1] = std::numeric_limits<double>::infinity();
        }
        else
        {
            if (x0 > x1)
            {
                extents_data[0] = std::numeric_limits<double>::infinity();
                extents_data[2] = -std::numeric_limits<double>::infinity();
            }
            else
            {
                extents_data[0] = x0;
                extents_data[2] = x1;
            }
            if (y0 > y1)
            {
                extents_data[1] = std::numeric_limits<double>::infinity();
                extents_data[3] = -std::numeric_limits<double>::infinity();
            }
            else
            {
                extents_data[1] = y0;
                extents_data[3] = y1;
            }
            minpos_data[0] = xm;
            minpos_data[1] = ym;
        }

        ::get_path_extents(path, trans, &extents_data[0], &extents_data[1],
                           &extents_data[2], &extents_data[3], &minpos_data[0],
                           &minpos_data[1]);

        changed = (extents_data[0] != x0 ||
                   extents_data[1] != y0 ||
                   extents_data[2] != x1 ||
                   extents_data[3] != y1 ||
                   minpos_data[0]  != xm ||
                   minpos_data[1]  != ym);

    }
    catch (...)
    {
        Py_XDECREF(extents);
        Py_XDECREF(minpos);
        throw;
    }

    Py::Tuple result(3);
    result[0] = Py::Object((PyObject*) extents);
    result[1] = Py::Object((PyObject*) minpos);
    result[2] = Py::Int(changed ? 1 : 0);

    Py_XDECREF(extents);
    Py_XDECREF(minpos);

    return result;
}
Esempio n. 27
0
int Object_npyArrayAddItem(void *prv, JSOBJ obj, JSOBJ value)
{
  PyObject* type;
  PyArray_Descr* dtype;
  npy_intp i;
  char *new_data, *item;
  NpyArrContext* npyarr = (NpyArrContext*) obj;
  PRINTMARK();
  if (!npyarr)
  {
    return 0;
  }

  i = npyarr->i;

  npyarr->shape.ptr[npyarr->dec->curdim-1]++;

  if (PyArray_Check((PyObject*)value))
  {
    // multidimensional array, keep decoding values.
    return 1;
  }

  if (!npyarr->ret)
  {
    // Array not initialised yet.
    // We do it here so we can 'sniff' the data type if none was provided
    if (!npyarr->dec->dtype)
    {
      type = PyObject_Type(value);
      if(!PyArray_DescrConverter(type, &dtype))
      {
        Py_DECREF(type);
        goto fail;
      }
      Py_INCREF(dtype);
      Py_DECREF(type);
    }
    else
    {
      dtype = PyArray_DescrNew(npyarr->dec->dtype);
    }

    // If it's an object or string then fill a Python list and subsequently
    // convert. Otherwise we would need to somehow mess about with
    // reference counts when renewing memory.
    npyarr->elsize = dtype->elsize;
    if (PyDataType_REFCHK(dtype) || npyarr->elsize == 0)
    {
      Py_XDECREF(dtype);

      if (npyarr->dec->curdim > 1)
      {
        PyErr_SetString(PyExc_ValueError, "Cannot decode multidimensional arrays with variable length elements to numpy");
        goto fail;
      }
      npyarr->elcount = 0;
      npyarr->ret = PyList_New(0);
      if (!npyarr->ret)
      {
        goto fail;
      }
      ((JSONObjectDecoder*)npyarr->dec)->newArray = Object_npyNewArrayList;
      ((JSONObjectDecoder*)npyarr->dec)->arrayAddItem = Object_npyArrayListAddItem;
      ((JSONObjectDecoder*)npyarr->dec)->endArray = Object_npyEndArrayList;
      return Object_npyArrayListAddItem(prv, obj, value);
    }

    npyarr->ret = PyArray_NewFromDescr(&PyArray_Type, dtype, 1,
        &npyarr->elcount, NULL,NULL, 0, NULL);

    if (!npyarr->ret)
    {
      goto fail;
    }
  }

  if (i >= npyarr->elcount) {
    // Grow PyArray_DATA(ret):
    // this is similar for the strategy for PyListObject, but we use
    // 50% overallocation => 0, 4, 8, 14, 23, 36, 56, 86 ...
    if (npyarr->elsize == 0)
    {
      PyErr_SetString(PyExc_ValueError, "Cannot decode multidimensional arrays with variable length elements to numpy");
      goto fail;
    }

    npyarr->elcount = (i >> 1) + (i < 4 ? 4 : 2) + i;
    if (npyarr->elcount <= NPY_MAX_INTP/npyarr->elsize) {
      new_data = PyDataMem_RENEW(PyArray_DATA(npyarr->ret), npyarr->elcount * npyarr->elsize);
    }
    else {
      PyErr_NoMemory();
      goto fail;
    }
    ((PyArrayObject*) npyarr->ret)->data = (void*) new_data;

    // PyArray_BYTES(npyarr->ret) = new_data;
  }

  PyArray_DIMS(npyarr->ret)[0] = i + 1;

  if ((item = PyArray_GETPTR1(npyarr->ret, i)) == NULL
      || PyArray_SETITEM(npyarr->ret, item, value) == -1) {
    goto fail;
  }

  Py_DECREF( (PyObject *) value);
  npyarr->i++;
  return 1;

fail:

  Npy_releaseContext(npyarr);
  return 0;
}
Esempio n. 28
0
Py::Object
_path_module::affine_transform(const Py::Tuple& args)
{
    args.verify_length(2);

    Py::Object vertices_obj = args[0];
    Py::Object transform_obj = args[1];

    PyArrayObject* vertices = NULL;
    PyArrayObject* transform = NULL;
    PyArrayObject* result = NULL;

    try
    {
        vertices = (PyArrayObject*)PyArray_FromObject
                   (vertices_obj.ptr(), PyArray_DOUBLE, 1, 2);
        if (!vertices ||
            (PyArray_NDIM(vertices) == 2 && PyArray_DIM(vertices, 0) != 0 &&
             PyArray_DIM(vertices, 1) != 2) ||
            (PyArray_NDIM(vertices) == 1 &&
             PyArray_DIM(vertices, 0) != 2 && PyArray_DIM(vertices, 0) != 0))
        {
            throw Py::ValueError("Invalid vertices array.");
        }

        transform = (PyArrayObject*) PyArray_FromObject
                    (transform_obj.ptr(), PyArray_DOUBLE, 2, 2);
        if (!transform ||
            PyArray_DIM(transform, 0) != 3 ||
            PyArray_DIM(transform, 1) != 3)
        {
            throw Py::ValueError("Invalid transform.");
        }

        double a, b, c, d, e, f;
        {
            size_t stride0 = PyArray_STRIDE(transform, 0);
            size_t stride1 = PyArray_STRIDE(transform, 1);
            char* row0 = PyArray_BYTES(transform);
            char* row1 = row0 + stride0;

            a = *(double*)(row0);
            row0 += stride1;
            c = *(double*)(row0);
            row0 += stride1;
            e = *(double*)(row0);

            b = *(double*)(row1);
            row1 += stride1;
            d = *(double*)(row1);
            row1 += stride1;
            f = *(double*)(row1);
        }

        result = (PyArrayObject*)PyArray_SimpleNew
                 (PyArray_NDIM(vertices), PyArray_DIMS(vertices), PyArray_DOUBLE);
        if (result == NULL)
        {
            throw Py::MemoryError("Could not allocate memory for path");
        }
        if (PyArray_NDIM(vertices) == 2)
        {
            size_t n = PyArray_DIM(vertices, 0);
            char* vertex_in = PyArray_BYTES(vertices);
            double* vertex_out = (double*)PyArray_DATA(result);
            size_t stride0 = PyArray_STRIDE(vertices, 0);
            size_t stride1 = PyArray_STRIDE(vertices, 1);
            double x;
            double y;

            for (size_t i = 0; i < n; ++i)
            {
                x = *(double*)(vertex_in);
                y = *(double*)(vertex_in + stride1);

                *vertex_out++ = a * x + c * y + e;
                *vertex_out++ = b * x + d * y + f;

                vertex_in += stride0;
            }
        }
        else if (PyArray_DIM(vertices, 0) != 0)
        {
            char* vertex_in = PyArray_BYTES(vertices);
            double* vertex_out = (double*)PyArray_DATA(result);
            size_t stride0 = PyArray_STRIDE(vertices, 0);
            double x;
            double y;
            x = *(double*)(vertex_in);
            y = *(double*)(vertex_in + stride0);
            *vertex_out++ = a * x + c * y + e;
            *vertex_out++ = b * x + d * y + f;
        }
    }
    catch (...)
    {
        Py_XDECREF(vertices);
        Py_XDECREF(transform);
        Py_XDECREF(result);
        throw;
    }

    Py_XDECREF(vertices);
    Py_XDECREF(transform);

    return Py::Object((PyObject*)result, true);
}
Esempio n. 29
0
int NI_Correlate1D(PyArrayObject *input, PyArrayObject *weights,
                   int axis, PyArrayObject *output, NI_ExtendMode mode,
                   double cval, npy_intp origin)
{
    int symmetric = 0, more;
    npy_intp ii, jj, ll, lines, length, size1, size2, filter_size;
    double *ibuffer = NULL, *obuffer = NULL;
    npy_double *fw;
    NI_LineBuffer iline_buffer, oline_buffer;
    NPY_BEGIN_THREADS_DEF;

    /* test for symmetry or anti-symmetry: */
    filter_size = PyArray_SIZE(weights);
    size1 = filter_size / 2;
    size2 = filter_size - size1 - 1;
    fw = (void *)PyArray_DATA(weights);
    if (filter_size & 0x1) {
        symmetric = 1;
        for(ii = 1; ii <= filter_size / 2; ii++) {
            if (fabs(fw[ii + size1] - fw[size1 - ii]) > DBL_EPSILON) {
                symmetric = 0;
                break;
            }
        }
        if (symmetric == 0) {
            symmetric = -1;
            for(ii = 1; ii <= filter_size / 2; ii++) {
                if (fabs(fw[size1 + ii] + fw[size1 - ii]) > DBL_EPSILON) {
                    symmetric = 0;
                    break;
                }
            }
        }
    }
    /* allocate and initialize the line buffers: */
    lines = -1;
    if (!NI_AllocateLineBuffer(input, axis, size1 + origin, size2 - origin,
                                                         &lines, BUFFER_SIZE, &ibuffer))
        goto exit;
    if (!NI_AllocateLineBuffer(output, axis, 0, 0, &lines, BUFFER_SIZE,
                                                         &obuffer))
        goto exit;
    if (!NI_InitLineBuffer(input, axis, size1 + origin, size2 - origin,
                                                            lines, ibuffer, mode, cval, &iline_buffer))
        goto exit;
    if (!NI_InitLineBuffer(output, axis, 0, 0, lines, obuffer, mode, 0.0,
                                                 &oline_buffer))
        goto exit;

    NPY_BEGIN_THREADS;
    length = PyArray_NDIM(input) > 0 ? PyArray_DIM(input, axis) : 1;
    fw += size1;
    /* iterate over all the array lines: */
    do {
        /* copy lines from array to buffer: */
        if (!NI_ArrayToLineBuffer(&iline_buffer, &lines, &more)) {
            goto exit;
        }
        /* iterate over the lines in the buffers: */
        for(ii = 0; ii < lines; ii++) {
            /* get lines: */
            double *iline = NI_GET_LINE(iline_buffer, ii) + size1;
            double *oline = NI_GET_LINE(oline_buffer, ii);
            /* the correlation calculation: */
            if (symmetric > 0) {
                for(ll = 0; ll < length; ll++) {
                    oline[ll] = iline[0] * fw[0];
                    for(jj = -size1 ; jj < 0; jj++)
                        oline[ll] += (iline[jj] + iline[-jj]) * fw[jj];
                    ++iline;
                }
            } else if (symmetric < 0) {
                for(ll = 0; ll < length; ll++) {
                    oline[ll] = iline[0] * fw[0];
                    for(jj = -size1 ; jj < 0; jj++)
                        oline[ll] += (iline[jj] - iline[-jj]) * fw[jj];
                    ++iline;
                }
            } else {
                for(ll = 0; ll < length; ll++) {
                    oline[ll] = iline[size2] * fw[size2];
                    for(jj = -size1; jj < size2; jj++)
                        oline[ll] += iline[jj] * fw[jj];
                    ++iline;
                }
            }
        }
        /* copy lines from buffer to array: */
        if (!NI_LineBufferToArray(&oline_buffer)) {
            goto exit;
        }
    } while(more);
exit:
    NPY_END_THREADS;
    free(ibuffer);
    free(obuffer);
    return PyErr_Occurred() ? 0 : 1;
}
Esempio n. 30
0
static PyObject* write_coords(PyObject* self, PyObject* args)
{
    oskar_MeasurementSet* h = 0;
    PyObject *capsule = 0;
    PyObject *obj[] = {0, 0, 0};
    PyArrayObject *uu = 0, *vv = 0, *ww = 0;
    int start_row = 0, num_baselines = 0;
    double exposure_sec = 0.0, interval_sec = 0.0, time_stamp = 0.0;
    if (!PyArg_ParseTuple(args, "OiiOOOddd", &capsule,
            &start_row, &num_baselines, &obj[0], &obj[1], &obj[2],
            &exposure_sec, &interval_sec, &time_stamp))
        return 0;
    if (!(h = get_handle(capsule))) return 0;

    /* Make sure input objects are arrays. Convert if required. */
    uu = (PyArrayObject*) PyArray_FROM_OF(obj[0], NPY_ARRAY_IN_ARRAY);
    vv = (PyArrayObject*) PyArray_FROM_OF(obj[1], NPY_ARRAY_IN_ARRAY);
    ww = (PyArrayObject*) PyArray_FROM_OF(obj[2], NPY_ARRAY_IN_ARRAY);
    if (!uu || !vv || !ww)
        goto fail;

    /* Check dimensions. */
    if (num_baselines != (int) PyArray_SIZE(uu) ||
            num_baselines != (int) PyArray_SIZE(vv) ||
            num_baselines != (int) PyArray_SIZE(ww))
    {
        PyErr_SetString(PyExc_RuntimeError, "Input data dimension mismatch.");
        goto fail;
    }

    /* Allow threads. */
    Py_BEGIN_ALLOW_THREADS

    /* Write the coordinates. */
    if (PyArray_TYPE(uu) == NPY_DOUBLE)
        oskar_ms_write_coords_d(h, start_row, num_baselines,
                (const double*)PyArray_DATA(uu),
                (const double*)PyArray_DATA(vv),
                (const double*)PyArray_DATA(ww),
                exposure_sec, interval_sec, time_stamp);
    else
        oskar_ms_write_coords_f(h, start_row, num_baselines,
                (const float*)PyArray_DATA(uu),
                (const float*)PyArray_DATA(vv),
                (const float*)PyArray_DATA(ww),
                exposure_sec, interval_sec, time_stamp);

    /* Disallow threads. */
    Py_END_ALLOW_THREADS

    Py_XDECREF(uu);
    Py_XDECREF(vv);
    Py_XDECREF(ww);
    return Py_BuildValue("");

fail:
    Py_XDECREF(uu);
    Py_XDECREF(vv);
    Py_XDECREF(ww);
    return 0;
}