示例#1
0
static cholmod_sparse *pack(spmatrix *A, char uplo)
{
    int j, k, n = SP_NROWS(A), nnz = 0, cnt = 0;
    cholmod_sparse *B;

    if (uplo == 'L'){
        for (j=0; j<n; j++){
            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] < j;
                k++);
            nnz += SP_COL(A)[j+1] - k;
        }
        if (!(B = CHOL(allocate_sparse)(n, n, nnz, 1, 1, -1,
            (SP_ID(A) == DOUBLE ? CHOLMOD_REAL : CHOLMOD_COMPLEX),
            &Common))) return 0;
        for (j=0; j<n; j++){
            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] < j;
                k++);
       	    for (; k<SP_COL(A)[j+1]; k++) {
                if (SP_ID(A) == DOUBLE)
                    ((double *)B->x)[cnt] = SP_VALD(A)[k];
                else
                    ((double complex *)B->x)[cnt] = SP_VALZ(A)[k];
                ((int_t *)B->p)[j+1]++;
                ((int_t *)B->i)[cnt++] = SP_ROW(A)[k];
	    }
        }
    }
    else {
        for (j=0; j<n; j++)
            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] <= j;
                k++)
                nnz++;
        if (!(B = CHOL(allocate_sparse)(n, n, nnz, 1, 1, 1,
            (SP_ID(A) == DOUBLE ? CHOLMOD_REAL : CHOLMOD_COMPLEX),
            &Common))) return 0;

        for (j=0; j<n; j++)
            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] <= j;
                k++) {
                if (SP_ID(A) == DOUBLE)
                    ((double *)B->x)[cnt] = SP_VALD(A)[k];
                else
                    ((double complex *)B->x)[cnt] = SP_VALZ(A)[k];
            ((int_t *)B->p)[j+1]++;
            ((int_t *)B->i)[cnt++] = SP_ROW(A)[k];
        }
    }
    for (j=0; j<n; j++) ((int_t *)B->p)[j+1] += ((int_t *)B->p)[j];
    return B;
}
示例#2
0
static PyObject* getfactor(PyObject *self, PyObject *args)
{
    PyObject *F;
    cholmod_factor *Lf;
    cholmod_sparse *Ls;
#if PY_MAJOR_VERSION >= 3
    const char *descr;
#else
    char *descr;
#endif

    if (!set_options()) return NULL;
    if (!PyArg_ParseTuple(args, "O", &F)) return NULL;

#if PY_MAJOR_VERSION >= 3
    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
        err_CO("F");
    if (strncmp(descr, "CHOLMOD FACTOR", 14))
        PY_ERR_TYPE("F is not a CHOLMOD factor");
    Lf = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
#else
    if (!PyCObject_Check(F)) err_CO("F");
    descr = PyCObject_GetDesc(F);
    if (!descr || strncmp(descr, "CHOLMOD FACTOR", 14))
        PY_ERR_TYPE("F is not a CHOLMOD factor");
    Lf = (cholmod_factor *) PyCObject_AsVoidPtr(F);
#endif

    /* Check factorization */
    if (Lf->xtype == CHOLMOD_PATTERN)
        PY_ERR(PyExc_ValueError, "F must be a numeric Cholesky factor");

    if (!(Ls = CHOL(factor_to_sparse)(Lf, &Common)))
        return PyErr_NoMemory();

    spmatrix *ret = SpMatrix_New(Ls->nrow, Ls->ncol, Ls->nzmax,
       (Ls->xtype == CHOLMOD_REAL ? DOUBLE : COMPLEX));
    if (!ret) {
        CHOL(free_sparse)(&Ls, &Common);
        return PyErr_NoMemory();
    }

    memcpy(SP_COL(ret), Ls->p, (Ls->ncol+1)*sizeof(int_t));
    memcpy(SP_ROW(ret), Ls->i, (Ls->nzmax)*sizeof(int_t));
    memcpy(SP_VAL(ret), Ls->x, (Ls->nzmax)*E_SIZE[SP_ID(ret)]);
    CHOL(free_sparse)(&Ls, &Common);

    return (PyObject *)ret;
}
示例#3
0
PyMODINIT_FUNC initcholmod(void)
{
    CHOL(start) (&Common);
    cholmod_module = Py_InitModule3("cvxopt.cholmod", cholmod_functions,
        cholmod__doc__);
    PyModule_AddObject(cholmod_module, "options", PyDict_New());
    if (import_cvxopt() < 0) return;
}
示例#4
0
PyMODINIT_FUNC PyInit_cholmod(void)
{
    CHOL(start) (&Common);
    if (!(cholmod_module = PyModule_Create(&cholmod_module_def)))
        return NULL;
    PyModule_AddObject(cholmod_module, "options", PyDict_New());
    if (import_cvxopt() < 0) return NULL;
    return cholmod_module;
}
示例#5
0
static cholmod_sparse * create_matrix(spmatrix *A)
{
    cholmod_sparse *B;

    if (!(B = CHOL(allocate_sparse)(SP_NROWS(A), SP_NCOLS(A), 0,
        1, 0, 0, (SP_ID(A) == DOUBLE ? CHOLMOD_REAL : CHOLMOD_COMPLEX),
        &Common))) return NULL;

    int i;
    for (i=0; i<SP_NCOLS(A); i++)
        ((int_t *)B->nz)[i] = SP_COL(A)[i+1] - SP_COL(A)[i];
    B->x = SP_VAL(A);
    B->i = SP_ROW(A);
    B->nzmax = SP_NNZ(A);
    memcpy(B->p, SP_COL(A), (SP_NCOLS(A)+1)*sizeof(int_t));
    return B;
}
示例#6
0
static PyObject* splinsolve(PyObject *self, PyObject *args,
    PyObject *kwrds)
{
    spmatrix *A, *B, *X;
    matrix *P=NULL;
    int n, nnz;
    cholmod_sparse *Ac=NULL, *Bc=NULL, *Xc=NULL;
    cholmod_factor *L=NULL;
#if PY_MAJOR_VERSION >= 3
    int uplo_='L';
#endif
    char uplo='L';
    char *kwlist[] = {"A", "B", "p", "uplo", NULL};

    if (!set_options()) return NULL;
#if PY_MAJOR_VERSION >= 3
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|OC", kwlist, &A,
        &B, &P, &uplo_)) return NULL;
    uplo = (char) uplo_;
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Oc", kwlist, &A,
        &B, &P, &uplo)) return NULL;
