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