Example #1
0
File: gsl.c Project: MGKhKhD/cvxopt
static PyObject *
uniform(PyObject *self, PyObject *args, PyObject *kwrds)
{
  matrix *obj;
  int i, nrows, ncols = 1;
  double a = 0, b = 1;

  char *kwlist[] = {"nrows", "ncols", "a", "b", NULL};

  if (!PyArg_ParseTupleAndKeywords(args, kwrds, "i|idd", kwlist,
	  &nrows, &ncols, &a, &b)) return NULL;

  if (a>b) PY_ERR(PyExc_ValueError, "a must be less than b");

  if ((nrows<0) || (ncols<0))
    PY_ERR_TYPE("dimensions must be non-negative");

  if (!(obj = (matrix *)Matrix_New(nrows, ncols, DOUBLE)))
    return PyErr_NoMemory();

  gsl_rng_env_setup();
  rng_type = gsl_rng_default;
  rng = gsl_rng_alloc (rng_type);
  gsl_rng_set(rng, seed);

  for (i= 0; i < nrows*ncols; i++)
    MAT_BUFD(obj)[i] = gsl_ran_flat (rng, a, b);

  seed = gsl_rng_get (rng);
  gsl_rng_free(rng);

  return (PyObject *)obj;
}
Example #2
0
File: misc.c Project: 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;
}
Example #3
0
static PyObject* diag(PyObject *self, PyObject *args)
{
    PyObject *F;
    matrix *d=NULL;
    cholmod_factor *L;
#if PY_MAJOR_VERSION >= 3
    const char *descr;
#else
    char *descr;
#endif
    int k, strt, incx=1, incy, nrows, ncols;

    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");
    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

    /* Check factorization */
    if (L->xtype == CHOLMOD_PATTERN  || L->minor<L->n || !L->is_ll
        || !L->is_super)
        PY_ERR(PyExc_ValueError, "F must be a nonsingular supernodal "
            "Cholesky factor");
    if (!(d = Matrix_New(L->n,1,L->xtype == CHOLMOD_REAL ? DOUBLE :
        COMPLEX))) return PyErr_NoMemory();

    strt = 0;
    for (k=0; k<L->nsuper; k++){
	/* x[L->px[k], .... ,L->px[k+1]-1] is a dense lower-triangular
	 * nrowx times ncols matrix.  We copy its diagonal to
	 * d[strt, ..., strt+ncols-1] */

        ncols = (int)((int_t *) L->super)[k+1] -
            ((int_t *) L->super)[k];
        nrows = (int)((int_t *) L->pi)[k+1] - ((int_t *) L->pi)[k];
        incy = nrows+1;
        if (MAT_ID(d) == DOUBLE)
	    dcopy_(&ncols, ((double *) L->x) + ((int_t *) L->px)[k],
                &incy, MAT_BUFD(d)+strt, &incx);
        else
	    zcopy_(&ncols, ((double complex *) L->x) + ((int_t *) L->px)[k],
                &incy, MAT_BUFZ(d)+strt, &incx);
        strt += ncols;
    }
    return (PyObject *)d;
}
Example #4
0
File: misc.c Project: 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;
}
Example #5
0
File: misc.c Project: cvxopt/smcp
static PyObject *phase1_sdp
(PyObject *self, PyObject *args, PyObject *kwrds) {

  matrix *u;
  spmatrix *Ai,*Ao;
  int_t k,i,j,n,m,nnz,nz,col;


  if(!PyArg_ParseTuple(args,"OO",&Ai,&u)) return NULL;
  n = (int_t) sqrt((double)SP_NROWS(Ai));
  m = SP_NCOLS(Ai) - 1;
  nnz = SP_NNZ(Ai) - SP_COL(Ai)[1] + 1 + m + n + 1;

  Ao = SpMatrix_New((n+2)*(n+2),m+2,nnz,DOUBLE);
  if (!Ao) return PyErr_NoMemory();

  // A_0
  SP_VALD(Ao)[0] = 1.0;
  SP_ROW(Ao)[0] = n*(n+2)+n;
  SP_COL(Ao)[0] = 0;
  SP_COL(Ao)[1] = 1;

  // A_i, i=1,..,m
  for (i=1;i<=m;i++){
    k = SP_COL(Ao)[i];
    nz = SP_COL(Ai)[i+1]-SP_COL(Ai)[i]; // nonzeros in Ai
    // copy Ai
    memcpy(SP_VALD(Ao)+k,SP_VALD(Ai)+SP_COL(Ai)[i],nz*sizeof(double));
    // insert -u[i]
    SP_VALD(Ao)[k+nz] = -MAT_BUFD(u)[i-1];
    // update row colptr
    SP_COL(Ao)[i+1] = SP_COL(Ao)[i]+nz+1;
    // generate row indices
    for (j=0;j<nz;j++) {
      col = SP_ROW(Ai)[SP_COL(Ai)[i]+j] / n;
      SP_ROW(Ao)[k+j] = SP_ROW(Ai)[SP_COL(Ai)[i]+j] + col*2;
    }
    SP_ROW(Ao)[k+nz] = n*(n+2)+n;
  }
  // last constraint
  k = SP_COL(Ao)[m+1];
  for (i=0;i<n;i++){
    SP_VALD(Ao)[k+i] = 1.0;
    SP_ROW(Ao)[k+i] = i*(n+2)+i;
  }
  SP_VALD(Ao)[k+n] = 1.0;
  SP_ROW(Ao)[k+n] = (n+2)*(n+2)-1;
  SP_COL(Ao)[m+2] = SP_COL(Ao)[m+1] + n + 1;

  return (PyObject*) Ao;
}
Example #6
0
File: misc.c Project: 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;
}
Example #7
0
File: misc.c Project: 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);
}
Example #8
0
File: misc.c Project: cvxopt/smcp
static PyObject* sdpa_readhead
(PyObject *self, PyObject *args)
{
  int i,j,t;
  int_t m=0,n=0,nblocks=0;
  matrix *bstruct = NULL;
  PyObject *f;

  char buf[2048];  // buffer
  char *info;

  if (!PyArg_ParseTuple(args,"O",&f)) return NULL;
#if PY_MAJOR_VERSION >= 3
    if (PyUnicode_Check(f)) {
      const char* fname = PyUnicode_AsUTF8AndSize(f,NULL);
#else
    if (PyString_Check(f)) {
      const char* fname = PyString_AsString(f);
#endif
      FILE *fp = fopen(fname,"r");
      if (!fp) {
        return NULL;
      }
      /* Skip comments and read m */
      while (1) {
        info = fgets(buf,1024,fp);
        if (buf[0] != '*' && buf[0] != '"') {
          sscanf(buf,"%d",&i);
          break;
        }
      }
      m = (int_t) i;

      /* read nblocks */
      j = fscanf(fp,"%d",&i);
      nblocks = (int_t) i;

      /* read blockstruct and compute block offsets*/
      bstruct = Matrix_New(nblocks,1,INT);
      if (!bstruct) return PyErr_NoMemory();
      n = 0;
      for (i=0; i<nblocks; i++) {
        j = fscanf(fp,"%*[^0-9+-]%d",&t);
        MAT_BUFI(bstruct)[i] = (int_t) t;
        n += (int_t) labs(MAT_BUFI(bstruct)[i]);
      }
      fclose(fp);
  }

  return Py_BuildValue("iiN",n,m,bstruct);
}


static char doc_sdpa_read[] =
  "Reads sparse SDPA data file (dat-s).\n"
  "\n"
  "A,b,bstruct = sdpa_read(f[,neg=False])\n"
  "\n"
  "PURPOSE\n"
  "Reads problem data from sparse SDPA data file for\n"
  "the semidefinite programs:\n"
  "\n"
  "  (P)  minimize    <A0,X>\n"
  "       subject to  <Ai,X> = bi,   i = 1,...,m\n"
  "                   X >= 0\n"
  "\n"
  "  (D)  maximize    b'*y\n"
  "       subject to  sum_i Ai*yi + S = A0\n"
  "                   S >= 0\n"
  "\n"
  "Here '>=' means that X and S must be positive semidefinite.\n"
  "The matrices A0,A1,...Am are symmetric and of order n.\n"
  "If the optional argument 'neg' is True, the negative of the\n"
  "problem data is returned.\n"
  "\n"
  "ARGUMENTS\n"
  "f         Python file object\n"
  "\n"
  "neg       Python boolean (optional)\n"
  "\n"
  "RETURNS\n"
  "A         CVXOPT sparse matrix of doubles with columns Ai[:]\n"
  "          (Only lower trianglular elements of Ai are stored.)\n"
  "\n"
  "b         CVXOPT matrix\n"
  "\n"
  "bstruct   CVXOPT integer matrix\n";

static PyObject* sdpa_read
(PyObject *self, PyObject *args, PyObject *kwrds)
{
  int i,j,mno,bno,ii,jj,t;
  int_t k,m,n,nblocks,nlines;
  double v;
  long fpos;
  PyObject *f;
  PyObject *neg = Py_False;
  char *info;
  const char* fname;
  int_t* boff;     // block offset
  char buf[2048];  // buffer
  char *kwlist[] = {"f","neg",NULL};

  if (!PyArg_ParseTupleAndKeywords(args,kwrds,"O|O",kwlist,&f,&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) {
    return NULL;
  }
  /* Skip comments and read m */
  while (1) {
    info = fgets(buf,1024,fp);
    if (buf[0] != '*' && buf[0] != '"') {
      sscanf(buf,"%d",&i);
      break;
    }
  }
  m = (int_t) i;

  /* read nblocks */
  j = fscanf(fp,"%d",&i);
  nblocks = (int_t) i;

  /* read blockstruct and compute block offsets*/
  matrix *bstruct = Matrix_New(nblocks,1,INT);
  if (!bstruct) return PyErr_NoMemory();
  boff = malloc(sizeof(int_t)*(nblocks+1));
  if(!boff) return PyErr_NoMemory();
  boff[0] = 0;  n = 0;
  for (i=0; i<nblocks; i++) {
    j = fscanf(fp,"%*[^0-9+-]%d",&t);
    MAT_BUFI(bstruct)[i] = (int_t) t;
    n += (int_t) labs(MAT_BUFI(bstruct)[i]);
    boff[i+1] = n;
  }

  /* read vector b */
  matrix *b = Matrix_New(m,1,DOUBLE);
  if (!b) return PyErr_NoMemory();
  for (i=0;i<m;i++) {
    j = fscanf(fp,"%*[^0-9+-]%lf",&MAT_BUFD(b)[i]);
    if (neg == Py_True)
      MAT_BUFD(b)[i] *= -1;
  }

  /* count remaining lines */
  fpos = ftell(fp);
  for (nlines = 0; fgets(buf, 1023, fp) != NULL; nlines++);
  //nlines--;
  fseek(fp,fpos,SEEK_SET);

  /* Create data matrix A */
  spmatrix *A = SpMatrix_New(n*n,m+1,nlines,DOUBLE);
  if (!A) return PyErr_NoMemory();

  // read data matrices
  fseek(fp,fpos,SEEK_SET);
  for (i=0,j=-1,k=0;k<nlines;k++){
    if (fscanf(fp,"%*[^0-9+-]%d",&mno) <=0 ) break;
    if (fscanf(fp,"%*[^0-9+-]%d",&bno) <=0 ) break;
    if (fscanf(fp,"%*[^0-9+-]%d",&ii) <=0 ) break;
    if (fscanf(fp,"%*[^0-9+-]%d",&jj) <=0 ) break;
    if (fscanf(fp,"%*[^0-9+-]%lf",&v) <=0 ) break;

    // check that value is nonzero
    if (v != 0) {
      // add block offset
      ii += boff[bno-1];
      jj += boff[bno-1];

      // insert index and value
      SP_ROW(A)[i] = (int_t)  ((ii-1)*n + (jj-1));
      if (neg == Py_True)
	SP_VALD(A)[i] = -v;
      else
	SP_VALD(A)[i] = v;

      // update col. ptr.
      while (mno > j)
	SP_COL(A)[++j] = i;

      i++;
    }
  }
  // update last element(s) of col. ptr.
  while (m+1 > j)
    SP_COL(A)[++j] = i;

  fclose(fp);

  // free temp. memory
  free(boff);

  return Py_BuildValue("NNN",A,b,bstruct);
}
Example #9
0
File: misc.c Project: 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;
}
Example #10
0
static PyObject* linsolve(PyObject *self, PyObject *args,
    PyObject *kwrds)
{
    spmatrix *A;
    matrix *B;
#if PY_MAJOR_VERSION >= 3
    int trans_ = 'N';
#endif
    char trans='N';
    double info[UMFPACK_INFO];
    int oB=0, n, nrhs=-1, ldB=0, k;
    void *symbolic, *numeric, *x;
    char *kwlist[] = {"A", "B", "trans", "nrhs", "ldB", "offsetB",
        NULL};

#if PY_MAJOR_VERSION >= 3
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|Ciii", kwlist,
        &A, &B, &trans_, &nrhs, &ldB, &oB)) return NULL;
    trans = (char) trans_;
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OO|ciii", kwlist,
        &A, &B, &trans, &nrhs, &ldB, &oB)) return NULL;