#endif

    if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
        PY_ERR_TYPE("A is not a square sparse matrix");
    n = SP_NROWS(A);
    nnz = SP_NNZ(A);

    if (!SpMatrix_Check(B) || SP_ID(A) != SP_ID(B))
        PY_ERR_TYPE("B must be a sparse matrix of the same type as A");
    if (SP_NROWS(B) != n)
        PY_ERR(PyExc_ValueError, "incompatible dimensions for B");

    if (P) {
        if (!Matrix_Check(P) || MAT_ID(P) != INT) err_int_mtrx("p");
        if (MAT_LGT(P) != n) err_buf_len("p");
        if (!CHOL(check_perm)(P->buffer, n, n, &Common))
            PY_ERR(PyExc_ValueError, "not a valid permutation");
    }

    if (uplo != 'U' && uplo != 'L') err_char("uplo", "'L', 'U'");
    if (!(Ac = pack(A, uplo))) return PyErr_NoMemory();

    L = CHOL(analyze_p) (Ac, P ? MAT_BUFI(P): NULL, NULL, 0, &Common);
    if (Common.status != CHOLMOD_OK){
        CHOL(free_factor)(&L, &Common);
        CHOL(free_sparse)(&Ac, &Common);
        if (Common.status == CHOLMOD_OUT_OF_MEMORY)
            return PyErr_NoMemory();
        else {
            PyErr_SetString(PyExc_ValueError, "symbolic factorization "
                "failed");
            return NULL;
        }
    }

    CHOL(factorize) (Ac, L, &Common);
    CHOL(free_sparse)(&Ac, &Common);
    if (Common.status > 0) switch (Common.status) {
        case CHOLMOD_NOT_POSDEF:
            PyErr_SetObject(PyExc_ArithmeticError, Py_BuildValue("i",
                L->minor));
            CHOL(free_factor)(&L, &Common);
            return NULL;
            break;

        case CHOLMOD_DSMALL:
            /* This never happens unless we change the default value
             * of Common.dbound (0.0).  */
            if (L->is_ll)
                PyErr_Warn(PyExc_RuntimeWarning, "tiny diagonal "
                    "elements in L");
            else
                PyErr_Warn(PyExc_RuntimeWarning, "tiny diagonal "
                    "elements in D");
            break;

        default:
            PyErr_Warn(PyExc_UserWarning, "");
    }

    if (L->minor<n) {
        CHOL(free_factor)(&L, &Common);
        PY_ERR(PyExc_ArithmeticError, "singular matrix");
    }
    if (!(Bc = create_matrix(B))) {
      CHOL(free_factor)(&L, &Common);
      return PyErr_NoMemory();
    }

    Xc = CHOL(spsolve)(0, L, Bc, &Common);
    free_matrix(Bc);
    CHOL(free_factor)(&L, &Common);
    if (Common.status != CHOLMOD_OK){
        CHOL(free_sparse)(&Xc, &Common);
        if (Common.status == CHOLMOD_OUT_OF_MEMORY)
            return PyErr_NoMemory();
        else
            PY_ERR(PyExc_ValueError, "solve step failed");
    }

    if (!(X = SpMatrix_New(Xc->nrow, Xc->ncol,
        ((int_t*)Xc->p)[Xc->ncol], SP_ID(A)))) {
        CHOL(free_sparse)(&Xc, &Common);
        return PyErr_NoMemory();
    }
    memcpy(SP_COL(X), (int_t *) Xc->p, (Xc->ncol+1)*sizeof(int_t));
    memcpy(SP_ROW(X), (int_t *) Xc->i,
        ((int_t *) Xc->p)[Xc->ncol]*sizeof(int_t));
    memcpy(SP_VAL(X), (double *) Xc->x,
        ((int_t *) Xc->p)[Xc->ncol]*E_SIZE[SP_ID(X)]);
    CHOL(free_sparse)(&Xc, &Common);
    return (PyObject *) X;
}
示例#7
0
static int set_options(void)
{
    int_t pos=0;
    PyObject *param, *key, *value;
    char err_str[100];
#if PY_MAJOR_VERSION < 3
    char *keystr; 
#endif

    CHOL(defaults)(&Common);
    Common.print = 0;
    Common.supernodal = 2;

    if (!(param = PyObject_GetAttrString(cholmod_module, "options")) ||
        ! PyDict_Check(param)) {
        PyErr_SetString(PyExc_AttributeError, "missing cholmod.options"
            "dictionary");
        return 0;
    }
    while (PyDict_Next(param, &pos, &key, &value))
#if PY_MAJOR_VERSION >= 3
        if (PyUnicode_Check(key)) {
            const char *keystr = _PyUnicode_AsString(key);
            if (!strcmp("supernodal", keystr) && PyLong_Check(value))
                Common.supernodal = (int) PyLong_AsLong(value);
            else if (!strcmp("print", keystr) && PyLong_Check(value))
                Common.print = (int) PyLong_AsLong(value);
            else if (!strcmp("nmethods", keystr) && PyLong_Check(value))
                Common.nmethods = (int) PyLong_AsLong(value);
            else if (!strcmp("postorder", keystr) &&
                PyBool_Check(value))
                Common.postorder = (int) PyLong_AsLong(value);
            else if (!strcmp("dbound", keystr) && PyFloat_Check(value))
                Common.dbound = (double) PyFloat_AsDouble(value);
            else {
                sprintf(err_str, "invalid value for CHOLMOD parameter:" \
                   " %-.20s", keystr);
                PyErr_SetString(PyExc_ValueError, err_str);
                Py_DECREF(param);
                return 0;
            }
        }
#else
        if ((keystr = PyString_AsString(key))) {
            if (!strcmp("supernodal", keystr) && PyInt_Check(value))
                Common.supernodal = (int) PyInt_AsLong(value);
            else if (!strcmp("print", keystr) && PyInt_Check(value))
                Common.print = (int) PyInt_AsLong(value);
            else if (!strcmp("nmethods", keystr) && PyInt_Check(value))
                Common.nmethods = (int) PyInt_AsLong(value);
            else if (!strcmp("postorder", keystr) &&
                PyBool_Check(value))
                Common.postorder = (int) PyInt_AsLong(value);
            else if (!strcmp("dbound", keystr) && PyFloat_Check(value))
                Common.dbound = (double) PyFloat_AsDouble(value);
            else {
                sprintf(err_str, "invalid value for CHOLMOD parameter:" \
                   " %-.20s", keystr);
                PyErr_SetString(PyExc_ValueError, err_str);
                Py_DECREF(param);
                return 0;
            }
        }
#endif
    Py_DECREF(param);
    return 1;
}
示例#8
0
static PyObject* linsolve(PyObject *self, PyObject *args,
    PyObject *kwrds)
{
    spmatrix *A;
    matrix *B, *P=NULL;
    int i, n, nnz, oB=0, ldB=0, nrhs=-1;
    cholmod_sparse *Ac=NULL;
    cholmod_factor *L=NULL;
    cholmod_dense *x=NULL, *b=NULL;
    void *b_old;
#if PY_MAJOR_VERSION >= 3
    int uplo_ = 'L';
#endif
    char uplo='L';
    char *kwlist[] = {"A", "B", "p", "uplo", "nrhs", "ldB", "offsetB",
        NULL};

    if (!set_options()) return NULL;
#if PY_MAJOR_VERSION >= 3
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|OCiii", kwlist,
        &A,  &B, &P, &uplo_, &nrhs, &ldB, &oB)) return NULL;
    uplo = (char) uplo_;
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ociii", kwlist,
        &A,  &B, &P, &uplo, &nrhs, &ldB, &oB)) return NULL;
