static PyObject *phoebeRV2(PyObject *self, PyObject *args)
{
    int index, i;
    PyObject *obj, *ret, *ts;
    char *rstr;

    PHOEBE_column_type itype;
    PHOEBE_vector *indep;
    PHOEBE_curve *curve;

    if (!PyArg_ParseTuple(args, "Oi", &obj, &index)) {
        printf("parsing failed: call with rv2(t_array, curve_index).\n");
        return NULL;
    }

    ts = PyArray_FromObject(obj, NPY_DOUBLE, 0, 0);
    indep = phoebe_vector_new_from_copied_data(PyArray_DATA(ts), PyArray_SIZE(ts));

    phoebe_parameter_get_value (phoebe_parameter_lookup ("phoebe_indep"), &rstr);
    phoebe_column_get_type (&itype, rstr);

    curve = phoebe_curve_new();
    phoebe_curve_compute(curve, indep, index, itype, PHOEBE_COLUMN_SECONDARY_RV, NULL, NULL, NULL);

    ret = PyTuple_New(indep->dim);
    for (i = 0; i < indep->dim; i++)
        PyTuple_SetItem(ret, i, Py_BuildValue("d", curve->dep->val[i]));

    phoebe_curve_free(curve);
    phoebe_vector_free(indep);

    return ret;
}
Beispiel #2
0
static PyObject *soomfunc_preload(PyObject *module, PyObject *args)
{
    PyObject *obj;
    PyArrayObject *array;
    int preload = -1;

    if (!PyArg_ParseTuple(args, "O|i", &obj, &preload))
	return NULL;
    array = (PyArrayObject *)PyArray_FromObject(obj, PyArray_NOTYPE, 0, 0);
    if (array == NULL)
	return NULL;
    if (array->nd != 1) {
	PyErr_SetString(PyExc_ValueError, "arrays must be rank-1");
	Py_DECREF(array);
	return NULL;
    }

    if (preload < 0 || preload > array->dimensions[0])
	preload = array->dimensions[0] - 1;

    INSTRUMENT(("ssi", "preload", "enter", preload));

    switch (array->descr->type_num) {
    case PyArray_CHAR:
    case PyArray_SBYTE:
	preload_schar(array, preload);
	break;
    case PyArray_UBYTE:
	preload_uchar(array, preload);
	break;
    case PyArray_SHORT:
	preload_short(array, preload);
	break;
    case PyArray_INT:
	preload_int(array, preload);
	break;
    case PyArray_LONG:
	preload_long(array, preload);
	break;
    case PyArray_FLOAT:
	preload_float(array, preload);
	break;
    case PyArray_DOUBLE: 
	preload_double(array, preload);
	break;
    }

    Py_DECREF(array);
    Py_INCREF(Py_None);

    INSTRUMENT(("ss", "preload", "exit"));
    return Py_None;
}
static PyObject *IIRsymorder2(PyObject *NPY_UNUSED(dummy), PyObject *args)
{
  PyObject *sig=NULL;
  PyArrayObject *a_sig=NULL, *out=NULL;
  double r, omega;
  double precision = -1.0;
  int thetype, N, ret;
  npy_intp outstrides, instrides;

  if (!PyArg_ParseTuple(args, "Odd|d", &sig, &r, &omega, &precision))
    return NULL;

  thetype = PyArray_ObjectType(sig, PyArray_FLOAT);
  thetype = NPY_MIN(thetype, PyArray_DOUBLE);
  a_sig = (PyArrayObject *)PyArray_FromObject(sig, thetype, 1, 1);
  
  if ((a_sig == NULL)) goto fail;
  
  out = (PyArrayObject *)PyArray_SimpleNew(1,DIMS(a_sig),thetype);
  if (out == NULL) goto fail;
  N = DIMS(a_sig)[0];

  convert_strides(STRIDES(a_sig), &instrides, ELSIZE(a_sig), 1);
  outstrides = 1;

  switch (thetype) {
  case PyArray_FLOAT:
    if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-6;      
    ret = S_IIR_forback2 (r, omega, (float *)DATA(a_sig), 
			  (float *)DATA(out), N,
			  instrides, outstrides, precision);
    break;
  case PyArray_DOUBLE:
    if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-11;
    ret = D_IIR_forback2 (r, omega, (double *)DATA(a_sig), 
			  (double *)DATA(out), N,
			  instrides, outstrides, precision);
    break;
  default:
    PYERR("Incorrect type.");
  }
  
  if (ret < 0) PYERR("Problem occured inside routine.");

  Py_DECREF(a_sig);
  return PyArray_Return(out);
 
 fail:
  Py_XDECREF(a_sig);
  Py_XDECREF(out);
  return NULL;

}
  static void*
  convertible(PyObject* obj_ptr)
  {
    PyArrayObject* a;

    a = (PyArrayObject*)PyArray_FromObject(
        obj_ptr, ::detail::numpy_type_map<T>::typenum, NDims, NDims);
    if (a == NULL) {
      return 0;
    }
    Py_DECREF(a);
    return obj_ptr;
  }
Beispiel #5
0
  /* Construct from an existing Numpy array */
  numpy_boost(PyObject* obj) throw (python_exception) :
    super(NULL, std::vector<typename super::index>(NDims, 0)),
    array(NULL)
  {
    PyArrayObject* a;

    a = (PyArrayObject*)PyArray_FromObject(
        obj, detail::numpy_type_map<T>::typenum, NDims, NDims);
    if (a == NULL) {
      throw python_exception();
    }

    init_from_array(a);
  }
Beispiel #6
0
  /* Construct from an existing Numpy array */
  numpy_boost(PyObject* obj) throw () :
    super(NULL, std::vector<typename super::index>(NDims, 0)),
    array(NULL)
  {
    PyArrayObject* a;

    a = (PyArrayObject*)PyArray_FromObject(
        obj, detail::numpy_type_map<T>::typenum, NDims, NDims);
    if (a == NULL) {
      throw boost::python::error_already_set();
    }

    init_from_array(a);
  }
