Example #1
0
static
PyObject* NRT_adapt_ndarray_to_python(arystruct_t* arystruct, int ndim,
                                      int writeable, PyArray_Descr *descr) {
    PyArrayObject *array;
    MemInfoObject *miobj = NULL;
    PyObject *args;
    npy_intp *shape, *strides;
    int flags = 0;

    if (!PyArray_DescrCheck(descr)) {
        PyErr_Format(PyExc_TypeError,
                     "expected dtype object, got '%.200s'",
                     Py_TYPE(descr)->tp_name);
        return NULL;
    }

    if (arystruct->parent) {
        PyObject *obj = try_to_return_parent(arystruct, ndim, descr);
        if (obj)
            return obj;
    }

    if (arystruct->meminfo) {
        /* wrap into MemInfoObject */
        miobj = PyObject_New(MemInfoObject, &MemInfoType);
        args = PyTuple_New(1);
        /* SETITEM steals reference */
        PyTuple_SET_ITEM(args, 0, PyLong_FromVoidPtr(arystruct->meminfo));
        if (MemInfo_init(miobj, args, NULL)) {
            return NULL;
        }
        Py_DECREF(args);
    }

    shape = arystruct->shape_and_strides;
    strides = shape + ndim;
    Py_INCREF((PyObject *) descr);
    array = (PyArrayObject *) PyArray_NewFromDescr(&PyArray_Type, descr, ndim,
                                                   shape, strides, arystruct->data,
                                                   flags, (PyObject *) miobj);

    if (array == NULL)
        return NULL;

    /* Set writable */
#if NPY_API_VERSION >= 0x00000007
    if (writeable) {
        PyArray_ENABLEFLAGS(array, NPY_ARRAY_WRITEABLE);
    }
    else {
        PyArray_CLEARFLAGS(array, NPY_ARRAY_WRITEABLE);
    }
#else
    if (writeable) {
        array->flags |= NPY_WRITEABLE;
    }
    else {
        array->flags &= ~NPY_WRITEABLE;
    }
#endif

    if (miobj) {
        /* Set the MemInfoObject as the base object */
#if NPY_API_VERSION >= 0x00000007
        if (-1 == PyArray_SetBaseObject(array,
                                        (PyObject *) miobj))
        {
            Py_DECREF(array);
            Py_DECREF(miobj);
            return NULL;
        }
#else
        PyArray_BASE(array) = (PyObject *) miobj;
#endif

    }
    return (PyObject *) array;
}
Example #2
0
static PyObject *csolve(PyObject* self, PyObject *args, PyObject *kwargs) {
    /* data structures for arguments */
    PyArrayObject *Ax, *Ai, *Ap, *c, *b;
    PyObject *cone, *warm = SCS_NULL;
    PyObject *verbose = SCS_NULL;
    PyObject *normalize = SCS_NULL;
    /* get the typenum for the primitive scs_int and scs_float types */
    int scs_intType = getIntType();
    int scs_floatType = getFloatType();
    struct ScsPyData ps = { SCS_NULL, SCS_NULL, SCS_NULL, SCS_NULL, SCS_NULL, };
    /* scs data structures */
    Data * d = scs_calloc(1, sizeof(Data));
    Cone * k = scs_calloc(1, sizeof(Cone));

    AMatrix * A;
	Sol sol = { 0 };
	Info info;
	char *kwlist[] = { "shape", "Ax", "Ai", "Ap", "b", "c", "cone", "warm",
        "verbose", "normalize", "max_iters", "scale", "eps", "cg_rate", "alpha", "rho_x", SCS_NULL };
	
    /* parse the arguments and ensure they are the correct type */
#ifdef DLONG
    #ifdef FLOAT
    char *argparse_string = "(ll)O!O!O!O!O!O!|O!O!O!lfffff";
    char *outarg_string = "{s:l,s:l,s:f,s:f,s:f,s:f,s:f,s:f,s:f,s:f,s:f,s:s}";
    #else
    char *argparse_string = "(ll)O!O!O!O!O!O!|O!O!O!lddddd";
    char *outarg_string = "{s:l,s:l,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:s}";
    #endif
#else
    #ifdef FLOAT
	char *argparse_string = "(ii)O!O!O!O!O!O!|O!O!O!ifffff";
	char *outarg_string = "{s:i,s:i,s:f,s:f,s:f,s:f,s:f,s:f,s:f,s:f,s:f,s:s}";
    #else
	char *argparse_string = "(ii)O!O!O!O!O!O!|O!O!O!iddddd";
	char *outarg_string = "{s:i,s:i,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:s}";
    #endif
#endif
    npy_intp veclen[1];
    PyObject *x, *y, *s, *returnDict, *infoDict;
    
    d->stgs = scs_malloc(sizeof(Settings));

    /* set defaults */
	setDefaultSettings(d);

	if ( !PyArg_ParseTupleAndKeywords(args, kwargs, argparse_string, kwlist, 
        &(d->m), 
        &(d->n), 
        &PyArray_Type, &Ax,
		&PyArray_Type, &Ai, 
        &PyArray_Type, &Ap, 
        &PyArray_Type, &b, 
        &PyArray_Type, &c, 
        &PyDict_Type, &cone,
        &PyDict_Type, &warm,
        &PyBool_Type, &verbose,
        &PyBool_Type, &normalize,
        &(d->stgs->max_iters),
        &(d->stgs->scale),
        &(d->stgs->eps),
        &(d->stgs->cg_rate),
        &(d->stgs->alpha),
        &(d->stgs->rho_x)) ) {
        PySys_WriteStderr("error parsing inputs\n");
        return SCS_NULL; 
    }

	if (d->m < 0) {
		PyErr_SetString(PyExc_ValueError, "m must be a positive integer");
		return SCS_NULL;
	}

	if (d->n < 0) {
		PyErr_SetString(PyExc_ValueError, "n must be a positive integer");
		return SCS_NULL;
	}

    /* set A */
	if (!PyArray_ISFLOAT(Ax) || PyArray_NDIM(Ax) != 1) {
		return finishWithErr(d, k, &ps, "Ax must be a numpy array of floats");
	}
	if (!PyArray_ISINTEGER(Ai) || PyArray_NDIM(Ai) != 1) {
		return finishWithErr(d, k, &ps, "Ai must be a numpy array of ints");
	}
	if (!PyArray_ISINTEGER(Ap) || PyArray_NDIM(Ap) != 1) {
		return finishWithErr(d, k, &ps, "Ap must be a numpy array of ints");
	}
	ps.Ax = getContiguous(Ax, scs_floatType);
	ps.Ai = getContiguous(Ai, scs_intType);
	ps.Ap = getContiguous(Ap, scs_intType);

    A = scs_malloc(sizeof(AMatrix));
	A->n = d->n;
    A->m = d->m;
    A->x = (scs_float *) PyArray_DATA(ps.Ax);
	A->i = (scs_int *) PyArray_DATA(ps.Ai);
	A->p = (scs_int *) PyArray_DATA(ps.Ap);
	d->A = A;
	/*d->Anz = d->Ap[d->n]; */
	/*d->Anz = PyArray_DIM(Ai,0); */
	/* set c */
	if (!PyArray_ISFLOAT(c) || PyArray_NDIM(c) != 1) {
		return finishWithErr(d, k, &ps, "c must be a dense numpy array with one dimension");
	}
	if (PyArray_DIM(c,0) != d->n) {
		return finishWithErr(d, k, &ps, "c has incompatible dimension with A");
	}
	ps.c = getContiguous(c, scs_floatType);
	d->c = (scs_float *) PyArray_DATA(ps.c);
	/* set b */
	if (!PyArray_ISFLOAT(b) || PyArray_NDIM(b) != 1) {
		return finishWithErr(d, k, &ps, "b must be a dense numpy array with one dimension");
	}
	if (PyArray_DIM(b,0) != d->m) {
		return finishWithErr(d, k, &ps, "b has incompatible dimension with A");
	}
	ps.b = getContiguous(b, scs_floatType);
	d->b = (scs_float *) PyArray_DATA(ps.b);
    
    if (getPosIntParam("f", &(k->f), 0, cone) < 0) {
		return finishWithErr(d, k, &ps, "failed to parse cone field f");
	}
	if (getPosIntParam("l", &(k->l), 0, cone) < 0) {
		return finishWithErr(d, k, &ps, "failed to parse cone field l");
	}
	if (getConeArrDim("q", &(k->q), &(k->qsize), cone) < 0) {
		return finishWithErr(d, k, &ps, "failed to parse cone field q");
	}
	if (getConeArrDim("s", &(k->s), &(k->ssize), cone) < 0) {
		return finishWithErr(d, k, &ps, "failed to parse cone field s");
	}
	if (getConeFloatArr("p", &(k->p), &(k->psize), cone) < 0) {
		return finishWithErr(d, k, &ps, "failed to parse cone field p");
	}
	if (getPosIntParam("ep", &(k->ep), 0, cone) < 0) {
		return finishWithErr(d, k, &ps, "failed to parse cone field ep");
	}
	if (getPosIntParam("ed", &(k->ed), 0, cone) < 0) {
		return finishWithErr(d, k, &ps, "failed to parse cone field ed");
	}

    d->stgs->verbose = verbose ? (scs_int) PyObject_IsTrue(verbose) : VERBOSE;
    d->stgs->normalize = normalize ? (scs_int) PyObject_IsTrue(normalize) : NORMALIZE;
    if(d->stgs->max_iters < 0) {
		return finishWithErr(d, k, &ps, "max_iters must be positive");
	}
    if(d->stgs->scale < 0) {
		return finishWithErr(d, k, &ps, "scale must be positive");
	}
    if(d->stgs->eps < 0) {
		return finishWithErr(d, k, &ps, "eps must be positive");
	}
    if(d->stgs->cg_rate < 0) {
		return finishWithErr(d, k, &ps, "cg_rate must be positive");
	}
    if(d->stgs->alpha < 0) {
		return finishWithErr(d, k, &ps, "alpha must be positive");
	}
    if(d->stgs->rho_x < 0) {
		return finishWithErr(d, k, &ps, "rho_x must be positive");
	}
	/* parse warm start if set */
    d->stgs->warm_start = WARM_START;
	if (warm) {
		d->stgs->warm_start = getWarmStart("x", &(sol.x), d->n, warm);
		d->stgs->warm_start |= getWarmStart("y", &(sol.y), d->m, warm);
		d->stgs->warm_start |= getWarmStart("s", &(sol.s), d->m, warm);
	}

    Py_BEGIN_ALLOW_THREADS
    /* Solve! */
    scs(d, k, &sol, &info);
    Py_END_ALLOW_THREADS

	/* create output (all data is *deep copied*) */
	/* x */
	/* matrix *x; */
	/* if(!(x = Matrix_New(n,1,DOUBLE))) */
	/*   return PyErr_NoMemory(); */
	/* memcpy(MAT_BUFD(x), mywork->x, n*sizeof(scs_float)); */
	veclen[0] = d->n;
	x = PyArray_SimpleNewFromData(1, veclen, scs_floatType, sol.x);
    PyArray_ENABLEFLAGS((PyArrayObject *) x, NPY_ARRAY_OWNDATA);

	/* y */
	/* matrix *y; */
	/* if(!(y = Matrix_New(p,1,DOUBLE))) */
	/*   return PyErr_NoMemory(); */
	/* memcpy(MAT_BUFD(y), mywork->y, p*sizeof(scs_float)); */
	veclen[0] = d->m;
	y = PyArray_SimpleNewFromData(1, veclen, scs_floatType, sol.y);
    PyArray_ENABLEFLAGS((PyArrayObject *) y, NPY_ARRAY_OWNDATA);

	/* s */
	/* matrix *s; */
	/* if(!(s = Matrix_New(m,1,DOUBLE))) */
	/*   return PyErr_NoMemory(); */
	/* memcpy(MAT_BUFD(s), mywork->s, m*sizeof(scs_float)); */
	veclen[0] = d->m;
	s = PyArray_SimpleNewFromData(1, veclen, scs_floatType, sol.s);
    PyArray_ENABLEFLAGS((PyArrayObject *) s, NPY_ARRAY_OWNDATA);

    infoDict = Py_BuildValue(outarg_string,
			"statusVal", (scs_int) info.statusVal, "iter", (scs_int) info.iter, "pobj", (scs_float) info.pobj,
			"dobj", (scs_float) info.dobj, "resPri", (scs_float) info.resPri, "resDual", (scs_float) info.resDual,
			"relGap", (scs_float) info.relGap, "resInfeas", (scs_float) info.resInfeas, "resUnbdd", (scs_float) info.resUnbdd,
			"solveTime", (scs_float) (info.solveTime), "setupTime", (scs_float) (info.setupTime),
			"status", info.status);

    returnDict = Py_BuildValue("{s:O,s:O,s:O,s:O}", "x", x, "y", y, "s", s, "info", infoDict);
	/* give up ownership to the return dictionary */
	Py_DECREF(x);
	Py_DECREF(y);
	Py_DECREF(s);
	Py_DECREF(infoDict);

	/* no longer need pointers to arrays that held primitives */
	freePyData(d, k, &ps);
	return returnDict;
}