#endif

    if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
        PY_ERR_TYPE("A is not a sparse matrix");
    n = SP_NROWS(A);
    nnz = SP_NNZ(A);

    if (!Matrix_Check(B) || MAT_ID(B) != SP_ID(A))
        PY_ERR_TYPE("B must be a dense matrix of the same numerical "
            "type as A");
    if (nrhs < 0) nrhs = MAT_NCOLS(B);
    if (n == 0 || nrhs == 0) return Py_BuildValue("");
    if (ldB == 0) ldB = MAX(1,MAT_NROWS(B));
    if (ldB < MAX(1,n)) err_ld("ldB");
    if (oB < 0) err_nn_int("offsetB");
    if (oB + (nrhs-1)*ldB + n > MAT_LGT(B)) err_buf_len("B");

    if (P) {
        if (!Matrix_Check(P) || MAT_ID(P) != INT) err_int_mtrx("p");
        if (MAT_LGT(P) != n) err_buf_len("p");
        if (!CHOL(check_perm)(P->buffer, n, n, &Common))
            PY_ERR(PyExc_ValueError, "not a valid permutation");
    }
    if (uplo != 'U' && uplo != 'L') err_char("uplo", "'L', 'U'");

    if (!(Ac = pack(A, uplo))) return PyErr_NoMemory();
    L = CHOL(analyze_p)(Ac, P ? MAT_BUFI(P): NULL, NULL, 0, &Common);
    if (Common.status != CHOLMOD_OK){
        free_matrix(Ac);
        CHOL(free_sparse)(&Ac, &Common);
        CHOL(free_factor)(&L, &Common);
        if (Common.status == CHOLMOD_OUT_OF_MEMORY)
            return PyErr_NoMemory();
        else {
            PyErr_SetString(PyExc_ValueError, "symbolic factorization "
                "failed");
            return NULL;
        }
    }

    CHOL(factorize) (Ac, L, &Common);
    CHOL(free_sparse)(&Ac, &Common);
    if (Common.status < 0) {
        CHOL(free_factor)(&L, &Common);
        switch (Common.status) {
            case CHOLMOD_OUT_OF_MEMORY:
                return PyErr_NoMemory();

            default:
                PyErr_SetString(PyExc_ValueError, "factorization "
                    "failed");
                return NULL;
        }
    }
    if (Common.status > 0) switch (Common.status) {
        case CHOLMOD_NOT_POSDEF:
            PyErr_SetObject(PyExc_ArithmeticError,
                Py_BuildValue("i", L->minor));
            CHOL(free_factor)(&L, &Common);
            return NULL;
            break;

        case CHOLMOD_DSMALL:
            /* This never happens unless we change the default value
             * of Common.dbound (0.0).  */
            if (L->is_ll)
                PyErr_Warn(PyExc_RuntimeWarning, "tiny diagonal "
                    "elements in L");
            else
                PyErr_Warn(PyExc_RuntimeWarning, "tiny diagonal "
                    "elements in D");
            break;

        default:
            PyErr_Warn(PyExc_UserWarning, "");
    }

    if (L->minor<n) {
        CHOL(free_factor)(&L, &Common);
        PY_ERR(PyExc_ArithmeticError, "singular matrix");
    }
    b = CHOL(allocate_dense)(n, 1, n, (MAT_ID(B) == DOUBLE ?
        CHOLMOD_REAL : CHOLMOD_COMPLEX) , &Common);
    if (Common.status == CHOLMOD_OUT_OF_MEMORY) {
        CHOL(free_factor)(&L, &Common);
        CHOL(free_dense)(&b, &Common);
        return PyErr_NoMemory();
    }
    b_old = b->x;
    for (i=0; i<nrhs; i++) {
        b->x = MAT_BUF(B) + (i*ldB + oB)*E_SIZE[MAT_ID(B)];
        x = CHOL(solve) (CHOLMOD_A, L, b, &Common);
        if (Common.status != CHOLMOD_OK){
            PyErr_SetString(PyExc_ValueError, "solve step failed");
            CHOL(free_factor)(&L, &Common);
            b->x = b_old;
            CHOL(free_dense)(&b, &Common);
            CHOL(free_dense)(&x, &Common);
            return NULL;
        }
        memcpy(b->x, x->x, SP_NROWS(A)*E_SIZE[MAT_ID(B)]);
        CHOL(free_dense)(&x, &Common);
    }
    b->x = b_old;
    CHOL(free_dense)(&b, &Common);
    CHOL(free_factor)(&L, &Common);
    return Py_BuildValue("");
}
示例#9
0
static PyObject* spsolve(PyObject *self, PyObject *args,
    PyObject *kwrds)
{
    spmatrix *B, *X=NULL;
    cholmod_sparse *Bc=NULL, *Xc=NULL;
    PyObject *F;
    cholmod_factor *L;
    int n, sys=0;
#if PY_MAJOR_VERSION >= 3
    const char *descr;
#else
    char *descr;
#endif
    char *kwlist[] = {"F", "B", "sys", NULL};
    int sysvalues[] = {CHOLMOD_A, CHOLMOD_LDLt, CHOLMOD_LD,
        CHOLMOD_DLt, CHOLMOD_L, CHOLMOD_Lt, CHOLMOD_D, CHOLMOD_P,
        CHOLMOD_Pt };

    if (!set_options()) return NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|i", kwlist, &F,
        &B, &sys)) return NULL;