static PyObject *qspline2d(PyObject *NPY_UNUSED(dummy), PyObject *args)
{
  PyObject *image=NULL;
  PyArrayObject *a_image=NULL, *ck=NULL;
  double lambda = 0.0;
  double precision = -1.0;
  int thetype, M, N, retval=0;
  npy_intp outstrides[2], instrides[2];

  if (!PyArg_ParseTuple(args, "O|dd", &image, &lambda, &precision)) return NULL;

  if (lambda != 0.0) PYERR("Smoothing spline not yet implemented.");

  thetype = PyArray_ObjectType(image, PyArray_FLOAT);
  thetype = NPY_MIN(thetype, PyArray_DOUBLE);
  a_image = (PyArrayObject *)PyArray_FromObject(image, thetype, 2, 2);
  if (a_image == NULL) goto fail;
 
  ck = (PyArrayObject *)PyArray_SimpleNew(2,DIMS(a_image),thetype);
  if (ck == NULL) goto fail;
  M = DIMS(a_image)[0];
  N = DIMS(a_image)[1];

  convert_strides(STRIDES(a_image), instrides, ELSIZE(a_image), 2);
  outstrides[0] = N;
  outstrides[1] = 1;

  if (thetype == PyArray_FLOAT) {
    if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-3;
    retval = S_quadratic_spline2D((float *)DATA(a_image), (float *)DATA(ck), M, N, lambda, instrides, outstrides, precision);
  }
  else if (thetype == PyArray_DOUBLE) {
    if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-6;
    retval = D_quadratic_spline2D((double *)DATA(a_image), (double *)DATA(ck), M, N, lambda, instrides, outstrides, precision);
  }

  if (retval == -3) PYERR("Precision too high.  Error did not converge.");
  if (retval < 0) PYERR("Problem occured inside routine");

  Py_DECREF(a_image);
  return PyArray_Return(ck);
 
 fail:
  Py_XDECREF(a_image);
  Py_XDECREF(ck);
  return NULL;

}
Beispiel #8
0
PyObject *
PyAubio_CFmatToArray (fmat_t * input)
{
  PyObject *array = NULL;
  uint_t i;
  npy_intp dims[] = { input->length, 1 };
  PyObject *concat = PyList_New (0), *tmp = NULL;
  for (i = 0; i < input->height; i++) {
    tmp = PyArray_SimpleNewFromData (1, dims, AUBIO_NPY_SMPL, input->data[i]);
    PyList_Append (concat, tmp);
    Py_DECREF (tmp);
  }
  array = PyArray_FromObject (concat, AUBIO_NPY_SMPL, 2, 2);
  Py_DECREF (concat);
  return array;
}
Beispiel #9
0
/* Convert the given PyObject to a NumPy array with the given
 * typecode.  On success, return a valid PyArrayObject* with the
 * correct type.  On failure, the python error string will be set and
 * the routine returns NULL.
 */
PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
                                             int* is_new_object) {
  PyArrayObject* ary = NULL;
  PyObject* py_obj;
  if (is_array(input) && (typecode == NPY_NOTYPE ||
			  PyArray_EquivTypenums(array_type(input),typecode))) {
    ary = (PyArrayObject*) input;
    *is_new_object = 0;
  }
  else {
    py_obj = PyArray_FromObject(input, typecode, 0, 0);
    /* If NULL, PyArray_FromObject will have set python error value.*/
    ary = (PyArrayObject*) py_obj;
    *is_new_object = 1;
  }
  PyErr_Clear();
  return ary;
}
Beispiel #10
0
static ArrayInfo *check_array_args(PyObject *args,
				   int min_arrays, int max_arrays,
				   int contiguous)
{
    char msg[128];
    ArrayInfo *array_info, *info;
    int num_arrays, type_num, i;

    num_arrays = PyTuple_Size(args);
    if (num_arrays < min_arrays) {
	sprintf(msg, "at least %d arrays required", min_arrays);
	PyErr_SetString(PyExc_ValueError, msg);
	return NULL;
    }
    if (max_arrays > 0 && num_arrays > max_arrays) {
	sprintf(msg, "more than %d arrays not supported", max_arrays);
	PyErr_SetString(PyExc_ValueError, msg);
	return NULL;
    }
    type_num = -1;
    array_info = malloc(sizeof(*array_info) * num_arrays);
    if (array_info == NULL)
	return (ArrayInfo*)PyErr_NoMemory();
    memset(array_info, 0, sizeof(*array_info) * num_arrays);

    for (i = 0, info = array_info; i < num_arrays; i++, info++) {
	PyObject *arg;
	PyArrayObject *array;

	arg = PyTuple_GetItem(args, i);
	if (arg == NULL)
	    goto error;
	if (contiguous)
	    array = (PyArrayObject *)
		PyArray_ContiguousFromObject(arg, PyArray_NOTYPE, 0, 0);
	else
	    array = (PyArrayObject *)
		PyArray_FromObject(arg, PyArray_NOTYPE, 0, 0);
	if (array == NULL)
	    goto error;
	if (i == 0)
	    type_num = array->descr->type_num;
	else if (array->descr->type_num != type_num) {
	    PyErr_SetString(PyExc_ValueError,
			    "arrays must have the same typecode");
	    goto error;
	}
	if (array->nd != 1) {
	    PyErr_SetString(PyExc_ValueError, "arrays must be rank-1");
	    goto error;
	}
	if (array->descr->type_num == PyArray_CFLOAT
	    || array->descr->type_num == PyArray_CDOUBLE
	    || array->descr->type_num == PyArray_OBJECT
	    || array->descr->type_num == PyArray_NTYPES
	    || array->descr->type_num == PyArray_NOTYPE) {
	    PyErr_SetString(PyExc_ValueError, "unhandled array type");
	    goto error;
	}
	set_array_info(info, array);
    }
    return array_info;

error:
    free_array_info(array_info, num_arrays);
    return NULL;
}
static PyObject*
test_neighborhood_iterator_oob(PyObject* NPY_UNUSED(self), PyObject* args)
{
    PyObject *x, *out, *b1, *b2;
    PyArrayObject *ax;
    PyArrayIterObject *itx;
    int i, typenum, mode1, mode2, st;
    npy_intp bounds[NPY_MAXDIMS*2];
    PyArrayNeighborhoodIterObject *niterx1, *niterx2;

    if (!PyArg_ParseTuple(args, "OOiOi", &x, &b1, &mode1, &b2, &mode2)) {
        return NULL;
    }

    if (!PySequence_Check(b1) || !PySequence_Check(b2)) {
        return NULL;
    }

    typenum = PyArray_ObjectType(x, 0);

    ax = (PyArrayObject*)PyArray_FromObject(x, typenum, 1, 10);
    if (ax == NULL) {
        return NULL;
    }
    if (PySequence_Size(b1) != 2 * PyArray_NDIM(ax)) {
        PyErr_SetString(PyExc_ValueError,
                "bounds sequence 1 size not compatible with x input");
        goto clean_ax;
    }
    if (PySequence_Size(b2) != 2 * PyArray_NDIM(ax)) {
        PyErr_SetString(PyExc_ValueError,
                "bounds sequence 2 size not compatible with x input");
        goto clean_ax;
    }

    out = PyList_New(0);
    if (out == NULL) {
        goto clean_ax;
    }

    itx = (PyArrayIterObject*)PyArray_IterNew(x);
    if (itx == NULL) {
        goto clean_out;
    }

    /* Compute boundaries for the neighborhood iterator */
    for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) {
        PyObject* bound;
        bound = PySequence_GetItem(b1, i);
        if (bounds == NULL) {
            goto clean_itx;
        }
        if (!PyInt_Check(bound)) {
            PyErr_SetString(PyExc_ValueError,
                    "bound not long");
            Py_DECREF(bound);
            goto clean_itx;
        }
        bounds[i] = PyInt_AsLong(bound);
        Py_DECREF(bound);
    }

    /* Create the neighborhood iterator */
    niterx1 = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
                    (PyArrayIterObject*)itx, bounds,
                    mode1, NULL);
    if (niterx1 == NULL) {
        goto clean_out;
    }

    for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) {
        PyObject* bound;
        bound = PySequence_GetItem(b2, i);
        if (bounds == NULL) {
            goto clean_itx;
        }
        if (!PyInt_Check(bound)) {
            PyErr_SetString(PyExc_ValueError,
                    "bound not long");
            Py_DECREF(bound);
            goto clean_itx;
        }
        bounds[i] = PyInt_AsLong(bound);
        Py_DECREF(bound);
    }

    niterx2 = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
                    (PyArrayIterObject*)niterx1, bounds,
                    mode2, NULL);
    if (niterx1 == NULL) {
        goto clean_niterx1;
    }

    switch (typenum) {
        case NPY_DOUBLE:
            st = copy_double_double(niterx1, niterx2, bounds, &out);
            break;
        default:
            PyErr_SetString(PyExc_ValueError,
                    "Type not supported");
            goto clean_niterx2;
    }

    if (st) {
        goto clean_niterx2;
    }

    Py_DECREF(niterx2);
    Py_DECREF(niterx1);
    Py_DECREF(itx);
    Py_DECREF(ax);
    return out;

