Exemplo n.º 1
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject *SCMcolumn
(PyObject *self, PyObject *args)
{
  PyObject *H,*Av,*Ip,*Jp,*V;
  int_t m,n,K;
  int_t i,j,k,l,p,q,r,c;

  if(!PyArg_ParseTuple(args,"OOOOOn",&H,&Av,&V,&Ip,&Jp,&j)) return NULL;

  m = MAT_NCOLS(H);
  n = MAT_NROWS(V);
  K = MAT_NCOLS(V)/2;

  //#pragma omp parallel for shared(m,n,K,Av,Ip,Jp,H,V,j) private(i,l,k,r,c,q,p)
  for (i=j;i<m;i++) {
    p = SP_COL(Av)[i];
    MAT_BUFD(H)[j*m+i] = 0;
    for (l=0;l<SP_COL(Av)[i+1]-p;l++) {
      q = SP_ROW(Av)[p+l];
      r = MAT_BUFI(Ip)[q];
      c = MAT_BUFI(Jp)[q];
      for (k=0;k<K;k++) {
	MAT_BUFD(H)[j*m+i] += SP_VALD(Av)[p+l]*
	  MAT_BUFD(V)[k*n+r]*MAT_BUFD(V)[(K+k)*n+c];
	if (r != c)
	  MAT_BUFD(H)[j*m+i] += SP_VALD(Av)[p+l]*
	    MAT_BUFD(V)[k*n+c]*MAT_BUFD(V)[(K+k)*n+r];
      }
    }
  }

  Py_RETURN_NONE;
}
Exemplo n.º 2
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject *sub2ind
(PyObject *self, PyObject *args)
{
  matrix *Im,*Jm;
  PyObject *siz;
  int_t i;
  int_t m,n;

  if (!PyArg_ParseTuple(args, "OOO", &siz, &Im, &Jm)) return NULL;
  if (!PyArg_ParseTuple(siz, "nn", &m, &n)) return NULL;

  matrix *Ind = Matrix_New(MAT_NROWS(Im),1,INT);
  if (!Ind) return PyErr_NoMemory();

  for (i=0;i< MAT_NROWS(Im) ;i++) {
    // Add data check:
    MAT_BUFI(Ind)[i] = MAT_BUFI(Im)[i] + m*MAT_BUFI(Jm)[i];
  }
  return Py_BuildValue("N", Ind);
}
Exemplo n.º 3
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject *ind2sub
(PyObject *self, PyObject *args)
{
  matrix *Im;
  int_t i;
  int_t n;

  if (!PyArg_ParseTuple(args, "nO", &n, &Im)) return NULL;

  matrix *Il = Matrix_New(MAT_NROWS(Im),1,INT);
  if (!Il) return PyErr_NoMemory();
  matrix *Jl = Matrix_New(MAT_NROWS(Im),1,INT);
  if (!Il) return PyErr_NoMemory();

  for (i=0;i< MAT_NROWS(Im);i++) {
    MAT_BUFI(Il)[i] = MAT_BUFI(Im)[i] % n;
    MAT_BUFI(Jl)[i] = MAT_BUFI(Im)[i] / n;
  }

  return Py_BuildValue("NN", Il, Jl);
}
Exemplo n.º 4
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject *toeplitz
(PyObject *self, PyObject *args, PyObject *kwrds) {

  PyObject *r=NULL, *c=NULL;
  int_t m,n,i,j;
  char *kwlist[] = {"c","r",NULL};

  if (!PyArg_ParseTupleAndKeywords(args,kwrds,"O|O",kwlist,&c,&r)) return NULL;

  if (!Matrix_Check(c))
    return NULL;
  if (r==NULL)
    r = c;
  else if (!Matrix_Check(r))
    return NULL;

  if (MAT_ID(r) != DOUBLE || MAT_ID(c) != DOUBLE)
    return NULL;

  if (MAT_NCOLS(r) > 1 || MAT_NCOLS(c) > 1)
    return NULL;

  m = MAT_NROWS(c);
  n = MAT_NROWS(r);

  // build dense toeplitz matrix, column by column
  matrix *T = Matrix_New(m,n,DOUBLE);
  if (!T) return PyErr_NoMemory();
  for(j=0;j<n;j++) {
    for(i=0;i<(m>j?j:m);i++) {
      MAT_BUFD(T)[j*m+i] = MAT_BUFD(r)[j-i];
    }
    for(i=j;i<m;i++) {
      MAT_BUFD(T)[j*m+i] = MAT_BUFD(c)[i-j];
    }
  }

  return (PyObject*) T;
}
Exemplo n.º 5
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject *scal_diag
(PyObject *self, PyObject *args)
{
  PyObject *Vp,*Id;
  int_t i,n;
  double t = 0.5;

  if(!PyArg_ParseTuple(args,"OO|d",&Vp,&Id,&t)) return NULL;
  n = MAT_NROWS(Id);

  for (i=0;i<n;i++){
    SP_VALD(Vp)[MAT_BUFI(Id)[i]] *= t;
  }

  Py_RETURN_NONE;
}
Exemplo n.º 6
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject *SCMcolumn2
(PyObject *self, PyObject *args)
{
  PyObject *H,*Av,*Ip,*Jp,*V,*Kl;
  int_t m,n;
  int_t i,j,k,p,q,r,c,r1,c1,pj,pi;
  double alpha,beta;

  if(!PyArg_ParseTuple(args,"OOOOOOn",&H,&Av,&V,&Ip,&Jp,&Kl,&j)) return NULL;

  m = MAT_NCOLS(H);
  n = MAT_NROWS(V);

  for (i=j;i<m;i++) MAT_BUFD(H)[j*m+i] = 0;

  //#pragma omp parallel for shared(m,n,K,Av,Ip,Jp,H,V,j) private(i,l,k,r,c,q,p)
  pj = SP_COL(Av)[j];
  for (p=0;p<SP_COL(Av)[j+1]-pj;p++) {
    alpha = SP_VALD(Av)[pj+p];
    k = SP_ROW(Av)[pj+p];
    r = MAT_BUFI(Ip)[k];
    c = MAT_BUFI(Jp)[k];
    if (r!=c) alpha*=2;
    // look up columns in V
    r = MAT_BUFI(Kl)[r];
    c = MAT_BUFI(Kl)[c];

    for(i=j;i<m;i++) {
      pi = SP_COL(Av)[i];
      for (q=0;q<SP_COL(Av)[i+1]-pi;q++) {
	beta = SP_VALD(Av)[pi+q];
	k = SP_ROW(Av)[pi+q];
	r1 = MAT_BUFI(Ip)[k];
	c1 = MAT_BUFI(Jp)[k];

	MAT_BUFD(H)[j*m+i] += alpha*beta*MAT_BUFD(V)[n*r+r1]*MAT_BUFD(V)[n*c+c1];
	if (r1!=c1)
	  MAT_BUFD(H)[j*m+i] += alpha*beta*MAT_BUFD(V)[n*r+c1]*MAT_BUFD(V)[n*c+r1];
      }
    }
  }

  Py_RETURN_NONE;
}
Exemplo n.º 7
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject *matperm
(PyObject *self, PyObject *args)
{
  PyObject *nzc;
  matrix *pm;
  int_t Ns,Nd,m,i,Nmax;

  if (!PyArg_ParseTuple(args,"On",&nzc,&Nmax)) return NULL;
  m = MAT_NROWS(nzc);
  pm = Matrix_New(m,1,INT);
  if (!pm) return PyErr_NoMemory();

  // Check Nmax
  if (Nmax<0) Nmax = 0;

  Ns = 0; Nd = 0;
  for (i=0;i<m;i++){
    if(MAT_BUFI(nzc)[i] > Nmax)
      MAT_BUFI(pm)[Nd++] = i;
    else
      MAT_BUFI(pm)[m-1-Ns++] = i;
  }
  return Py_BuildValue("Nn",pm,Ns);
}
Exemplo n.º 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("");
}
Exemplo n.º 9
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("");
}
Exemplo n.º 10
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject *robustLS_to_sdp
(PyObject *self, PyObject *args, PyObject *kwrds) {

  PyObject *Alist,*bt, *Ai;
  spmatrix *A,*b;
  int_t m,n,mp,np,pt,i,j,k,N,nnz=0,ri=0;
  char *kwlist[] = {"Alist","bt",NULL};

  if(!PyArg_ParseTupleAndKeywords(args,kwrds,"OO",kwlist,&Alist,&bt)) return NULL;

  if(!PyList_Check(Alist)) {
    PyErr_SetString(PyExc_TypeError,"Alist must be a list of matrices");
    return NULL;
  }

  // get pt = p + 1
  pt = PyList_Size(Alist);

  // get size of bt
  if(Matrix_Check(bt)){
    m = MAT_NROWS(bt);
    np = MAT_NCOLS(bt);
  }
  else if (SpMatrix_Check(bt)){
    m = SP_NROWS(bt);
    np = SP_NCOLS(bt);
  }
  else {
    PyErr_SetString(PyExc_TypeError,"b must be a vector");
    return NULL;
  }
  if (np!=1) {
    PyErr_SetString(PyExc_TypeError,"b must be a vector");
    return NULL;
  }

  // get n and check A0
  if (!(Ai = PyList_GetItem(Alist,0))) return NULL;
  if (Matrix_Check(Ai)) {
    n = MAT_NCOLS(Ai);
    nnz += m*n;
  }
  else if (SpMatrix_Check(Ai)) {
    n = SP_NCOLS(Ai);
    nnz += SP_NNZ(Ai);
  }
  else {
    PyErr_SetString(PyExc_TypeError,"only spmatrix and matrix types allowed");
    return NULL;
  }

  // check remaining matrices in Alist
  for (i=1;i<pt;i++) {
    if (!(Ai = PyList_GetItem(Alist,i))) return NULL;
    if (Matrix_Check(Ai)) {
      mp = MAT_NROWS(Ai);
      np = MAT_NCOLS(Ai);
      nnz += m*n;
    }
    else if (SpMatrix_Check(Ai)) {
      mp = SP_NROWS(Ai);
      np = SP_NCOLS(Ai);
      nnz += SP_NNZ(Ai);
    }
    else {
      PyErr_SetString(PyExc_TypeError,"only spmatrix and matrix types allowed");
      return NULL;
    }
    if (!(mp==m && np==n)){
      PyErr_SetString(PyExc_TypeError,"matrices in Alist must have same size");
      return NULL;
    }
  }
  nnz += 2*m + pt;

  // generate b
  b = SpMatrix_New(n+2,1,2,DOUBLE);
  if (!b) return PyErr_NoMemory();
  SP_COL(b)[0] = 0;
  SP_VALD(b)[0] = -1;
  SP_ROW(b)[0] = 0;
  SP_VALD(b)[1] = -1;
  SP_ROW(b)[1] = 1;
  SP_COL(b)[1] = 2;

  // generate A
  N = m+pt;
  A = SpMatrix_New(N*N,n+3,nnz,DOUBLE);
  if (!A) return PyErr_NoMemory();

  // build A0
  SP_COL(A)[0] = ri;
  for(i=0;i<m;i++){
    if(SpMatrix_Check(bt)){
      SP_VALD(A)[ri] = -SP_VALD(bt)[i];
      SP_ROW(A)[ri++] = pt+i;
    }
    else{
      SP_VALD(A)[ri] = -MAT_BUFD(bt)[i];
      SP_ROW(A)[ri++] = pt+i;
    }
  }
  for(i=0;i<m;i++) {
    SP_VALD(A)[ri] = 1;
    SP_ROW(A)[ri++] = (N+1)*pt + i*N+i;
  }

  // build A1
  SP_COL(A)[1] = ri;
  for(i=0;i<pt-1;i++){
    SP_VALD(A)[ri] = -1;
    SP_ROW(A)[ri++] = N+1 + i*N+i;
  }

  // build A2
  SP_COL(A)[2] = ri;
  SP_VALD(A)[ri] = -1;
  SP_ROW(A)[ri++] = 0;
  SP_COL(A)[3] = ri;

  // build A3,...
  for(j=0;j<n;j++){
    // generate col. i
    for(i=0;i<pt;i++){
      Ai = PyList_GetItem(Alist,i);
      if(SpMatrix_Check(Ai)) {
	nnz = SP_COL(Ai)[j+1]-SP_COL(Ai)[j];
	for(k=0;k<nnz;k++) {
	  SP_VALD(A)[ri] = -SP_VALD(Ai)[SP_COL(Ai)[j]+k];
	  SP_ROW(A)[ri++] = pt+i*N + SP_ROW(Ai)[SP_COL(Ai)[j]+k];
	}
      }
      else {
	for (k=0;k<m;k++) {
	  SP_VALD(A)[ri] = -MAT_BUFD(Ai)[j*m+k];
	  SP_ROW(A)[ri++] = pt+i*N + k;
	}
      }
    }
    SP_COL(A)[j+4] = ri;
  }

  return Py_BuildValue("NN",A,b);
}
Exemplo n.º 11
0
Arquivo: misc.c Projeto: cvxopt/smcp
static PyObject* sdpa_write
(PyObject *self, PyObject *args, PyObject *kwrds)
{
  int i,Il,Jl,Bl,Ml;
  int_t n;
  spmatrix *A;
  matrix *b,*bstruct;
  PyObject *f;
  PyObject *neg = Py_False;
  char *kwlist[] = {"f","A","b","bstruct","neg",NULL};
  const char* fname;
  double v;

  if (!PyArg_ParseTupleAndKeywords(args,kwrds, "OOOO|O", kwlist, &f, &A, &b, &bstruct,&neg)) return NULL;
  #if PY_MAJOR_VERSION >= 3
  if (PyUnicode_Check(f)) fname = PyUnicode_AsUTF8AndSize(f,NULL);
  #elif PY_MAJOR_VERSION == 2
  if (PyString_Check(f)) fname = PyString_AsString(f);
  #endif
  FILE *fp = fopen(fname,"r");
  if (!fp) {
    Py_DECREF(f);
    return NULL;
  }

  fprintf(fp,"* sparse SDPA data file (created by SMCP)\n");
  fprintf(fp,"%i = m\n",(int) MAT_NROWS(b));
  fprintf(fp,"%i = nBlocks\n", (int) MAT_NROWS(bstruct));
  // compute n and write blockstruct
  n = 0;
  for (i=0;i<MAT_NROWS(bstruct);i++) {
    fprintf(fp,"%i ", (int) MAT_BUFI(bstruct)[i]);
    n += (int_t) labs(MAT_BUFI(bstruct)[i]);
  }
  fprintf(fp,"\n");

  // write vector b
  if (neg == Py_True) {
    for (i=0;i<MAT_NROWS(b);i++)
      fprintf(fp,"%.12g ",-MAT_BUFD(b)[i]);
  }
  else {
    for (i=0;i<MAT_NROWS(b);i++)
      fprintf(fp,"%.12g ",MAT_BUFD(b)[i]);
  }
  fprintf(fp,"\n");

  // Write data matrices A0,A1,A2,...,Am
  for (Ml=0;Ml<=MAT_NROWS(b);Ml++) {
    for (i=0;i<SP_COL(A)[Ml+1]-SP_COL(A)[Ml];i++){

      Jl = 1 + SP_ROW(A)[SP_COL(A)[Ml]+i] / n;
      Il = 1 + SP_ROW(A)[SP_COL(A)[Ml]+i] % n;

      // Skip if element is in strict upper triangle
      if (Jl > Il)
	PyErr_Warn(PyExc_Warning,"Ignored strictly upper triangular element.");

      Bl = 1;
      while ((Il > labs(MAT_BUFI(bstruct)[Bl-1])) && (Jl > labs(MAT_BUFI(bstruct)[Bl-1]))) {
	Il -= (int_t) labs(MAT_BUFI(bstruct)[Bl-1]);
	Jl -= (int_t) labs(MAT_BUFI(bstruct)[Bl-1]);
	Bl += 1;
      }
      /* Error check */
      if ((Il > labs(MAT_BUFI(bstruct)[Bl-1])) || (Jl > labs(MAT_BUFI(bstruct)[Bl-1])))
	printf("Error: Matrix contains elements outside blocks!\n");

      // print upper triangle entries:
      //   <matno> <blkno> <i> <j> <entry>
      v = SP_VALD(A)[SP_COL(A)[Ml]+i];
      if ( v != 0.0) {
	if (neg == Py_True)
	  fprintf(fp,"%i %i %i %i %.12g\n",
		  (int) Ml,(int) Bl,(int) Jl,(int) Il, -v);
	else
	  fprintf(fp,"%i %i %i %i %.12g\n",
		  (int) Ml,(int) Bl,(int) Jl,(int) Il, v);
      }
    }
  }

  fclose(fp);
  Py_DECREF(f);
  Py_RETURN_NONE;
}
Exemplo n.º 12
0
Arquivo: glpk.c Projeto: ugonj/cvxopt
static PyObject *integer(PyObject *self, PyObject *args,
    PyObject *kwrds)
{
    matrix *c, *h, *b=NULL, *x=NULL;
    PyObject *G, *A=NULL, *IntSet=NULL, *BinSet = NULL;
    PyObject *t=NULL;
    pyiocp *iocpParm = NULL;;
    glp_iocp *options = NULL;
    glp_prob *lp;
    int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL;
    double *a=NULL, val;
    char *kwlist[] = {"c", "G", "h", "A", "b", "I", "B","iocp", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OOOOO!", kwlist, &c,
	    &G, &h, &A, &b, &IntSet, &BinSet,iocp_t,&iocpParm)) return NULL;

    if(!iocpParm) 
    {
      iocpParm = (pyiocp*)malloc(sizeof(*iocpParm));
      glp_init_iocp(&(iocpParm->obj));
    }
    if(iocpParm) 
    {
      Py_INCREF(iocpParm);
      options = &iocpParm->obj;
      options->presolve = 1;
    }

    if ((Matrix_Check(G) && MAT_ID(G) != DOUBLE) ||
        (SpMatrix_Check(G) && SP_ID(G) != DOUBLE) ||
        (!Matrix_Check(G) && !SpMatrix_Check(G))){
        PyErr_SetString(PyExc_TypeError, "G must be a 'd' matrix");
        return NULL;
    }
    if ((m = Matrix_Check(G) ? MAT_NROWS(G) : SP_NROWS(G)) <= 0)
        err_p_int("m");
    if ((n = Matrix_Check(G) ? MAT_NCOLS(G) : SP_NCOLS(G)) <= 0)
        err_p_int("n");

    if (!Matrix_Check(h) || h->id != DOUBLE) err_dbl_mtrx("h");
    if (h->nrows != m || h->ncols != 1){
        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
        return NULL;
    }

    if (A){
        if ((Matrix_Check(A) && MAT_ID(A) != DOUBLE) ||
            (SpMatrix_Check(A) && SP_ID(A) != DOUBLE) ||
            (!Matrix_Check(A) && !SpMatrix_Check(A))){
                PyErr_SetString(PyExc_ValueError, "A must be a dense "
                    "'d' matrix or a general sparse matrix");
                return NULL;
	}
        if ((p = Matrix_Check(A) ? MAT_NROWS(A) : SP_NROWS(A)) < 0)
            err_p_int("p");
        if ((Matrix_Check(A) ? MAT_NCOLS(A) : SP_NCOLS(A)) != n){
            PyErr_SetString(PyExc_ValueError, "incompatible "
                "dimensions");
            return NULL;
	}
    }
    else p = 0;

    if (b && (!Matrix_Check(b) || b->id != DOUBLE)) err_dbl_mtrx("b");
    if ((b && (b->nrows != p || b->ncols != 1)) || (!b && p !=0 )){
        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
        return NULL;
    }

    if ((IntSet) && (!PyAnySet_Check(IntSet)))
      PY_ERR_TYPE("invalid integer index set");

    if ((BinSet) && (!PyAnySet_Check(BinSet)))
      PY_ERR_TYPE("invalid binary index set");

    lp = glp_create_prob();
    glp_add_rows(lp, m+p);
    glp_add_cols(lp, n);

    for (i=0; i<n; i++){
        glp_set_obj_coef(lp, i+1, MAT_BUFD(c)[i]);
        glp_set_col_bnds(lp, i+1, GLP_FR, 0.0, 0.0);
    }
    for (i=0; i<m; i++)
        glp_set_row_bnds(lp, i+1, GLP_UP, 0.0, MAT_BUFD(h)[i]);
    for (i=0; i<p; i++)
        glp_set_row_bnds(lp, i+m+1, GLP_FX, MAT_BUFD(b)[i],
            MAT_BUFD(b)[i]);

    nnzmax = (SpMatrix_Check(G) ? SP_NNZ(G) : m*n ) +
        ((A && SpMatrix_Check(A)) ? SP_NNZ(A) : p*n);
    a = (double *) calloc(nnzmax+1, sizeof(double));
    rn = (int *) calloc(nnzmax+1, sizeof(int));
    cn = (int *) calloc(nnzmax+1, sizeof(int));
    if (!a || !rn || !cn){
        free(a);  free(rn);  free(cn);  glp_delete_prob(lp);
        return PyErr_NoMemory();
    }

    nnz = 0;
    if (SpMatrix_Check(G)) {
        for (j=0; j<n; j++) for (k=SP_COL(G)[j]; k<SP_COL(G)[j+1]; k++)
            if ((val = SP_VALD(G)[k]) != 0.0){
                a[1+nnz] = val;
                rn[1+nnz] = SP_ROW(G)[k]+1;
                cn[1+nnz] = j+1;
                nnz++;
            }
    }
    else for (j=0; j<n; j++) for (i=0; i<m; i++)
        if ((val = MAT_BUFD(G)[i+j*m]) != 0.0){
            a[1+nnz] = val;
            rn[1+nnz] = i+1;
            cn[1+nnz] = j+1;
            nnz++;
        }

    if (A && SpMatrix_Check(A)){
        for (j=0; j<n; j++) for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1]; k++)
            if ((val = SP_VALD(A)[k]) != 0.0){
                a[1+nnz] = val;
                rn[1+nnz] = m+SP_ROW(A)[k]+1;
                cn[1+nnz] = j+1;
                nnz++;
            }
    }
    else for (j=0; j<n; j++) for (i=0; i<p; i++)
        if ((val = MAT_BUFD(A)[i+j*p]) != 0.0){
            a[1+nnz] = val;
            rn[1+nnz] = m+i+1;
            cn[1+nnz] = j+1;
            nnz++;
        }

    glp_load_matrix(lp, nnz, rn, cn, a);
    free(rn);  free(cn);  free(a);

    if (!(t = PyTuple_New(2))) {
        glp_delete_prob(lp);
        return PyErr_NoMemory();
    }

    if (IntSet) {
      PyObject *iter = PySequence_Fast(IntSet, "Critical error: not sequence");

      for (i=0; i<PySet_GET_SIZE(IntSet); i++) {

	PyObject *tmp = PySequence_Fast_GET_ITEM(iter, i);
#if PY_MAJOR_VERSION >= 3
	if (!PyLong_Check(tmp)) {
#else
	if (!PyInt_Check(tmp)) {
#endif
	  glp_delete_prob(lp);
	  Py_DECREF(iter);
	  PY_ERR_TYPE("non-integer element in I");
	}
#if PY_MAJOR_VERSION >= 3
	int k = PyLong_AS_LONG(tmp);
#else
	int k = PyInt_AS_LONG(tmp);
#endif
	if ((k < 0) || (k >= n)) {
	  glp_delete_prob(lp);
	  Py_DECREF(iter);
	  PY_ERR(PyExc_IndexError, "index element out of range in I");
	}
	glp_set_col_kind(lp, k+1, GLP_IV);
      }

      Py_DECREF(iter);
    }

    if (BinSet) {
      PyObject *iter = PySequence_Fast(BinSet, "Critical error: not sequence");

      for (i=0; i<PySet_GET_SIZE(BinSet); i++) {

	PyObject *tmp = PySequence_Fast_GET_ITEM(iter, i);
#if PY_MAJOR_VERSION >= 3
	if (!PyLong_Check(tmp)) {
#else
	if (!PyInt_Check(tmp)) {
#endif
	  glp_delete_prob(lp);
	  Py_DECREF(iter);
	  PY_ERR_TYPE("non-binary element in I");
	}
#if PY_MAJOR_VERSION >= 3
	int k = PyLong_AS_LONG(tmp);
#else
	int k = PyInt_AS_LONG(tmp);
#endif
	if ((k < 0) || (k >= n)) {
	  glp_delete_prob(lp);
	  Py_DECREF(iter);
	  PY_ERR(PyExc_IndexError, "index element out of range in B");
	}
	glp_set_col_kind(lp, k+1, GLP_BV);
      }

      Py_DECREF(iter);

    }


      switch (glp_intopt(lp,options)){

          case 0:

              x = (matrix *) Matrix_New(n,1,DOUBLE);
              if (!x) {
                  Py_XDECREF(iocpParm);
                  Py_XDECREF(t);
                  glp_delete_prob(lp);
                  return PyErr_NoMemory();
              }
              set_output_string(t,"optimal");
              set_output_string(t,"optimal");

              for (i=0; i<n; i++)
                  MAT_BUFD(x)[i] = glp_mip_col_val(lp, i+1);
              PyTuple_SET_ITEM(t, 1, (PyObject *) x);

              Py_XDECREF(iocpParm);
              glp_delete_prob(lp);
              return (PyObject *) t;

          case GLP_ETMLIM:

              x = (matrix *) Matrix_New(n,1,DOUBLE);
              if (!x) {
                  Py_XDECREF(t);
                  Py_XDECREF(iocpParm);
                  glp_delete_prob(lp);
                  return PyErr_NoMemory();
              }
              set_output_string(t,"time limit exceeded");

              for (i=0; i<n; i++)
                  MAT_BUFD(x)[i] = glp_mip_col_val(lp, i+1);
              PyTuple_SET_ITEM(t, 1, (PyObject *) x);

              Py_XDECREF(iocpParm);
              glp_delete_prob(lp);
              return (PyObject *) t;


          case GLP_EBOUND:
              set_output_string(t,"incorrect bounds");
              break;
          case GLP_EFAIL:
              set_output_string(t,"invalid MIP formulation");
              break;

          case GLP_ENOPFS:
              set_output_string(t,"primal infeasible");
              break;

          case GLP_ENODFS:
              set_output_string(t,"dual infeasible");
              break;

          case GLP_EMIPGAP:
              set_output_string(t,"Relative mip gap tolerance reached");
              break;

              /*case LPX_E_ITLIM:

                set_output_string(t,"maxiters exceeded");
                break;*/

              /*case LPX_E_SING:

                set_output_string(t,"singular or ill-conditioned basis");
                break;*/


          default:

              set_output_string(t,"unknown");
      }

      Py_XDECREF(iocpParm);
    glp_delete_prob(lp);

    PyTuple_SET_ITEM(t, 1, Py_BuildValue(""));
    return (PyObject *) t;
}


static PyMethodDef glpk_functions[] = {
    {"lp", (PyCFunction) simplex, METH_VARARGS|METH_KEYWORDS,
        doc_simplex},
    {"ilp", (PyCFunction) integer, METH_VARARGS|METH_KEYWORDS,
        doc_integer},
    {NULL}  /* Sentinel */
};

#if PY_MAJOR_VERSION >= 3

static PyModuleDef glpk_module_def = {
    PyModuleDef_HEAD_INIT,
    "glpk",
    glpk__doc__,
    -1,
    glpk_functions,
    NULL, NULL, NULL, NULL
};

void addglpkConstants (void)
{
  PyModule_AddIntMacro(glpk_module, GLP_ON);
  PyModule_AddIntMacro(glpk_module,GLP_OFF);

  /* reason codes: */
  PyModule_AddIntMacro(glpk_module,GLP_IROWGEN);
  PyModule_AddIntMacro(glpk_module,GLP_IBINGO);
  PyModule_AddIntMacro(glpk_module,GLP_IHEUR);
  PyModule_AddIntMacro(glpk_module,GLP_ICUTGEN);
  PyModule_AddIntMacro(glpk_module,GLP_IBRANCH);
  PyModule_AddIntMacro(glpk_module,GLP_ISELECT);
  PyModule_AddIntMacro(glpk_module,GLP_IPREPRO);

  /* branch selection indicator: */
  PyModule_AddIntMacro(glpk_module,GLP_NO_BRNCH);
  PyModule_AddIntMacro(glpk_module,GLP_DN_BRNCH);
  PyModule_AddIntMacro(glpk_module,GLP_UP_BRNCH);

  /* return codes: */
  PyModule_AddIntMacro(glpk_module,GLP_EBADB);
  PyModule_AddIntMacro(glpk_module,GLP_ESING);
  PyModule_AddIntMacro(glpk_module,GLP_ECOND);
  PyModule_AddIntMacro(glpk_module,GLP_EBOUND);
  PyModule_AddIntMacro(glpk_module,GLP_EFAIL);
  PyModule_AddIntMacro(glpk_module,GLP_EOBJLL);
  PyModule_AddIntMacro(glpk_module,GLP_EOBJUL);
  PyModule_AddIntMacro(glpk_module,GLP_EITLIM);
  PyModule_AddIntMacro(glpk_module,GLP_ETMLIM);
  PyModule_AddIntMacro(glpk_module,GLP_ENOPFS);
  PyModule_AddIntMacro(glpk_module,GLP_ENODFS);
  PyModule_AddIntMacro(glpk_module,GLP_EROOT);
  PyModule_AddIntMacro(glpk_module,GLP_ESTOP);
  PyModule_AddIntMacro(glpk_module,GLP_EMIPGAP);
  PyModule_AddIntMacro(glpk_module,GLP_ENOFEAS);
  PyModule_AddIntMacro(glpk_module,GLP_ENOCVG);
  PyModule_AddIntMacro(glpk_module,GLP_EINSTAB);
  PyModule_AddIntMacro(glpk_module,GLP_EDATA);
  PyModule_AddIntMacro(glpk_module,GLP_ERANGE);

  /* condition indicator: */
  PyModule_AddIntMacro(glpk_module,GLP_KKT_PE);
  PyModule_AddIntMacro(glpk_module,GLP_KKT_PB);
  PyModule_AddIntMacro(glpk_module,GLP_KKT_DE);
  PyModule_AddIntMacro(glpk_module,GLP_KKT_DB);
  PyModule_AddIntMacro(glpk_module,GLP_KKT_CS);

  /* MPS file format: */
  PyModule_AddIntMacro(glpk_module,GLP_MPS_DECK);
  PyModule_AddIntMacro(glpk_module,GLP_MPS_FILE);

  /* simplex method control parameters */
  /* message level: */
  PyModule_AddIntMacro(glpk_module,GLP_MSG_OFF);
  PyModule_AddIntMacro(glpk_module,GLP_MSG_ERR);
  PyModule_AddIntMacro(glpk_module,GLP_MSG_ON);
  PyModule_AddIntMacro(glpk_module,GLP_MSG_ALL);
  PyModule_AddIntMacro(glpk_module,GLP_MSG_DBG);
  /* simplex method option: */
  PyModule_AddIntMacro(glpk_module,GLP_PRIMAL);
  PyModule_AddIntMacro(glpk_module,GLP_DUALP);
  PyModule_AddIntMacro(glpk_module,GLP_DUAL);
  /* pricing technique: */
  PyModule_AddIntMacro(glpk_module,GLP_PT_STD);
  PyModule_AddIntMacro(glpk_module,GLP_PT_PSE);
  /* ratio test technique: */
  PyModule_AddIntMacro(glpk_module,GLP_RT_STD);
  PyModule_AddIntMacro(glpk_module,GLP_RT_HAR);

  /* interior-point solver control parameters */
  /* ordering algorithm: */
  PyModule_AddIntMacro(glpk_module,GLP_ORD_NONE);
  PyModule_AddIntMacro(glpk_module,GLP_ORD_QMD);
  PyModule_AddIntMacro(glpk_module,GLP_ORD_AMD);
  PyModule_AddIntMacro(glpk_module,GLP_ORD_SYMAMD);
}

PyMODINIT_FUNC PyInit_glpk(void)
{
  if (!(glpk_module = PyModule_Create(&glpk_module_def))) return NULL;
  if (PyType_Ready(&iocp_t) < 0 || (PyType_Ready(&smcp_t) < 0)) return NULL;
  /*  Adding macros */
  addglpkConstants();
  /* Adding  option lists as objects */
  Py_INCREF(&smcp_t);
  PyModule_AddObject(glpk_module,"smcp",(PyObject*)&smcp_t);
  Py_INCREF(&iocp_t);
  PyModule_AddObject(glpk_module,"iocp",(PyObject*)&iocp_t);
  if (import_cvxopt() < 0) return NULL;
  return glpk_module;
}

#else

PyMODINIT_FUNC initglpk(void)
{
    glpk_module = Py_InitModule3("cvxopt.glpk", glpk_functions, 
            glpk__doc__);
    if (PyType_Ready(&iocp_t) < 0 || (PyType_Ready(&smcp_t) < 0)) return NULL;
    addglpkConstants();
    Py_INCREF(&smcp_t);
    PyModule_AddObject(glpk_module,"smcp",(PyObject*)&smcp_t);
    Py_INCREF(&iocp_t);
    PyModule_AddObject(glpk_module,"iocp",(PyObject*)&iocp_t);
    if (import_cvxopt() < 0) return;
}
Exemplo n.º 13
0
Arquivo: glpk.c Projeto: ugonj/cvxopt
static PyObject *simplex(PyObject *self, PyObject *args,
    PyObject *kwrds)
{
    matrix *c, *h, *b=NULL, *x=NULL, *z=NULL, *y=NULL;
    PyObject *G, *A=NULL, *t=NULL;
    glp_prob *lp;
    glp_smcp *options = NULL;
    pysmcp *smcpParm = NULL;
    int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL;
    double *a=NULL, val;
    char *kwlist[] = {"c", "G", "h", "A", "b","options", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OOO!", kwlist, &c,
        &G, &h, &A, &b,&smcp_t,&smcpParm)) return NULL;

    if ((Matrix_Check(G) && MAT_ID(G) != DOUBLE) ||
        (SpMatrix_Check(G) && SP_ID(G) != DOUBLE) ||
        (!Matrix_Check(G) && !SpMatrix_Check(G))){
        PyErr_SetString(PyExc_TypeError, "G must be a 'd' matrix");
        return NULL;
    }
    if ((m = Matrix_Check(G) ? MAT_NROWS(G) : SP_NROWS(G)) <= 0)
        err_p_int("m");
    if ((n = Matrix_Check(G) ? MAT_NCOLS(G) : SP_NCOLS(G)) <= 0)
        err_p_int("n");

    if (!Matrix_Check(h) || h->id != DOUBLE) err_dbl_mtrx("h");
    if (h->nrows != m || h->ncols != 1){
        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
        return NULL;
    }

    if (A){
        if ((Matrix_Check(A) && MAT_ID(A) != DOUBLE) ||
            (SpMatrix_Check(A) && SP_ID(A) != DOUBLE) ||
            (!Matrix_Check(A) && !SpMatrix_Check(A))){
                PyErr_SetString(PyExc_ValueError, "A must be a dense "
                    "'d' matrix or a general sparse matrix");
                return NULL;
	}
        if ((p = Matrix_Check(A) ? MAT_NROWS(A) : SP_NROWS(A)) < 0)
            err_p_int("p");
        if ((Matrix_Check(A) ? MAT_NCOLS(A) : SP_NCOLS(A)) != n){
            PyErr_SetString(PyExc_ValueError, "incompatible "
                "dimensions");
            return NULL;
	}
    }
    else p = 0;

    if (b && (!Matrix_Check(b) || b->id != DOUBLE)) err_dbl_mtrx("b");
    if ((b && (b->nrows != p || b->ncols != 1)) || (!b && p !=0 )){
        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
        return NULL;
    }
    if(!smcpParm) 
    {
      smcpParm = (pysmcp*)malloc(sizeof(*smcpParm));
      glp_init_smcp(&(smcpParm->obj));
    }
    if(smcpParm) 
    {
      Py_INCREF(smcpParm);
      options = &smcpParm->obj;
      options->presolve = 1;
    }

    lp = glp_create_prob();
    glp_add_rows(lp, m+p);
    glp_add_cols(lp, n);

    for (i=0; i<n; i++){
        glp_set_obj_coef(lp, i+1, MAT_BUFD(c)[i]);
        glp_set_col_bnds(lp, i+1, GLP_FR, 0.0, 0.0);
    }
    for (i=0; i<m; i++)
        glp_set_row_bnds(lp, i+1, GLP_UP, 0.0, MAT_BUFD(h)[i]);
    for (i=0; i<p; i++)
        glp_set_row_bnds(lp, i+m+1, GLP_FX, MAT_BUFD(b)[i],
            MAT_BUFD(b)[i]);

    nnzmax = (SpMatrix_Check(G) ? SP_NNZ(G) : m*n ) +
        ((A && SpMatrix_Check(A)) ? SP_NNZ(A) : p*n);
    a = (double *) calloc(nnzmax+1, sizeof(double));
    rn = (int *) calloc(nnzmax+1, sizeof(int));
    cn = (int *) calloc(nnzmax+1, sizeof(int));
    if (!a || !rn || !cn){
        free(a);  free(rn);  free(cn);  glp_delete_prob(lp);
        return PyErr_NoMemory();
    }

    nnz = 0;
    if (SpMatrix_Check(G)) {
        for (j=0; j<n; j++) for (k=SP_COL(G)[j]; k<SP_COL(G)[j+1]; k++)
            if ((val = SP_VALD(G)[k]) != 0.0){
                a[1+nnz] = val;
                rn[1+nnz] = SP_ROW(G)[k]+1;
                cn[1+nnz] = j+1;
                nnz++;
            }
    }
    else for (j=0; j<n; j++) for (i=0; i<m; i++)
        if ((val = MAT_BUFD(G)[i+j*m]) != 0.0){
            a[1+nnz] = val;
            rn[1+nnz] = i+1;
            cn[1+nnz] = j+1;
            nnz++;
        }

    if (A && SpMatrix_Check(A)){
        for (j=0; j<n; j++) for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1]; k++)
            if ((val = SP_VALD(A)[k]) != 0.0){
                a[1+nnz] = val;
                rn[1+nnz] = m+SP_ROW(A)[k]+1;
                cn[1+nnz] = j+1;
                nnz++;
            }
    }
    else for (j=0; j<n; j++) for (i=0; i<p; i++)
        if ((val = MAT_BUFD(A)[i+j*p]) != 0.0){
            a[1+nnz] = val;
            rn[1+nnz] = m+i+1;
            cn[1+nnz] = j+1;
            nnz++;
        }

    glp_load_matrix(lp, nnz, rn, cn, a);
    free(rn);  free(cn);  free(a);

    if (!(t = PyTuple_New(A ? 4 : 3))){
        glp_delete_prob(lp);
        return PyErr_NoMemory();
    }


    switch (glp_simplex(lp,options)){

        case 0:

            x = (matrix *) Matrix_New(n,1,DOUBLE);
            z = (matrix *) Matrix_New(m,1,DOUBLE);
            if (A) y = (matrix *) Matrix_New(p,1,DOUBLE);
            if (!x || !z || (A && !y)){
                Py_XDECREF(x);
                Py_XDECREF(z);
                Py_XDECREF(y);
                Py_XDECREF(t);
                Py_XDECREF(smcpParm);
                glp_delete_prob(lp);
                return PyErr_NoMemory();
            }

            set_output_string(t,"optimal");

            for (i=0; i<n; i++)
                MAT_BUFD(x)[i] = glp_get_col_prim(lp, i+1);
            PyTuple_SET_ITEM(t, 1, (PyObject *) x);

            for (i=0; i<m; i++)
                MAT_BUFD(z)[i] = -glp_get_row_dual(lp, i+1);
            PyTuple_SET_ITEM(t, 2, (PyObject *) z);

            if (A){
                for (i=0; i<p; i++)
                    MAT_BUFD(y)[i] = -glp_get_row_dual(lp, m+i+1);
                PyTuple_SET_ITEM(t, 3, (PyObject *) y);
            }

            Py_XDECREF(smcpParm);
            glp_delete_prob(lp);
            return (PyObject *) t;
        case GLP_EBADB:
            set_output_string(t,"incorrect initial basis");
            break;
        case GLP_ESING:
            set_output_string(t,"singular initial basis matrix");
            break;
        case GLP_ECOND:
            set_output_string(t,"ill-conditioned initial basis matrix");
            break;
        case GLP_EBOUND:
            set_output_string(t,"incorrect bounds");
            break;
        case GLP_EFAIL:
            set_output_string(t,"solver failure");
            break;
        case GLP_EOBJLL:
            set_output_string(t,"objective function reached lower limit");
            break;
        case GLP_EOBJUL:
            set_output_string(t,"objective function reached upper limit");
            break;
        case GLP_EITLIM:
            set_output_string(t,"iteration limit exceeded");
            break;
        case GLP_ETMLIM:
            set_output_string(t,"time limit exceeded");
            break;
        case GLP_ENOPFS:
            set_output_string(t,"primal infeasible");
            break;
        case GLP_ENODFS:
            set_output_string(t,"dual infeasible");
            break;
        default:
            set_output_string(t,"unknown");
            break;
    }

    Py_XDECREF(smcpParm);
    glp_delete_prob(lp);

    PyTuple_SET_ITEM(t, 1, Py_BuildValue(""));
    PyTuple_SET_ITEM(t, 2, Py_BuildValue(""));
    if (A) PyTuple_SET_ITEM(t, 3, Py_BuildValue(""));

    return (PyObject *) t;
}