#if PY_MAJOR_VERSION >= 3
    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
        err_CO("F");
    if (strncmp(descr, "CHOLMOD FACTOR", 14))
        PY_ERR_TYPE("F is not a CHOLMOD factor");
    L = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
#else
    if (!PyCObject_Check(F)) err_CO("F");
    descr = PyCObject_GetDesc(F);
    if (!descr || strncmp(descr, "CHOLMOD FACTOR", 14))
        PY_ERR_TYPE("F is not a CHOLMOD factor");
    L = (cholmod_factor *) PyCObject_AsVoidPtr(F);
#endif
    if (L->xtype == CHOLMOD_PATTERN)
        PY_ERR(PyExc_ValueError, "called with symbolic factor");
    n = L->n;
    if (L->minor<n) PY_ERR(PyExc_ArithmeticError, "singular matrix");

    if (sys < 0 || sys > 8)
         PY_ERR(PyExc_ValueError, "invalid value for sys");

    if (!SpMatrix_Check(B) ||
        (SP_ID(B) == DOUBLE  && L->xtype == CHOLMOD_COMPLEX) ||
        (SP_ID(B) == COMPLEX && L->xtype == CHOLMOD_REAL))
            PY_ERR_TYPE("B must a sparse matrix of the same "
                "numerical type as F");
    if (SP_NROWS(B) != n)
        PY_ERR(PyExc_ValueError, "incompatible dimensions for B");

    if (!(Bc = create_matrix(B))) return PyErr_NoMemory();
    Xc = CHOL(spsolve)(sysvalues[sys], L, Bc, &Common);
    free_matrix(Bc);
    if (Common.status == CHOLMOD_OUT_OF_MEMORY) return PyErr_NoMemory();
    if (Common.status != CHOLMOD_OK)
        PY_ERR(PyExc_ValueError, "solve step failed");

    if (!(X = SpMatrix_New(Xc->nrow, Xc->ncol,
        ((int_t*)Xc->p)[Xc->ncol], (L->xtype == CHOLMOD_REAL ? DOUBLE :
        COMPLEX)))) {
        CHOL(free_sparse)(&Xc, &Common);
        return PyErr_NoMemory();
    }
    memcpy(SP_COL(X), Xc->p, (Xc->ncol+1)*sizeof(int_t));
    memcpy(SP_ROW(X), Xc->i, ((int_t *)Xc->p)[Xc->ncol]*sizeof(int_t));
    memcpy(SP_VAL(X), Xc->x,
        ((int_t *) Xc->p)[Xc->ncol]*E_SIZE[SP_ID(X)]);
    CHOL(free_sparse)(&Xc, &Common);
    return (PyObject *) X;
}
示例#10
0
static PyObject* solve(PyObject *self, PyObject *args, PyObject *kwrds)
{
    matrix *B;
    PyObject *F;
    int i, n, oB=0, ldB=0, nrhs=-1, sys=0;
#if PY_MAJOR_VERSION >= 3
    const char *descr;
#else
    char *descr;
#endif
    char *kwlist[] = {"F", "B", "sys", "nrhs", "ldB", "offsetB", NULL};
    int sysvalues[] = { CHOLMOD_A, CHOLMOD_LDLt, CHOLMOD_LD,
        CHOLMOD_DLt, CHOLMOD_L, CHOLMOD_Lt, CHOLMOD_D, CHOLMOD_P,
        CHOLMOD_Pt };

    if (!set_options()) return NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|iiii", kwlist,
        &F, &B, &sys, &nrhs, &ldB, &oB)) return NULL;