clean_niterx2:
    Py_DECREF(niterx2);
clean_niterx1:
    Py_DECREF(niterx1);
clean_itx:
    Py_DECREF(itx);
clean_out:
    Py_DECREF(out);
clean_ax:
    Py_DECREF(ax);
    return NULL;
}
Beispiel #12
0
Py::Object
_image_module::fromarray(const Py::Tuple& args) {
  _VERBOSE("_image_module::fromarray");
  
  args.verify_length(2);
  
  Py::Object x = args[0];
  int isoutput = Py::Int(args[1]);
  //PyArrayObject *A = (PyArrayObject *) PyArray_ContiguousFromObject(x.ptr(), PyArray_DOUBLE, 2, 3); 
  PyArrayObject *A = (PyArrayObject *) PyArray_FromObject(x.ptr(), PyArray_DOUBLE, 2, 3); 
  
  if (A==NULL) 
    throw Py::ValueError("Array must be rank 2 or 3 of doubles"); 
  
  
  Image* imo = new Image;
  
  imo->rowsIn  = A->dimensions[0];
  imo->colsIn  = A->dimensions[1];
  
  
  size_t NUMBYTES(imo->colsIn * imo->rowsIn * imo->BPP);
  agg::int8u *buffer = new agg::int8u[NUMBYTES];  
  if (buffer==NULL) //todo: also handle allocation throw
    throw Py::MemoryError("_image_module::fromarray could not allocate memory");
  
  if (isoutput) {
    // make the output buffer point to the input buffer
    
    imo->rowsOut  = imo->rowsIn;
    imo->colsOut  = imo->colsIn;
    
    imo->rbufOut = new agg::rendering_buffer;
    imo->bufferOut = buffer;
    imo->rbufOut->attach(imo->bufferOut, imo->colsOut, imo->rowsOut, imo->colsOut * imo->BPP);
    
  }
  else {
    imo->bufferIn = buffer;
    imo->rbufIn = new agg::rendering_buffer;
    imo->rbufIn->attach(buffer, imo->colsIn, imo->rowsIn, imo->colsIn*imo->BPP);
  }
  
  if   (A->nd == 2) { //assume luminance for now; 
    
    agg::int8u gray;
    for (size_t rownum=0; rownum<imo->rowsIn; rownum++) 
      for (size_t colnum=0; colnum<imo->colsIn; colnum++) {
	
	double val = *(double *)(A->data + rownum*A->strides[0] + colnum*A->strides[1]);
	
	gray = int(255 * val);
	*buffer++ = gray;       // red
	*buffer++ = gray;       // green
	*buffer++ = gray;       // blue
	*buffer++   = 255;        // alpha
      }
    
  }
  else if   (A->nd == 3) { // assume RGB
    
    if (A->dimensions[2] != 3 && A->dimensions[2] != 4 ) {
      Py_XDECREF(A);  
      throw Py::ValueError(Printf("3rd dimension must be length 3 (RGB) or 4 (RGBA); found %d", A->dimensions[2]).str()); 
      
    }
    
    int rgba = A->dimensions[2]==4;    
    double r,g,b,alpha;
    int offset =0;
    
    for (size_t rownum=0; rownum<imo->rowsIn; rownum++) 
      for (size_t colnum=0; colnum<imo->colsIn; colnum++) {
	offset = rownum*A->strides[0] + colnum*A->strides[1];
	r = *(double *)(A->data + offset);
	g = *(double *)(A->data + offset + A->strides[2] );
	b = *(double *)(A->data + offset + 2*A->strides[2] );
 	
	if (rgba) 
	  alpha = *(double *)(A->data + offset + 3*A->strides[2] );
	else
	  alpha = 1.0;
	
	*buffer++ = int(255*r);         // red
	*buffer++ = int(255*g);         // green
	*buffer++ = int(255*b);         // blue
	*buffer++ = int(255*alpha);     // alpha
	
      }
    
  } 
  else   { // error
    Py_XDECREF(A);  
    throw Py::ValueError("Illegal array rank; must be rank; must 2 or 3"); 
  }
  buffer -= NUMBYTES;
  Py_XDECREF(A);  
  
  return Py::asObject( imo );
}
Beispiel #13
0
static PyObject *phoebeLC(PyObject *self, PyObject *args)
{
    int status;
    int index, i;
    PyObject *obj, *lc, *combo = NULL, *ts = NULL;
    char *rstr;

    Py_ssize_t mswitch = 0, hswitch = 0;
    PHOEBE_column_type itype;
    PHOEBE_vector *indep;
    PHOEBE_curve *curve;
    PHOEBE_mesh *mesh1 = NULL, *mesh2 = NULL;
    PHOEBE_horizon *horizon = NULL;

    if (!PyArg_ParseTuple(args, "Oi|ii", &obj, &index, &mswitch, &hswitch)) {
        printf("parsing failed: call with lc(t_array, curve_index [, mswitch, hswitch]).\n");
        return NULL;
    }

    // printf("array type: %s\n", obj->ob_type->tp_name);

    // if (!PyArray_Check(obj)) {
    //     printf("timestamps need to be provided as a numpy-compatible array.\n");
    //     return NULL;
    // }

    // tlen = PyTuple_Size(obj);
    ts = PyArray_FromObject(obj, NPY_DOUBLE, 0, 0);
    indep = phoebe_vector_new_from_copied_data(PyArray_DATA(ts), PyArray_SIZE(ts));

    // printf("dim=%d\n", indep->dim);

    phoebe_parameter_get_value (phoebe_parameter_lookup ("phoebe_indep"), &rstr);
    phoebe_column_get_type (&itype, rstr);

    /* If mswitch is turned on, we need to store the computed meshes. */
    if (mswitch) {
        mesh1 = phoebe_mesh_new();
        mesh2 = phoebe_mesh_new();
    }

    /* If hswitch is turned on, we need to store the horizon. */
    if (hswitch) {
        horizon = phoebe_horizon_new();
    }

    curve = phoebe_curve_new();
    status = phoebe_curve_compute(curve, indep, index, itype, PHOEBE_COLUMN_FLUX, mesh1, mesh2, horizon);

    if (status != SUCCESS) {
        printf("%s", phoebe_error(status));
        return NULL;
    }

    lc = PyTuple_New(indep->dim);
    for (i = 0; i < indep->dim; i++)
        PyTuple_SetItem(lc, i, Py_BuildValue("d", curve->dep->val[i]));

	  if (mswitch || hswitch) {
        combo = PyTuple_New(1 + mswitch + hswitch);
        PyTuple_SetItem(combo, 0, lc);
	  }

    if (mswitch) {
        /* Now we need to wrap this into something nice. */
        PyObject *dict = PyDict_New();

        intern_add_mesh_to_dict(dict, mesh1, "vcx1",   0);
        intern_add_mesh_to_dict(dict, mesh1, "vcy1",   1);
        intern_add_mesh_to_dict(dict, mesh1, "vcz1",   2);
        intern_add_mesh_to_dict(dict, mesh1, "rad1",   3);
        intern_add_mesh_to_dict(dict, mesh1, "grx1",   4);
        intern_add_mesh_to_dict(dict, mesh1, "gry1",   5);
        intern_add_mesh_to_dict(dict, mesh1, "grz1",   6);
        intern_add_mesh_to_dict(dict, mesh1, "fr1",    7);
        intern_add_mesh_to_dict(dict, mesh1, "slump1", 8);
        intern_add_mesh_to_dict(dict, mesh1, "glump1", 9);
        intern_add_mesh_to_dict(dict, mesh1, "gmag1",  10);
        intern_add_mesh_to_dict(dict, mesh1, "glog1",  11);
        intern_add_mesh_to_dict(dict, mesh1, "csbt1",  12);
        intern_add_mesh_to_dict(dict, mesh1, "tloc1",  13);
        intern_add_mesh_to_dict(dict, mesh1, "Inorm1", 14);

        intern_add_mesh_to_dict(dict, mesh2, "vcx2",   0);
        intern_add_mesh_to_dict(dict, mesh2, "vcy2",   1);
        intern_add_mesh_to_dict(dict, mesh2, "vcz2",   2);
        intern_add_mesh_to_dict(dict, mesh2, "rad2",   3);
        intern_add_mesh_to_dict(dict, mesh2, "grx2",   4);
        intern_add_mesh_to_dict(dict, mesh2, "gry2",   5);
        intern_add_mesh_to_dict(dict, mesh2, "grz2",   6);
        intern_add_mesh_to_dict(dict, mesh2, "fr2",    7);
        intern_add_mesh_to_dict(dict, mesh2, "slump2", 8);
        intern_add_mesh_to_dict(dict, mesh2, "glump2", 9);
        intern_add_mesh_to_dict(dict, mesh2, "gmag2",  10);
        intern_add_mesh_to_dict(dict, mesh2, "glog2",  11);
        intern_add_mesh_to_dict(dict, mesh2, "csbt2",  12);
        intern_add_mesh_to_dict(dict, mesh2, "tloc2",  13);
        intern_add_mesh_to_dict(dict, mesh2, "Inorm2", 14);

        PyTuple_SetItem(combo, 1, dict);
    }

	if (hswitch) {
		PyObject *dict = PyDict_New();

		intern_add_horizon_to_dict(dict, horizon);

        PyTuple_SetItem(combo, 1+mswitch, dict);
	}

    phoebe_curve_free(curve);
    phoebe_vector_free(indep);
    phoebe_mesh_free(mesh1);
    phoebe_mesh_free(mesh2);
	phoebe_horizon_free(horizon);

	if (mswitch || hswitch)
        return combo;

    return lc;
}
static PyObject*
test_neighborhood_iterator(PyObject* NPY_UNUSED(self), PyObject* args)
{
    PyObject *x, *fill, *out, *b;
    PyArrayObject *ax, *afill;
    PyArrayIterObject *itx;
    int i, typenum, mode, st;
    npy_intp bounds[NPY_MAXDIMS*2];
    PyArrayNeighborhoodIterObject *niterx;

    if (!PyArg_ParseTuple(args, "OOOi", &x, &b, &fill, &mode)) {
        return NULL;
    }

    if (!PySequence_Check(b)) {
        return NULL;
    }

    typenum = PyArray_ObjectType(x, 0);
    typenum = PyArray_ObjectType(fill, typenum);

    ax = (PyArrayObject*)PyArray_FromObject(x, typenum, 1, 10);
    if (ax == NULL) {
        return NULL;
    }
    if (PySequence_Size(b) != 2 * PyArray_NDIM(ax)) {
        PyErr_SetString(PyExc_ValueError,
                "bounds sequence size not compatible with x input");
        goto clean_ax;
    }

    out = PyList_New(0);
    if (out == NULL) {
        goto clean_ax;
    }

    itx = (PyArrayIterObject*)PyArray_IterNew(x);
    if (itx == NULL) {
        goto clean_out;
    }

    /* Compute boundaries for the neighborhood iterator */
    for (i = 0; i < 2 * PyArray_NDIM(ax); ++i) {
        PyObject* bound;
        bound = PySequence_GetItem(b, i);
        if (bounds == NULL) {
            goto clean_itx;
        }
        if (!PyInt_Check(bound)) {
            PyErr_SetString(PyExc_ValueError,
                    "bound not long");
            Py_DECREF(bound);
            goto clean_itx;
        }
        bounds[i] = PyInt_AsLong(bound);
        Py_DECREF(bound);
    }

    /* Create the neighborhood iterator */
    afill = NULL;
    if (mode == NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING) {
            afill = (PyArrayObject *)PyArray_FromObject(fill, typenum, 0, 0);
            if (afill == NULL) {
            goto clean_itx;
        }
    }

    niterx = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
                    (PyArrayIterObject*)itx, bounds, mode, afill);
    if (niterx == NULL) {
        goto clean_afill;
    }

    switch (typenum) {
        case NPY_OBJECT:
            st = copy_object(itx, niterx, bounds, &out);
            break;
        case NPY_INT:
            st = copy_int(itx, niterx, bounds, &out);
            break;
        case NPY_DOUBLE:
            st = copy_double(itx, niterx, bounds, &out);
            break;
        default:
            PyErr_SetString(PyExc_ValueError,
                    "Type not supported");
            goto clean_niterx;
    }

    if (st) {
        goto clean_niterx;
    }

    Py_DECREF(niterx);
    Py_XDECREF(afill);
    Py_DECREF(itx);

    Py_DECREF(ax);

    return out;