#endif

    if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A))
        PY_ERR_TYPE("A must be a square sparse matrix");
    n = SP_NROWS(A);
    if (!Matrix_Check(B) || MAT_ID(B) != SP_ID(A))
        PY_ERR_TYPE("B must a dense matrix of the same numeric type "
            "as A");

    if (nrhs < 0) nrhs = B->ncols;
    if (n == 0 || nrhs == 0) return Py_BuildValue("i", 0);
    if (ldB == 0) ldB = MAX(1,B->nrows);
    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 (trans != 'N' && trans != 'T' && trans != 'C')
        err_char("trans", "'N', 'T', 'C'");

    if (SP_ID(A) == DOUBLE)
        UMFD(symbolic)(n, n, SP_COL(A), SP_ROW(A), SP_VAL(A), &symbolic,
            NULL, info);
    else
        UMFZ(symbolic)(n, n, SP_COL(A), SP_ROW(A), SP_VAL(A), NULL,
            &symbolic, NULL, info);

    if (info[UMFPACK_STATUS] != UMFPACK_OK){
        if (SP_ID(A) == DOUBLE)
            UMFD(free_symbolic)(&symbolic);
        else
            UMFZ(free_symbolic)(&symbolic);
        if (info[UMFPACK_STATUS] == UMFPACK_ERROR_out_of_memory)
            return PyErr_NoMemory();
        else {
            snprintf(umfpack_error,20,"%s %i","UMFPACK ERROR",
                (int) info[UMFPACK_STATUS]);
            PyErr_SetString(PyExc_ValueError, umfpack_error);
            return NULL;
        }
    }

    if (SP_ID(A) == DOUBLE) {
        UMFD(numeric)(SP_COL(A), SP_ROW(A), SP_VAL(A), symbolic,
            &numeric, NULL, info);
        UMFD(free_symbolic)(&symbolic);
    } else {
        UMFZ(numeric)(SP_COL(A), SP_ROW(A), SP_VAL(A), NULL, symbolic,
            &numeric, NULL, info);
        UMFZ(free_symbolic)(&symbolic);
    }
    if (info[UMFPACK_STATUS] != UMFPACK_OK){
        if (SP_ID(A) == DOUBLE)
            UMFD(free_numeric)(&numeric);
        else
            UMFZ(free_numeric)(&numeric);
        if (info[UMFPACK_STATUS] == UMFPACK_ERROR_out_of_memory)
            return PyErr_NoMemory();
        else {
            if (info[UMFPACK_STATUS] == UMFPACK_WARNING_singular_matrix)
                PyErr_SetString(PyExc_ArithmeticError, "singular "
                    "matrix");
            else {
                snprintf(umfpack_error,20,"%s %i","UMFPACK ERROR",
                    (int) info[UMFPACK_STATUS]);
                PyErr_SetString(PyExc_ValueError, umfpack_error);
            }
            return NULL;
        }
    }

    if (!(x = malloc(n*E_SIZE[SP_ID(A)]))) {
        if (SP_ID(A) == DOUBLE)
            UMFD(free_numeric)(&numeric);
        else
            UMFZ(free_numeric)(&numeric);
        return PyErr_NoMemory();
    }
    for (k=0; k<nrhs; k++){
        if (SP_ID(A) == DOUBLE)
            UMFD(solve)(trans == 'N' ? UMFPACK_A: UMFPACK_Aat,
                SP_COL(A), SP_ROW(A), SP_VAL(A), x,
                MAT_BUFD(B) + k*ldB + oB, numeric, NULL, info);
        else
            UMFZ(solve)(trans == 'N' ? UMFPACK_A: trans == 'C' ?
                UMFPACK_At : UMFPACK_Aat, SP_COL(A), SP_ROW(A),
                SP_VAL(A), NULL, x, NULL,
                (double *)(MAT_BUFZ(B) + k*ldB + oB), NULL, numeric,
                NULL, info);
        if (info[UMFPACK_STATUS] == UMFPACK_OK)
            memcpy(B->buffer + (k*ldB + oB)*E_SIZE[SP_ID(A)], x,
                n*E_SIZE[SP_ID(A)]);
        else
	    break;
    }
    free(x);
    if (SP_ID(A) == DOUBLE)
        UMFD(free_numeric)(&numeric);
    else
        UMFZ(free_numeric)(&numeric);

    if (info[UMFPACK_STATUS] != UMFPACK_OK){
        if (info[UMFPACK_STATUS] == UMFPACK_ERROR_out_of_memory)
            return PyErr_NoMemory();
        else {
            if (info[UMFPACK_STATUS] == UMFPACK_WARNING_singular_matrix)
                PyErr_SetString(PyExc_ArithmeticError, "singular "
                    "matrix");
            else {
                snprintf(umfpack_error,20,"%s %i","UMFPACK ERROR",
                    (int) info[UMFPACK_STATUS]);
                PyErr_SetString(PyExc_ValueError, umfpack_error);
            }
        return NULL;
        }
    }
    return Py_BuildValue("");
}
Example #11
0
File: glpk.c Project: 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;
}
Example #12
0
File: glpk.c Project: 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;
}