#if PY_MAJOR_VERSION >= 3
    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
        err_CO("F");
    if (strncmp(descr, "CHOLMOD FACTOR", 14))
        PY_ERR_TYPE("F is not a CHOLMOD factor");
    cholmod_factor *L = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
#else
    if (!PyCObject_Check(F)) err_CO("F");
    descr = PyCObject_GetDesc(F);
    if (!descr || strncmp(descr, "CHOLMOD FACTOR", 14))
        PY_ERR_TYPE("F is not a CHOLMOD factor");
    cholmod_factor *L = (cholmod_factor *) PyCObject_AsVoidPtr(F);
#endif
    if (L->xtype == CHOLMOD_PATTERN)
        PY_ERR(PyExc_ValueError, "called with symbolic factor");

    n = L->n;
    if (L->minor<n) PY_ERR(PyExc_ArithmeticError, "singular matrix");

    if (sys < 0 || sys > 8)
         PY_ERR(PyExc_ValueError, "invalid value for sys");

    if (!Matrix_Check(B) || MAT_ID(B) == INT ||
        (MAT_ID(B) == DOUBLE && L->xtype == CHOLMOD_COMPLEX) ||
        (MAT_ID(B) == COMPLEX && L->xtype == CHOLMOD_REAL))
            PY_ERR_TYPE("B must a dense matrix of the same numerical "
                "type as F");

    if (nrhs < 0) nrhs = MAT_NCOLS(B);
    if (n == 0 || nrhs == 0) return Py_BuildValue("");
    if (ldB == 0) ldB = MAX(1,MAT_NROWS(B));
    if (ldB < MAX(1,n)) err_ld("ldB");
    if (oB < 0) err_nn_int("offsetB");
    if (oB + (nrhs-1)*ldB + n > MAT_LGT(B)) err_buf_len("B");

    cholmod_dense *x;
    cholmod_dense *b = CHOL(allocate_dense)(n, 1, n,
        (MAT_ID(B) == DOUBLE ? CHOLMOD_REAL : CHOLMOD_COMPLEX),
        &Common);
    if (Common.status == CHOLMOD_OUT_OF_MEMORY) return PyErr_NoMemory();

    void *b_old = b->x;
    for (i=0; i<nrhs; i++){
        b->x = MAT_BUF(B) + (i*ldB + oB)*E_SIZE[MAT_ID(B)];
        x = CHOL(solve) (sysvalues[sys], L, b, &Common);
        if (Common.status != CHOLMOD_OK){
            PyErr_SetString(PyExc_ValueError, "solve step failed");
            CHOL(free_dense)(&x, &Common);
            CHOL(free_dense)(&b, &Common);
	    return NULL;
	}
	memcpy(b->x, x->x, n*E_SIZE[MAT_ID(B)]);
        CHOL(free_dense)(&x, &Common);
    }
    b->x = b_old;
    CHOL(free_dense)(&b, &Common);

    return Py_BuildValue("");
}
示例#11
0
static PyObject* numeric(PyObject *self, PyObject *args)
{
    spmatrix *A;
    PyObject *F;
    cholmod_factor *Lc;
    cholmod_sparse *Ac = NULL;
    char uplo;
#if PY_MAJOR_VERSION >= 3
    const char *descr; 
#else
    char *descr; 
#endif

    if (!set_options()) return NULL;

    if (!PyArg_ParseTuple(args, "OO", &A, &F)) return NULL;

    if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
        PY_ERR_TYPE("A is not a sparse matrix");

#if PY_MAJOR_VERSION >= 3
    if (!PyCapsule_CheckExact(F) || !(descr = PyCapsule_GetName(F)))
        err_CO("F");
#else
    if (!PyCObject_Check(F)) err_CO("F");
    descr = PyCObject_GetDesc(F);
    if (!descr) PY_ERR_TYPE("F is not a CHOLMOD factor");
#endif
    if (SP_ID(A) == DOUBLE){
        if (!strcmp(descr, "CHOLMOD FACTOR D L"))
	    uplo = 'L';
	else if (!strcmp(descr, "CHOLMOD FACTOR D U"))
	    uplo = 'U';
        else
	    PY_ERR_TYPE("F is not the CHOLMOD factor of a 'd' matrix");
    } else {
        if (!strcmp(descr, "CHOLMOD FACTOR Z L"))
	    uplo = 'L';
	else if (!strcmp(descr, "CHOLMOD FACTOR Z U"))
	    uplo = 'U';
        else
	    PY_ERR_TYPE("F is not the CHOLMOD factor of a 'z' matrix");
    }
#if PY_MAJOR_VERSION >= 3
    Lc = (cholmod_factor *) PyCapsule_GetPointer(F, descr);
#else
    Lc = (cholmod_factor *) PyCObject_AsVoidPtr(F);
#endif
    if (!(Ac = pack(A, uplo))) return PyErr_NoMemory();
    CHOL(factorize) (Ac, Lc, &Common);
    CHOL(free_sparse)(&Ac, &Common);

    if (Common.status < 0) switch (Common.status) {
        case CHOLMOD_OUT_OF_MEMORY:
            return PyErr_NoMemory();

        default:
            PyErr_SetString(PyExc_ValueError, "factorization failed");
            return NULL;
    }

    if (Common.status > 0) switch (Common.status) {
        case CHOLMOD_NOT_POSDEF:
            PyErr_SetObject(PyExc_ArithmeticError, Py_BuildValue("i",
                Lc->minor));
            return NULL;
            break;

        case CHOLMOD_DSMALL:
            /* This never happens unless we change the default value
             * of Common.dbound (0.0).  */
            if (Lc->is_ll)
                PyErr_Warn(PyExc_RuntimeWarning, "tiny diagonal "\
                    "elements in L");
            else
                PyErr_Warn(PyExc_RuntimeWarning, "tiny diagonal "\
                    "elements in D");
            break;

        default:
            PyErr_Warn(PyExc_UserWarning, "");
    }

    return Py_BuildValue("");
}
示例#12
0
static PyObject* symbolic(PyObject *self, PyObject *args,
    PyObject *kwrds)
{
    spmatrix *A;
    cholmod_sparse *Ac = NULL;
    cholmod_factor *L;
    matrix *P=NULL;
#if PY_MAJOR_VERSION >= 3
    int uplo_='L';
#endif
    char uplo='L';
    int n;
    char *kwlist[] = {"A", "p", "uplo", NULL};

    if (!set_options()) return NULL;

#if PY_MAJOR_VERSION >= 3
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|OC", kwlist, &A,
        &P, &uplo_)) return NULL;
    uplo = (char) uplo_;
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|Oc", kwlist, &A,
        &P, &uplo)) return NULL;