clean_niterx:
    Py_DECREF(niterx);
clean_afill:
    Py_XDECREF(afill);
clean_itx:
    Py_DECREF(itx);
clean_out:
    Py_DECREF(out);
clean_ax:
    Py_DECREF(ax);
    return NULL;
}
Beispiel #15
0
Py::Object
_path_module::point_in_path_collection(const Py::Tuple& args)
{
    args.verify_length(9);

    //segments, trans, clipbox, colors, linewidths, antialiaseds
    double                  x                = Py::Float(args[0]);
    double                  y                = Py::Float(args[1]);
    double                  radius           = Py::Float(args[2]);
    agg::trans_affine       master_transform = py_to_agg_transformation_matrix(args[3].ptr());
    Py::SeqBase<Py::Object> paths            = args[4];
    Py::SeqBase<Py::Object> transforms_obj   = args[5];
    Py::SeqBase<Py::Object> offsets_obj      = args[6];
    agg::trans_affine       offset_trans     = py_to_agg_transformation_matrix(args[7].ptr());
    bool                    filled           = Py::Boolean(args[8]);

    PyArrayObject* offsets = (PyArrayObject*)PyArray_FromObject(
        offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
    if (!offsets ||
            (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
            (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0))
    {
        Py_XDECREF(offsets);
        throw Py::ValueError("Offsets array must be Nx2");
    }

    size_t Npaths      = paths.length();
    size_t Noffsets    = offsets->dimensions[0];
    size_t N           = std::max(Npaths, Noffsets);
    size_t Ntransforms = std::min(transforms_obj.length(), N);
    size_t i;

    // Convert all of the transforms up front
    typedef std::vector<agg::trans_affine> transforms_t;
    transforms_t transforms;
    transforms.reserve(Ntransforms);
    for (i = 0; i < Ntransforms; ++i)
    {
        agg::trans_affine trans = py_to_agg_transformation_matrix
                                  (transforms_obj[i].ptr(), false);
        trans *= master_transform;
        transforms.push_back(trans);
    }

    Py::List result;
    agg::trans_affine trans;

    for (i = 0; i < N; ++i)
    {
        PathIterator path(paths[i % Npaths]);

        if (Ntransforms)
        {
            trans = transforms[i % Ntransforms];
        }
        else
        {
            trans = master_transform;
        }

        if (Noffsets)
        {
            double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
            double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
            offset_trans.transform(&xo, &yo);
            trans *= agg::trans_affine_translation(xo, yo);
        }

        if (filled)
        {
            if (::point_in_path(x, y, path, trans))
                result.append(Py::Int((int)i));
        }
        else
        {
            if (::point_on_path(x, y, radius, path, trans))
                result.append(Py::Int((int)i));
        }
    }

    return result;
}
Beispiel #16
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);
}
Beispiel #17
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;
}
Beispiel #18
0
Py::Object
_path_module::get_path_collection_extents(const Py::Tuple& args)
{
    args.verify_length(5);

    //segments, trans, clipbox, colors, linewidths, antialiaseds
    agg::trans_affine       master_transform = py_to_agg_transformation_matrix(args[0].ptr());
    Py::SeqBase<Py::Object> paths            = args[1];
    Py::SeqBase<Py::Object> transforms_obj   = args[2];
    Py::Object              offsets_obj      = args[3];
    agg::trans_affine       offset_trans     = py_to_agg_transformation_matrix(args[4].ptr(), false);

    PyArrayObject* offsets = NULL;
    double x0, y0, x1, y1, xm, ym;

    try
    {
        offsets = (PyArrayObject*)PyArray_FromObject(
            offsets_obj.ptr(), PyArray_DOUBLE, 0, 2);
        if (!offsets ||
            (PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
            (PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0))
        {
            throw Py::ValueError("Offsets array must be Nx2");
        }

        size_t Npaths      = paths.length();
        size_t Noffsets    = offsets->dimensions[0];
        size_t N               = std::max(Npaths, Noffsets);
        size_t Ntransforms = std::min(transforms_obj.length(), N);
        size_t i;

        // Convert all of the transforms up front
        typedef std::vector<agg::trans_affine> transforms_t;
        transforms_t transforms;
        transforms.reserve(Ntransforms);
        for (i = 0; i < Ntransforms; ++i)
        {
            agg::trans_affine trans = py_to_agg_transformation_matrix
                (transforms_obj[i].ptr(), false);
            trans *= master_transform;
            transforms.push_back(trans);
        }

        // The offset each of those and collect the mins/maxs
        x0 = std::numeric_limits<double>::infinity();
        y0 = std::numeric_limits<double>::infinity();
        x1 = -std::numeric_limits<double>::infinity();
        y1 = -std::numeric_limits<double>::infinity();
        xm = std::numeric_limits<double>::infinity();
        ym = std::numeric_limits<double>::infinity();
        agg::trans_affine trans;

        for (i = 0; i < N; ++i)
        {
            PathIterator path(paths[i % Npaths]);
            if (Ntransforms)
            {
                trans = transforms[i % Ntransforms];
            }
            else
            {
                trans = master_transform;
            }

            if (Noffsets)
            {
                double xo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 0);
                double yo = *(double*)PyArray_GETPTR2(offsets, i % Noffsets, 1);
                offset_trans.transform(&xo, &yo);
                trans *= agg::trans_affine_translation(xo, yo);
            }

            ::get_path_extents(path, trans, &x0, &y0, &x1, &y1, &xm, &ym);
        }
    }
    catch (...)
    {
        Py_XDECREF(offsets);
        throw;
    }

    Py_XDECREF(offsets);

    Py::Tuple result(4);
    result[0] = Py::Float(x0);
    result[1] = Py::Float(y0);
    result[2] = Py::Float(x1);
    result[3] = Py::Float(y1);
    return result;
}
static PyObject *Py_is_sorted(PyObject *self, PyObject *obj)
{
    npy_intp size;
    bool result;

    PyArrayObject *array = (PyArrayObject *)PyArray_FromAny(
        obj, NULL, 1, 1, 0, NULL);

    if (array == NULL) {
        return NULL;
    }

    size = PyArray_DIM(array, 0);

    if (size < 2) {
        Py_DECREF(array);
        Py_RETURN_TRUE;
    }

    /* Handle just the most common types here, otherwise coerce to
    double */
    switch(PyArray_TYPE(array)) {
    case NPY_INT:
        {
            _is_sorted_int<npy_int> is_sorted;
            result = is_sorted(array);
        }
        break;

    case NPY_LONG:
        {
            _is_sorted_int<npy_long> is_sorted;
            result = is_sorted(array);
        }
        break;

    case NPY_LONGLONG:
        {
            _is_sorted_int<npy_longlong> is_sorted;
            result = is_sorted(array);
        }
        break;

    case NPY_FLOAT:
        {
            _is_sorted<npy_float> is_sorted;
            result = is_sorted(array);
        }
        break;

    case NPY_DOUBLE:
        {
            _is_sorted<npy_double> is_sorted;
            result = is_sorted(array);
        }
        break;

    default:
        {
            Py_DECREF(array);
            array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1);

            if (array == NULL) {
                return NULL;
            }

            _is_sorted<npy_double> is_sorted;
            result = is_sorted(array);
        }
    }

    Py_DECREF(array);

    if (result) {
        Py_RETURN_TRUE;
    } else {
        Py_RETURN_FALSE;
    }
}
static PyObject *FIRsepsym2d(PyObject *NPY_UNUSED(dummy), PyObject *args)
{
  PyObject *image=NULL, *hrow=NULL, *hcol=NULL;
  PyArrayObject *a_image=NULL, *a_hrow=NULL, *a_hcol=NULL, *out=NULL;
  int thetype, M, N, ret;
  npy_intp outstrides[2], instrides[2];

  if (!PyArg_ParseTuple(args, "OOO", &image, &hrow, &hcol)) return NULL;

  thetype = PyArray_ObjectType(image, PyArray_FLOAT);
  thetype = NPY_MIN(thetype, PyArray_CDOUBLE);
  a_image = (PyArrayObject *)PyArray_FromObject(image, thetype, 2, 2);
  a_hrow = (PyArrayObject *)PyArray_ContiguousFromObject(hrow, thetype, 1, 1);
  a_hcol = (PyArrayObject *)PyArray_ContiguousFromObject(hcol, thetype, 1, 1);
  
  if ((a_image == NULL) || (a_hrow == NULL) || (a_hcol==NULL)) goto fail;
  
  out = (PyArrayObject *)PyArray_SimpleNew(2,DIMS(a_image),thetype);
  if (out == NULL) goto fail;
  M = DIMS(a_image)[0];
  N = DIMS(a_image)[1];

  convert_strides(STRIDES(a_image), instrides, ELSIZE(a_image), 2);
  outstrides[0] = N;
  outstrides[1] = 1;

  switch (thetype) {
  case PyArray_FLOAT:
    ret = S_separable_2Dconvolve_mirror((float *)DATA(a_image), 
					(float *)DATA(out), M, N,
					(float *)DATA(a_hrow), 
					(float *)DATA(a_hcol),
					DIMS(a_hrow)[0], DIMS(a_hcol)[0], 
					instrides, outstrides);
    break;
  case PyArray_DOUBLE:
    ret = D_separable_2Dconvolve_mirror((double *)DATA(a_image), 
					(double *)DATA(out), M, N, 
					(double *)DATA(a_hrow), 
					(double *)DATA(a_hcol),
					DIMS(a_hrow)[0], DIMS(a_hcol)[0], 
					instrides, outstrides);
    break;
#ifdef __GNUC__
  case PyArray_CFLOAT:
    ret = C_separable_2Dconvolve_mirror((__complex__ float *)DATA(a_image), 
					(__complex__ float *)DATA(out), M, N, 
					(__complex__ float *)DATA(a_hrow), 
					(__complex__ float *)DATA(a_hcol),
					DIMS(a_hrow)[0], DIMS(a_hcol)[0], 
					instrides, outstrides);
    break;
  case PyArray_CDOUBLE:
    ret = Z_separable_2Dconvolve_mirror((__complex__ double *)DATA(a_image), 
					(__complex__ double *)DATA(out), M, N, 
					(__complex__ double *)DATA(a_hrow), 
					(__complex__ double *)DATA(a_hcol),
					DIMS(a_hrow)[0], DIMS(a_hcol)[0], 
					instrides, outstrides);
    break;
#endif
  default:
    PYERR("Incorrect type.");
  }
  
  if (ret < 0) PYERR("Problem occured inside routine.");

  Py_DECREF(a_image);
  Py_DECREF(a_hrow);
  Py_DECREF(a_hcol);
  return PyArray_Return(out);
 
 fail:
  Py_XDECREF(a_image);
  Py_XDECREF(a_hrow);
  Py_XDECREF(a_hcol);
  Py_XDECREF(out);
  return NULL;

}
Beispiel #21
0
static PyObject*
PyUnits_convert(
    PyUnits* self,
    PyObject* args,
    PyObject* kwds) {

  int            status       = 1;
  PyObject*      input        = NULL;
  PyArrayObject* input_arr    = NULL;
  PyArrayObject* output_arr   = NULL;
  PyObject*      input_iter   = NULL;
  PyObject*      output_iter  = NULL;
  double         input_val;
  double         output_val;

  if (!PyArg_ParseTuple(args, "O:UnitConverter.convert", &input)) {
    goto exit;
  }

  input_arr = (PyArrayObject*)PyArray_FromObject(
      input, NPY_DOUBLE, 0, NPY_MAXDIMS);
  if (input_arr == NULL) {
    goto exit;
  }

  output_arr = (PyArrayObject*)PyArray_SimpleNew(
      PyArray_NDIM(input_arr), PyArray_DIMS(input_arr), PyArray_DOUBLE);
  if (output_arr == NULL) {
    goto exit;
  }

  input_iter = PyArray_IterNew((PyObject*)input_arr);
  if (input_iter == NULL) {
    goto exit;
  }

  output_iter = PyArray_IterNew((PyObject*)output_arr);
  if (output_iter == NULL) {
    goto exit;
  }

  if (self->power != 1.0) {
    while (PyArray_ITER_NOTDONE(input_iter)) {
      input_val = *(double *)PyArray_ITER_DATA(input_iter);
      output_val = pow(self->scale*input_val + self->offset, self->power);
      if (errno) {
        PyErr_SetFromErrno(PyExc_ValueError);
        goto exit;
      }
      *(double *)PyArray_ITER_DATA(output_iter) = output_val;
      PyArray_ITER_NEXT(input_iter);
      PyArray_ITER_NEXT(output_iter);
    }
  } else {
    while (PyArray_ITER_NOTDONE(input_iter)) {
      input_val = *(double *)PyArray_ITER_DATA(input_iter);
      output_val = self->scale*input_val + self->offset;
      *(double *)PyArray_ITER_DATA(output_iter) = output_val;
      PyArray_ITER_NEXT(input_iter);
      PyArray_ITER_NEXT(output_iter);
    }
  }

  status = 0;

 exit:

  Py_XDECREF((PyObject*)input_arr);
  Py_XDECREF(input_iter);
  Py_XDECREF(output_iter);
  if (status) {
    Py_XDECREF((PyObject*)output_arr);
    return NULL;
  }
  return (PyObject*)output_arr;
}
Beispiel #22
0
/*
 * Returns input array with values inserted sequentially into places
 * indicated by the mask
 */