#endif
    if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
        PY_ERR_TYPE("A is not a square sparse matrix");
    n = SP_NROWS(A);

    if (P) {
        if (!Matrix_Check(P) || MAT_ID(P) != INT) err_int_mtrx("p");
        if (MAT_LGT(P) != n) err_buf_len("p");
        if (!CHOL(check_perm)(P->buffer, n, n, &Common))
            PY_ERR(PyExc_ValueError, "p is not a valid permutation");
    }
    if (uplo != 'U' && uplo != 'L') err_char("uplo", "'L', 'U'");
    if (!(Ac = pack(A, uplo))) return PyErr_NoMemory();
    L = CHOL(analyze_p)(Ac, P ? MAT_BUFI(P): NULL, NULL, 0, &Common);
    CHOL(free_sparse)(&Ac, &Common);

    if (Common.status != CHOLMOD_OK){
        if (Common.status == CHOLMOD_OUT_OF_MEMORY)
            return PyErr_NoMemory();
        else{
            PyErr_SetString(PyExc_ValueError, "symbolic factorization "
                "failed");
            return NULL;
        }
    }
#if PY_MAJOR_VERSION >= 3
    return (PyObject *) PyCapsule_New((void *) L, SP_ID(A)==DOUBLE ?  
        (uplo == 'L' ?  "CHOLMOD FACTOR D L" : "CHOLMOD FACTOR D U") :
        (uplo == 'L' ?  "CHOLMOD FACTOR Z L" : "CHOLMOD FACTOR Z U"),
        (PyCapsule_Destructor) &cvxopt_free_cholmod_factor); 
#else
    return (PyObject *) PyCObject_FromVoidPtrAndDesc((void *) L,
        SP_ID(A)==DOUBLE ?  
        (uplo == 'L' ?  "CHOLMOD FACTOR D L" : "CHOLMOD FACTOR D U") :
        (uplo == 'L' ?  "CHOLMOD FACTOR Z L" : "CHOLMOD FACTOR Z U"),
	cvxopt_free_cholmod_factor);