NPY_NO_EXPORT PyObject *
arr_insert(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict)
{
    PyObject *mask = NULL, *vals = NULL;
    PyArrayObject *ainput = NULL, *amask = NULL, *avals = NULL, *tmp = NULL;
    int numvals, totmask, sameshape;
    char *input_data, *mptr, *vptr, *zero = NULL;
    int melsize, delsize, nd, objarray, k;
    npy_intp *instrides, *inshape;

    static char *kwlist[] = {"input", "mask", "vals", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O&OO", kwlist,
                PyArray_Converter, &ainput,
                &mask, &vals)) {
        goto fail;
    }

    amask = (PyArrayObject *)PyArray_FROM_OF(mask, NPY_ARRAY_CARRAY);
    if (amask == NULL) {
        goto fail;
    }
    /* Cast an object array */
    if (PyArray_DESCR(amask)->type_num == NPY_OBJECT) {
        tmp = (PyArrayObject *)PyArray_Cast(amask, NPY_INTP);
        if (tmp == NULL) {
            goto fail;
        }
        Py_DECREF(amask);
        amask = tmp;
    }

    sameshape = 1;
    if (PyArray_NDIM(amask) == PyArray_NDIM(ainput)) {
        for (k = 0; k < PyArray_NDIM(amask); k++) {
            if (PyArray_DIMS(amask)[k] != PyArray_DIMS(ainput)[k]) {
                sameshape = 0;
            }
        }
    }
    else {
        /* Test to see if amask is 1d */
        if (PyArray_NDIM(amask) != 1) {
            sameshape = 0;
        }
        else if ((PyArray_SIZE(ainput)) != PyArray_SIZE(amask)) {
            sameshape = 0;
        }
    }
    if (!sameshape) {
        PyErr_SetString(PyExc_TypeError,
                        "mask array must be 1-d or same shape as input array");
        goto fail;
    }

    avals = (PyArrayObject *)PyArray_FromObject(vals,
                                        PyArray_DESCR(ainput)->type_num, 0, 1);
    if (avals == NULL) {
        goto fail;
    }
    numvals = PyArray_SIZE(avals);
    nd = PyArray_NDIM(ainput);
    input_data = PyArray_DATA(ainput);
    mptr = PyArray_DATA(amask);
    melsize = PyArray_DESCR(amask)->elsize;
    vptr = PyArray_DATA(avals);
    delsize = PyArray_DESCR(avals)->elsize;
    zero = PyArray_Zero(amask);
    if (zero == NULL) {
        goto fail;
    }
    objarray = (PyArray_DESCR(ainput)->type_num == NPY_OBJECT);

    if (!numvals) {
        /* nothing to insert! fail unless none of mask is true */
        const char *iter = mptr;
        const char *const last = iter + PyArray_NBYTES(amask);
        while (iter != last && !memcmp(iter, zero, melsize)) {
            iter += melsize;
        }
        if (iter != last) {
            PyErr_SetString(PyExc_ValueError,
                    "Cannot insert from an empty array!");
            goto fail;
        }
        goto finish;
    }

    /* Handle zero-dimensional case separately */
    if (nd == 0) {
        if (memcmp(mptr,zero,melsize) != 0) {
            /* Copy value element over to input array */
            memcpy(input_data,vptr,delsize);
            if (objarray) {
                Py_INCREF(*((PyObject **)vptr));
            }
        }
        Py_DECREF(amask);
        Py_DECREF(avals);
        PyDataMem_FREE(zero);
        Py_DECREF(ainput);
        Py_RETURN_NONE;
    }

    totmask = (int) PyArray_SIZE(amask);
    instrides = PyArray_STRIDES(ainput);
    inshape = PyArray_DIMS(ainput);
    if (objarray) {
        /* object array, need to refcount, can't release the GIL */
        arr_insert_loop(mptr, vptr, input_data, zero, PyArray_DATA(avals),
                        melsize, delsize, objarray, totmask, numvals, nd,
                        instrides, inshape);
    }
    else {
        /* No increfs take place in arr_insert_loop, so release the GIL */
        NPY_BEGIN_ALLOW_THREADS;
        arr_insert_loop(mptr, vptr, input_data, zero, PyArray_DATA(avals),
                        melsize, delsize, objarray, totmask, numvals, nd,
                        instrides, inshape);
        NPY_END_ALLOW_THREADS;
    }