#endif
}
示例#13
0
static void cvxopt_free_cholmod_factor(void *L, void *descr)
{
    CHOL(free_factor) ((cholmod_factor **) &L, &Common) ;
}
示例#14
0
static void cvxopt_free_cholmod_factor(void *L)
{
   void *Lptr = PyCapsule_GetPointer(L, PyCapsule_GetName(L));   
   CHOL(free_factor) ((cholmod_factor **) &Lptr, &Common);
}
示例#15
0
static void free_matrix(cholmod_sparse *A)
{
    A->x = NULL;
    A->i = NULL;
    CHOL(free_sparse)(&A, &Common);
}
示例#16
0
mlgpStatus_t MLGP_LIKELIHOOD_CPU
(
  FLOAT* nll,
  MATRIX_T X,
  VECTOR_T y,
  INF_T inf,
  MEAN_T mean,
  COV_T cov,
  LIK_T lik,
  mlgpWorkspace_t* workspace,
  mlgpOptions_t options
)
{

  /* Exact inference with Gaussian Likelihood */

  /* This function computes the negative log marginal likelihood (nll)
   * and its derivatives with respect to the mean, covariance and likelihood
   * function hyperparameters.
   * 
   * Arguments:
   * - nll          : Pointer to a FLOAT to store the negative log
   *                  marginal likelihood
   *
   * - X            : MATRIX_T containing the matrix of training inputs.
   *                  Each row represents one input vector. Column major format.
   *
   * - y            : VECTOR_T containing the vector of training targets.
   *
   * - inf          : mlgpInf_t specifying the inference method to be used
   *                  (currently only the exact inference method available).
   *
   * - mean         : mlgpMean_t specifying the mean function and its parameters
   *
   * - cov          : mlgpCov_t specifying the covaraince function and its
   *                  parameters
   *
   * - lik          : mlgpLik_t specifying the likelihood function and its
   *                  parameters (currently only the Gaussian likelihood
   *                  avaialble).
   *
   * - workspace    : mlgpWorkspace_t containing the pointer to pointer for
   *                  the working memory. If the NOWORKSPACE flag is set in
   *                  options.opts, then this function takes care of memory
   *                  allocation entirely. If the CREATEWORKSPACE flag is 
   *                  set, this function only allocates the required working
   *                  memory in workspace->ws[0] (based on the parameters passed
   *                  in) and returns without performing any computation.
   *
   *                  If the SAVE flags is set, then workspace->ws[1] will
   *                  contain a pointer to a N*N + N block of memory containing
   *                  the vector (K^-1)*(y-m) and the Cholesky factor of the 
   *                  covariance matrix K (to use for prediction).
   *                  Note for this workspace->ws will need to have at least two
   *                  pointers worth of memory allocated to it.
   *
   * - options      : mlgpOptions_t specifying the options for the computation.
   *                  Possible options are
   *                  - CREATEWORKSPACE (as described above)
   *                  - NOWORKSPACE (as described above)
   *                  - PACKED uses packed storage for symmetric matrices
   *                  - SAVE (as described above)
   */

  unsigned N, dim;
  unsigned sizeK, memoryNeeded;
  unsigned np_cov, np_mean;

  ptrdiff_t shift;

  MATRIX_T K, dKdTheta1, dKdTheta2;
  VECTOR_T ymm, Kinvy;

  FLOAT sig_n2;

  mlgpOptions_t int_opts;

  N = X.nrows;
  dim = X.ncols;

  sizeK = (options.opts&PACKED) ? (N*(N+1))/2 : N*N;

  memoryNeeded = 3*sizeK + 2*N;

  /* Compute and assign working memory needed */
  if(options.opts&CREATEWORKSPACE || options.opts&NOWORKSPACE){
    
    if(options.opts&SAVE){
      workspace->ws = malloc(2*sizeof(FLOAT*));
      workspace->size = 2;
      workspace->allocated = 0x3u;
    }else{
      workspace->ws = malloc(sizeof(FLOAT*));
      workspace->size = 1;
      workspace->allocated = 0x1u;
    }
  
    workspace->ws[0] = malloc(memoryNeeded*sizeof(FLOAT));

    if(options.opts&SAVE){
      workspace->ws[1] = malloc((N*N+N)*sizeof(FLOAT));
    }

    if(options.opts&CREATEWORKSPACE){
      return mlgpSuccess;
    }
  }

  K         = MLGP_CREATEMATRIXNOMALLOC(N,N);
  dKdTheta1 = MLGP_CREATEMATRIXNOMALLOC(N,N);
  dKdTheta2 = MLGP_CREATEMATRIXNOMALLOC(N,N);

  ymm       = MLGP_CREATEVECTORNOMALLOC(N);
  Kinvy     = MLGP_CREATEVECTORNOMALLOC(N);


  shift = 0;
  K.m         = (FLOAT*)workspace->ws[0]+shift; shift+=sizeK; // N*N - covariance matrix
  dKdTheta1.m = (FLOAT*)workspace->ws[0]+shift; shift+=sizeK; // N*N - covariance derivatives
  dKdTheta2.m = (FLOAT*)workspace->ws[0]+shift; shift+=sizeK; // N*N - covariance derivatives
  ymm.v       = (FLOAT*)workspace->ws[0]+shift; shift+=N;     // N   - y-m
  Kinvy.v     = (FLOAT*)workspace->ws[0]+shift; shift+=N;     // N   - (K^-1)*y
  


  /* ymm contains y */
  MLGP_COPY(N,y.v,1,ymm.v,1);

  /* apply mean function, ymm contains y-m */
  int_opts.opts = _SUBMEAN;
  MLGP_MEAN(ymm,X,mean,ymm,0,int_opts);

  /* copy y-m into Kinvy */
  MLGP_COPY(N,ymm.v,1,Kinvy.v,1);

  /* generate the covariance matrix in K */
  int_opts.opts = _SYMM;
  if(options.opts&PACKED){ int_opts.opts|=_PACKED; }
  MLGP_COV(K,X,X,cov,K,0,int_opts);

  /* cache K in dKdTheta2 for derivatives computation */
  if(options.opts&PACKED){
    MLGP_COPY((N*(N+1))/2,K.m,1,dKdTheta2.m,1);
  }else{
    MLGP_COPY(N*N,K.m,1,dKdTheta2.m,1);
  }

  /* add noise term to the diagonal */
  sig_n2 = exp(2.*lik.params[0]);
  if(options.opts&PACKED){
    for(unsigned i=0;i<N;i++){
      K.m[i+(i*(i+1))/2] += sig_n2;
    }
  }else{
    MLGP_AXPY(N,1.,&sig_n2,0,K.m,N+1);
  }

  /* Cholesky decomposition K = LL^T */
  /* solve K(Kinvy) = y for Kinvy using L */
  if(options.opts&PACKED){
    CHOL_PACKED(K);
    SOLVE_CHOL_PACKED_ONE(K,Kinvy);
  }else{
    CHOL(K);
    SOLVE_CHOL_ONE(K,Kinvy);
  }

  /* first term in nll = 0.5*y'*(K^-1)*y */
  *nll = 0.5*MLGP_DOT(N,ymm.v,1,Kinvy.v,1);


  /* second term in nll = 0.5*log(det(K)) 
   * = 0.5*log(det(LL')) = 0.5*log(det(L)^2) = log(det(L))*/
  if(options.opts&PACKED){
    *nll += LOG_DET_TR_PACKED(K);
  }else{
    *nll += LOG_DET_TR(K);
  }

  /* third term in nll = (N/2)*log(2*pi)  */ 
  *nll += N*HALFLOG2PI;

  if(options.opts&SAVE){
    MLGP_COPY(N,Kinvy.v,1,workspace->ws[1],1);
    MLGP_COPY(N*N,K.m,1,workspace->ws[1]+N,1);
  }

  /* derivatives */
  if(!(options.opts&NODERIVATIVES)){

    /* precompute Q = (K^-1) - Kinvy'*Kinvy (stored in K) */
    if(options.opts&PACKED){
      INV_CHOL_PACKED(K);
      MLGP_SPR('U',N,-1.,Kinvy.v,1,K.m);
    }else{
      INV_CHOL(K);
      MLGP_GEMM('N','N',N,N,1,-1.,Kinvy.v,N,Kinvy.v,1,1.,K.m,N);
    }

    /* get number of covariance function parameters */
    np_cov = MLGP_NPARAMS_COV(cov,dim);

    /* covariance function options flag for derivatives computation */
    int_opts.opts = _SYMM|_DERIVATIVES|_PRECOMPUTE;
    if(options.opts&PACKED){ int_opts.opts|=_PACKED; }

    /* iterate through covariance parameters and compute derivatives for each */
    for(unsigned p_i=0;p_i<np_cov;p_i++){

      MLGP_COV(dKdTheta2,X,X,cov,dKdTheta1,p_i,int_opts);

      if(options.opts&PACKED){
        // elementwise product of Q and dKdTheta1 = trace(Q*dKdTheta1)
        cov.dparams[p_i] = MLGP_DOT((N*(N+1))/2,dKdTheta1.m,1,K.m,1); 

        // subtract duplicates from using the diagonal twice
        for(unsigned i=0;i<N;i++){
          cov.dparams[p_i] -= K.m[i+(i*(i+1))/2]*dKdTheta1.m[i+(i*(i+1))/2]/2;
        }
      }else{
        // elementwise product of Q and dKdTheta1 = trace(Q*dKdTheta1)
        cov.dparams[p_i] = MLGP_DOT(N*N,dKdTheta1.m,1,K.m,1)/2;
      }
    }

    /* get number of mean parameters */
    np_mean = MLGP_NPARAMS_MEAN(mean,dim);

    /* iterate through mean parameters and compute derivatives for each */
    /* using ymm as memory to hold mean derivatives */
    int_opts.opts = _DERIVATIVES;
    for(unsigned p_i=0;p_i<np_mean;p_i++){
      MLGP_MEAN(ymm,X,mean,ymm,p_i,int_opts);
      mean.dparams[p_i] = -MLGP_DOT(N,Kinvy.v,1,ymm.v,1);
    }

    /* derivative wrt gaussian noise parameter = sig_n*tr(Q) */
    if(options.opts&PACKED){
      lik.dparams[0] = 0;
      for(unsigned i=0;i<N;i++){
        lik.dparams[0] += K.m[i+(i*(i+1))/2]*sig_n2;
      }
    }else{
      lik.dparams[0] = MLGP_DOT(N,K.m,N+1,&sig_n2,0);
    }

    if(options.opts&NOWORKSPACE){
      free(workspace->ws[0]);
      workspace->allocated&=(~0x1u);
    }
  }

  return mlgpSuccess;
  
}