finish:
    Py_DECREF(amask);
    Py_DECREF(avals);
    PyDataMem_FREE(zero);
    Py_DECREF(ainput);
    Py_RETURN_NONE;

fail:
    PyDataMem_FREE(zero);
    Py_XDECREF(ainput);
    Py_XDECREF(amask);
    Py_XDECREF(avals);
    return NULL;
}
static PyObject *IIRsymorder1(PyObject *NPY_UNUSED(dummy), PyObject *args)
{
  PyObject *sig=NULL;
  PyArrayObject *a_sig=NULL, *out=NULL;
  Py_complex c0, z1;
  double precision = -1.0;
  int thetype, N, ret;
  npy_intp outstrides, instrides;

  if (!PyArg_ParseTuple(args, "ODD|d", &sig, &c0, &z1, &precision))
    return NULL;

  thetype = PyArray_ObjectType(sig, PyArray_FLOAT);
  thetype = NPY_MIN(thetype, PyArray_CDOUBLE);
  a_sig = (PyArrayObject *)PyArray_FromObject(sig, thetype, 1, 1);
  
  if ((a_sig == NULL)) goto fail;
  
  out = (PyArrayObject *)PyArray_SimpleNew(1,DIMS(a_sig),thetype);
  if (out == NULL) goto fail;
  N = DIMS(a_sig)[0];

  convert_strides(STRIDES(a_sig), &instrides, ELSIZE(a_sig), 1);
  outstrides = 1;

  switch (thetype) {
  case PyArray_FLOAT:
    {
      float rc0 = c0.real;
      float rz1 = z1.real;

      if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-6;      
      ret = S_IIR_forback1 (rc0, rz1, (float *)DATA(a_sig), 
			    (float *)DATA(out), N,
			    instrides, outstrides, (float )precision);
    }
    break;
  case PyArray_DOUBLE:
    {
      double rc0 = c0.real;
      double rz1 = z1.real;

      if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-11;
      ret = D_IIR_forback1 (rc0, rz1, (double *)DATA(a_sig), 
			    (double *)DATA(out), N,
			    instrides, outstrides, precision);
    }
    break;
#ifdef __GNUC__
  case PyArray_CFLOAT:
    {
      __complex__ float zc0 = c0.real + 1.0i*c0.imag;
      __complex__ float zz1 = z1.real + 1.0i*z1.imag;      
      if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-6;
      ret = C_IIR_forback1 (zc0, zz1, (__complex__ float *)DATA(a_sig), 
			    (__complex__ float *)DATA(out), N,
			    instrides, outstrides, (float )precision);
    }
    break;
  case PyArray_CDOUBLE:
    {
      __complex__ double zc0 = c0.real + 1.0i*c0.imag;
      __complex__ double zz1 = z1.real + 1.0i*z1.imag;      
      if ((precision <= 0.0) || (precision > 1.0)) precision = 1e-11;
      ret = Z_IIR_forback1 (zc0, zz1, (__complex__ double *)DATA(a_sig), 
			    (__complex__ double *)DATA(out), N,
			    instrides, outstrides, precision);
    }
    break;
#endif
  default:
    PYERR("Incorrect type.");
  }

  if (ret == 0) {
    Py_DECREF(a_sig);
    return PyArray_Return(out);
  }

  if (ret == -1) PYERR("Could not allocate enough memory.");
  if (ret == -2) PYERR("|z1| must be less than 1.0");
  if (ret == -3) PYERR("Sum to find symmetric boundary conditions did not converge.");

  PYERR("Unknown error.");

 
 fail:
  Py_XDECREF(a_sig);
  Py_XDECREF(out);
  return NULL;

}