--- src/C/glpk.c.orig 2013-07-31 12:05:27.089955661 -0600 +++ src/C/glpk.c 2013-07-31 12:13:40.702115730 -0600 @@ -22,6 +22,8 @@ #include "cvxopt.h" #include "misc.h" #include "glpk.h" +#include +#include PyDoc_STRVAR(glpk__doc__, "Interface to the simplex and mixed integer LP algorithms in GLPK.\n\n" @@ -36,62 +38,15 @@ PyDoc_STRVAR(glpk__doc__, static PyObject *glpk_module; -typedef struct { - char name[20]; - int idx; - char type; -} param_tuple; - -static const param_tuple GLPK_PARAM_LIST[] = { - {"LPX_K_MSGLEV", LPX_K_MSGLEV, 'i'}, - {"LPX_K_SCALE", LPX_K_SCALE, 'i'}, - {"LPX_K_DUAL", LPX_K_DUAL, 'i'}, - {"LPX_K_PRICE", LPX_K_PRICE, 'i'}, - {"LPX_K_RELAX", LPX_K_RELAX, 'f'}, - {"LPX_K_TOLBND", LPX_K_TOLBND, 'f'}, - {"LPX_K_TOLDJ", LPX_K_TOLDJ, 'f'}, - {"LPX_K_TOLPIV", LPX_K_TOLPIV, 'f'}, - {"LPX_K_ROUND", LPX_K_ROUND, 'i'}, - {"LPX_K_OBJLL", LPX_K_OBJLL, 'f'}, - {"LPX_K_OBJUL", LPX_K_OBJUL, 'f'}, - {"LPX_K_ITLIM", LPX_K_ITLIM, 'i'}, - {"LPX_K_ITCNT", LPX_K_ITCNT, 'i'}, - {"LPX_K_TMLIM", LPX_K_TMLIM, 'f'}, - {"LPX_K_OUTFRQ", LPX_K_OUTFRQ, 'i'}, - {"LPX_K_OUTDLY", LPX_K_OUTDLY, 'f'}, - {"LPX_K_BRANCH", LPX_K_BRANCH, 'i'}, - {"LPX_K_BTRACK", LPX_K_BTRACK, 'i'}, - {"LPX_K_TOLINT", LPX_K_TOLINT, 'f'}, - {"LPX_K_TOLOBJ", LPX_K_TOLOBJ, 'f'}, - {"LPX_K_MPSINFO", LPX_K_MPSINFO, 'i'}, - {"LPX_K_MPSOBJ", LPX_K_MPSOBJ, 'i'}, - {"LPX_K_MPSORIG", LPX_K_MPSORIG, 'i'}, - {"LPX_K_MPSWIDE", LPX_K_MPSWIDE, 'i'}, - {"LPX_K_MPSFREE", LPX_K_MPSFREE, 'i'}, - {"LPX_K_MPSSKIP", LPX_K_MPSSKIP, 'i'}, - {"LPX_K_LPTORIG", LPX_K_LPTORIG, 'i'}, - {"LPX_K_PRESOL", LPX_K_PRESOL, 'i'}, -}; /* 28 paramaters */ - - #if PY_MAJOR_VERSION >= 3 -static int get_param_idx(const char *str, int *idx, char *type) +#define PYINT_CHECK(value) PyLong_Check(value) +#define PYINT_AS_LONG(value) PyLong_AS_LONG(value) +#define PYSTRING_FROMSTRING(str) PyUnicode_FromString(str) #else -static int get_param_idx(char *str, int *idx, char *type) +#define PYINT_CHECK(value) PyInt_Check(value) +#define PYINT_AS_LONG(value) PyInt_AS_LONG(value) +#define PYSTRING_FROMSTRING(str) PyString_FromString(str) #endif -{ - int i; - - for (i=0; i<28; i++) { - if (!strcmp(GLPK_PARAM_LIST[i].name, str)) { - *idx = GLPK_PARAM_LIST[i].idx; - *type = GLPK_PARAM_LIST[i].type; - return 1; - } - } - return 0; -} - static char doc_simplex[] = "Solves a linear program using GLPK.\n\n" @@ -127,11 +82,12 @@ static PyObject *simplex(PyObject *self, { matrix *c, *h, *b=NULL, *x=NULL, *z=NULL, *y=NULL; PyObject *G, *A=NULL, *t=NULL, *param, *key, *value; - LPX *lp; - int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL, param_id; + glp_prob *lp; + glp_smcp smcp; + int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL; int_t pos=0; double *a=NULL, val; - char param_type, err_str[100]; + char err_str[100]; #if PY_MAJOR_VERSION >= 3 const char *keystr; #else @@ -183,18 +139,18 @@ static PyObject *simplex(PyObject *self, return NULL; } - lp = lpx_create_prob(); - lpx_add_rows(lp, m+p); - lpx_add_cols(lp, n); + lp = glp_create_prob(); + glp_add_rows(lp, m+p); + glp_add_cols(lp, n); for (i=0; i= 3 - if ((PyUnicode_Check(key)) && - get_param_idx(_PyUnicode_AsString(key), ¶m_id, - ¶m_type)){ + if (PyUnicode_Check(key)){ keystr = _PyUnicode_AsString(key); #else - if ((keystr = PyString_AsString(key)) && get_param_idx(keystr, - ¶m_id, ¶m_type)){ -#endif - if (param_type == 'i'){ -#if PY_MAJOR_VERSION >= 3 - if (!PyLong_Check(value)){ -#else - if (!PyInt_Check(value)){ -#endif - sprintf(err_str, "invalid value for integer " - "GLPK parameter: %-.20s", keystr); - PyErr_SetString(PyExc_ValueError, err_str); - lpx_delete_prob(lp); - Py_DECREF(param); - return NULL; - } - if (!strcmp("LPX_K_PRESOL", keystr) && -#if PY_MAJOR_VERSION >= 3 - PyLong_AS_LONG(value) != 1){ -#else - PyInt_AS_LONG(value) != 1){ + if ((keystr = PyString_AsString(key))){ #endif + if (!strcmp("LPX_K_MSGLEV", keystr)){ + switch (PYINT_AS_LONG(value)){ + case 0: smcp.msg_lev = GLP_MSG_OFF; break; + case 1: smcp.msg_lev = GLP_MSG_ERR; break; + case 2: smcp.msg_lev = GLP_MSG_ON; break; + case 3: smcp.msg_lev = GLP_MSG_ALL; break; + default: goto error; + } + } else if (!strcmp("LPX_K_SCALE", keystr)){ + switch(PYINT_AS_LONG(value)){ + case 0: glp_unscale_prob(lp); break; + case 1: glp_scale_prob(lp, GLP_SF_EQ); break; + case 2: glp_scale_prob(lp, GLP_SF_GM); break; + case 3: glp_scale_prob(lp, GLP_SF_GM | GLP_SF_EQ); break; + default: goto error; + } + } else if (!strcmp("LPX_K_DUAL", keystr)){ + switch(PYINT_AS_LONG(value)){ + case 0: smcp.meth = GLP_PRIMAL; break; + case 1: smcp.meth = GLP_DUAL; break; + default: goto error; + } + } else if (!strcmp("LPX_K_PRICE", keystr)){ + switch(PYINT_AS_LONG(value)){ + case 0: smcp.pricing = GLP_PT_STD; break; + case 1: smcp.pricing = GLP_PT_PSE; break; + default: goto error; + } + } else if (!strcmp("LPX_K_RELAX", keystr)){ + double relax = PyFloat_AsDouble(value); + if (relax < 0.0 || relax > 1.0) + goto error; + smcp.r_test = (relax == 0.0) ? GLP_RT_STD : GLP_RT_HAR; + } else if (!strcmp("LPX_K_TOLBND", keystr)){ + smcp.tol_bnd = PyFloat_AsDouble(value); + if (smcp.tol_bnd < DBL_EPSILON || smcp.tol_bnd > 0.001) + goto error; + } else if (!strcmp("LPX_K_TOLDJ", keystr)){ + smcp.tol_dj = PyFloat_AsDouble(value); + if (smcp.tol_dj < DBL_EPSILON || smcp.tol_dj > 0.001) + goto error; + } else if (!strcmp("LPX_K_TOLPIV", keystr)){ + smcp.tol_piv = PyFloat_AsDouble(value); + if (smcp.tol_piv < DBL_EPSILON || smcp.tol_piv > 0.001) + goto error; + } else if (!strcmp("LPX_K_ROUND", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_OBJLL", keystr)){ + smcp.obj_ll = PyFloat_AsDouble(value); + } else if (!strcmp("LPX_K_OBJUL", keystr)){ + smcp.obj_ul = PyFloat_AsDouble(value); + } else if (!strcmp("LPX_K_ITLIM", keystr)){ + smcp.it_lim = PYINT_AS_LONG(value); + if (smcp.it_lim < 0) + smcp.it_lim = INT_MAX; + } else if (!strcmp("LPX_K_ITCNT", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_TMLIM", keystr)){ + smcp.tm_lim = (int)(PyFloat_AsDouble(value) * 1000.0); + if (smcp.tm_lim < 0) + smcp.tm_lim = INT_MAX; + } else if (!strcmp("LPX_K_OUTFRQ", keystr)){ + smcp.out_frq = PYINT_AS_LONG(value); + if (smcp.out_frq <= 0) + goto error; + } else if (!strcmp("LPX_K_OUTDLY", keystr)){ + smcp.out_dly = (int)(PyFloat_AsDouble(value) * 1000.0); + } else if (!strcmp("LPX_K_BRANCH", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_BTRACK", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_TOLINT", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_TOLOBJ", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSINFO", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSOBJ", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSORIG", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSWIDE", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSFREE", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSSKIP", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_LPTORIG", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_PRESOL", keystr)){ + if (PYINT_AS_LONG(value) != 1) PyErr_Warn(PyExc_UserWarning, "ignoring value of " "GLPK parameter 'LPX_K_PRESOL'"); + } else if (!strcmp("LPX_K_BINARIZE", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_USECUTS", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_BFTYPE", keystr)){ + glp_bfcp bfcp; + + glp_get_bfcp(lp, &bfcp); + switch(PYINT_AS_LONG(value)){ + case 1: bfcp.type = GLP_BF_FT; break; + case 2: bfcp.type = GLP_BF_BG; break; + case 3: bfcp.type = GLP_BF_GR; break; + default: goto error; } - else lpx_set_int_parm(lp, param_id, -#if PY_MAJOR_VERSION >= 3 - PyLong_AS_LONG(value)); -#else - PyInt_AS_LONG(value)); -#endif - } - else { -#if PY_MAJOR_VERSION >= 3 - if (!PyLong_Check(value) && !PyFloat_Check(value)){ -#else - if (!PyInt_Check(value) && !PyFloat_Check(value)){ -#endif - sprintf(err_str, "invalid value for floating point " - "GLPK parameter: %-.20s", keystr); - PyErr_SetString(PyExc_ValueError, err_str); - lpx_delete_prob(lp); - Py_DECREF(param); - return NULL; - } - lpx_set_real_parm(lp, param_id, - PyFloat_AsDouble(value)); + glp_set_bfcp(lp, &bfcp); + } else if (!strcmp("LPX_K_MIPGAP", keystr)){ + /* Ignored */ + } else { + sprintf(err_str, "unknown GLPK parameter: %-.20s", keystr); + PyErr_SetString(PyExc_ValueError, err_str); + glp_delete_prob(lp); + Py_DECREF(param); + return NULL; } + } } - lpx_set_int_parm(lp, LPX_K_PRESOL, 1); + smcp.presolve = GLP_ON; Py_DECREF(param); - switch (lpx_simplex(lp)){ + switch (glp_simplex(lp, &smcp)){ - case LPX_E_OK: + case 0: x = (matrix *) Matrix_New(n,1,DOUBLE); z = (matrix *) Matrix_New(m,1,DOUBLE); @@ -329,71 +356,61 @@ static PyObject *simplex(PyObject *self, Py_XDECREF(z); Py_XDECREF(y); Py_XDECREF(t); - lpx_delete_prob(lp); + glp_delete_prob(lp); return PyErr_NoMemory(); } - PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("optimal")); -#else - PyString_FromString("optimal")); -#endif + PyTuple_SET_ITEM(t, 0, (PyObject *)PYSTRING_FROMSTRING("optimal")); for (i=0; i= 3 - PyUnicode_FromString("primal infeasible")); -#else - PyString_FromString("primal infeasible")); -#endif + PYSTRING_FROMSTRING("primal infeasible")); break; - case LPX_E_NODFS: + case GLP_ENODFS: PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("dual infeasible")); -#else - PyString_FromString("dual infeasible")); -#endif + PYSTRING_FROMSTRING("dual infeasible")); break; default: PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("unknown")); -#else - PyString_FromString("unknown")); -#endif + PYSTRING_FROMSTRING("unknown")); } - lpx_delete_prob(lp); + 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; + +error: + sprintf(err_str, "invalid value for GLPK parameter: %-.20s", keystr); + PyErr_SetString(PyExc_ValueError, err_str); + glp_delete_prob(lp); + Py_DECREF(param); + return NULL; } @@ -428,11 +445,12 @@ static PyObject *integer(PyObject *self, matrix *c, *h, *b=NULL, *x=NULL; PyObject *G, *A=NULL, *IntSet=NULL, *BinSet = NULL; PyObject *t=NULL, *param, *key, *value; - LPX *lp; - int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL, param_id; + glp_prob *lp; + glp_iocp iocp; + int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL; int_t pos=0; double *a=NULL, val; - char param_type, err_str[100]; + char err_str[100]; #if PY_MAJOR_VERSION >= 3 const char *keystr; #else @@ -490,18 +508,18 @@ static PyObject *integer(PyObject *self, if ((BinSet) && (!PyAnySet_Check(BinSet))) PY_ERR_TYPE("invalid binary index set"); - lp = lpx_create_prob(); - lpx_add_rows(lp, m+p); - lpx_add_cols(lp, n); + lp = glp_create_prob(); + glp_add_rows(lp, m+p); + glp_add_cols(lp, n); for (i=0; i= 3 - if ((PyUnicode_Check(key)) && (keystr = PyUnicode_AS_DATA(key)) - && get_param_idx(keystr, ¶m_id, ¶m_type)){ -#else - if ((keystr = PyString_AsString(key)) && get_param_idx(keystr, - ¶m_id, ¶m_type)){ -#endif - if (param_type == 'i'){ -#if PY_MAJOR_VERSION >= 3 - if (!PyLong_Check(value)){ -#else - if (!PyInt_Check(value)){ -#endif - sprintf(err_str, "invalid value for integer " - "GLPK parameter: %-.20s", keystr); - PyErr_SetString(PyExc_ValueError, err_str); - lpx_delete_prob(lp); - Py_DECREF(param); - return NULL; - } - if (!strcmp("LPX_K_PRESOL", keystr) && + glp_init_iocp(&iocp); + while (PyDict_Next(param, &pos, &key, &value)) { #if PY_MAJOR_VERSION >= 3 - PyLong_AS_LONG(value) != 1){ + if ((PyUnicode_Check(key)) && (keystr = PyUnicode_AS_DATA(key))){ #else - PyInt_AS_LONG(value) != 1){ + if ((keystr = PyString_AsString(key))){ #endif + if (!strcmp("LPX_K_MSGLEV", keystr)){ + switch (PYINT_AS_LONG(value)){ + case 0: iocp.msg_lev = GLP_MSG_OFF; break; + case 1: iocp.msg_lev = GLP_MSG_ERR; break; + case 2: iocp.msg_lev = GLP_MSG_ON; break; + case 3: iocp.msg_lev = GLP_MSG_ALL; break; + default: goto error; + } + } else if (!strcmp("LPX_K_SCALE", keystr)){ + switch(PYINT_AS_LONG(value)){ + case 0: glp_unscale_prob(lp); break; + case 1: glp_scale_prob(lp, GLP_SF_EQ); break; + case 2: glp_scale_prob(lp, GLP_SF_GM); break; + case 3: glp_scale_prob(lp, GLP_SF_GM | GLP_SF_EQ); break; + default: goto error; + } + } else if (!strcmp("LPX_K_DUAL", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_PRICE", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_RELAX", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_TOLBND", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_TOLDJ", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_TOLPIV", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_ROUND", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_OBJLL", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_OBJUL", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_ITLIM", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_ITCNT", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_TMLIM", keystr)){ + iocp.tm_lim = (int)(PyFloat_AsDouble(value) * 1000.0); + if (iocp.tm_lim < 0) + iocp.tm_lim = INT_MAX; + } else if (!strcmp("LPX_K_OUTFRQ", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_OUTDLY", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_BRANCH", keystr)){ + switch(PYINT_AS_LONG(value)){ + case 0: iocp.br_tech = GLP_BR_FFV; break; + case 1: iocp.br_tech = GLP_BR_LFV; break; + case 2: iocp.br_tech = GLP_BR_DTH; break; + case 3: iocp.br_tech = GLP_BR_MFV; break; + default: goto error; + } + } else if (!strcmp("LPX_K_BTRACK", keystr)){ + switch(PYINT_AS_LONG(value)){ + case 0: iocp.bt_tech = GLP_BT_DFS; break; + case 1: iocp.bt_tech = GLP_BT_BFS; break; + case 2: iocp.bt_tech = GLP_BT_BPH; break; + case 3: iocp.bt_tech = GLP_BT_BLB; break; + default: goto error; + } + } else if (!strcmp("LPX_K_TOLINT", keystr)){ + iocp.tol_int = PyFloat_AsDouble(value); + if (iocp.tol_int < DBL_EPSILON || iocp.tol_int > 0.001) + goto error; + } else if (!strcmp("LPX_K_TOLOBJ", keystr)){ + iocp.tol_obj = PyFloat_AsDouble(value); + if (iocp.tol_obj < DBL_EPSILON || iocp.tol_obj > 0.001) + goto error; + } else if (!strcmp("LPX_K_MPSINFO", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSOBJ", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSORIG", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSWIDE", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSFREE", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_MPSSKIP", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_LPTORIG", keystr)){ + /* Ignored */ + } else if (!strcmp("LPX_K_PRESOL", keystr)){ + if (PYINT_AS_LONG(value) != 1) PyErr_Warn(PyExc_UserWarning, "ignoring value of " "GLPK parameter 'LPX_K_PRESOL'"); + } else if (!strcmp("LPX_K_BINARIZE", keystr)){ + iocp.binarize = (PYINT_AS_LONG(value) == 0) ? GLP_OFF : GLP_ON; + } else if (!strcmp("LPX_K_USECUTS", keystr)){ + int cuts = PYINT_AS_LONG(value); + if (cuts & ~0xFF) + goto error; + iocp.cov_cuts = (cuts & 1) ? GLP_ON : GLP_OFF; + iocp.clq_cuts = (cuts & 2) ? GLP_ON : GLP_OFF; + iocp.gmi_cuts = (cuts & 4) ? GLP_ON : GLP_OFF; + iocp.mir_cuts = (cuts & 8) ? GLP_ON : GLP_OFF; + } else if (!strcmp("LPX_K_BFTYPE", keystr)){ + glp_bfcp bfcp; + + glp_get_bfcp(lp, &bfcp); + switch(PYINT_AS_LONG(value)){ + case 1: bfcp.type = GLP_BF_FT; break; + case 2: bfcp.type = GLP_BF_BG; break; + case 3: bfcp.type = GLP_BF_GR; break; + default: goto error; } - else -#if PY_MAJOR_VERSION >= 3 - lpx_set_int_parm(lp, param_id, PyLong_AS_LONG(value)); -#else - lpx_set_int_parm(lp, param_id, PyInt_AS_LONG(value)); -#endif - } - else { -#if PY_MAJOR_VERSION >= 3 - if (!PyLong_Check(value) && !PyFloat_Check(value)){ -#else - if (!PyInt_Check(value) && !PyFloat_Check(value)){ -#endif - sprintf(err_str, "invalid value for floating point " - "GLPK parameter: %-.20s", keystr); - PyErr_SetString(PyExc_ValueError, err_str); - lpx_delete_prob(lp); - Py_DECREF(param); - return NULL; - } - lpx_set_real_parm(lp, param_id, - PyFloat_AsDouble(value)); + glp_set_bfcp(lp, &bfcp); + } else if (!strcmp("LPX_K_MIPGAP", keystr)){ + iocp.mip_gap = PyFloat_AsDouble(value); + if (iocp.mip_gap < 0.0) + goto error; + } else { + sprintf(err_str, "unknown GLPK parameter: %-.20s", keystr); + PyErr_SetString(PyExc_ValueError, err_str); + glp_delete_prob(lp); + Py_DECREF(param); + return NULL; } + } } - lpx_set_int_parm(lp, LPX_K_PRESOL, 1); + iocp.presolve = GLP_ON; Py_DECREF(param); if (IntSet) { @@ -628,22 +721,14 @@ static PyObject *integer(PyObject *self, for (i=0; i= 3 - if (!PyLong_Check(tmp)) { -#else - if (!PyInt_Check(tmp)) { -#endif - lpx_delete_prob(lp); + if (!PYINT_CHECK(tmp)) { + 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 + int k = PYINT_AS_LONG(tmp); if ((k < 0) || (k >= n)) { - lpx_delete_prob(lp); + glp_delete_prob(lp); Py_DECREF(iter); PY_ERR(PyExc_IndexError, "index element out of range in I"); } @@ -659,22 +744,14 @@ static PyObject *integer(PyObject *self, for (i=0; i= 3 - if (!PyLong_Check(tmp)) { -#else - if (!PyInt_Check(tmp)) { -#endif - lpx_delete_prob(lp); + if (!PYINT_CHECK(tmp)) { + 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 + int k = PYINT_AS_LONG(tmp); if ((k < 0) || (k >= n)) { - lpx_delete_prob(lp); + glp_delete_prob(lp); Py_DECREF(iter); PY_ERR(PyExc_IndexError, "index element out of range in B"); } @@ -686,117 +763,92 @@ static PyObject *integer(PyObject *self, } + switch (glp_intopt(lp, &iocp)){ - switch (lpx_intopt(lp)){ - - case LPX_E_OK: + case 0: x = (matrix *) Matrix_New(n,1,DOUBLE); if (!x) { Py_XDECREF(t); - lpx_delete_prob(lp); + glp_delete_prob(lp); return PyErr_NoMemory(); } - PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("optimal")); -#else - PyString_FromString("optimal")); -#endif + PyTuple_SET_ITEM(t, 0, (PyObject *)PYSTRING_FROMSTRING("optimal")); for (i=0; i= 3 - PyUnicode_FromString("time limit exceeded")); -#else - PyString_FromString("time limit exceeded")); -#endif + PYSTRING_FROMSTRING("time limit exceeded")); for (i=0; i= 3 - PyUnicode_FromString("invalid MIP formulation")); -#else - PyString_FromString("invalid MIP formulation")); -#endif + PYSTRING_FROMSTRING("invalid MIP formulation")); break; - case LPX_E_NOPFS: + case GLP_ENOPFS: PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("primal infeasible")); -#else - PyString_FromString("primal infeasible")); -#endif + PYSTRING_FROMSTRING("primal infeasible")); break; - case LPX_E_NODFS: + case GLP_ENODFS: PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("dual infeasible")); -#else - PyString_FromString("dual infeasible")); -#endif + PYSTRING_FROMSTRING("dual infeasible")); break; - case LPX_E_ITLIM: + case GLP_EITLIM: PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("maxiters exceeded")); -#else - PyString_FromString("maxiters exceeded")); -#endif + PYSTRING_FROMSTRING("maxiters exceeded")); break; - case LPX_E_SING: + case GLP_ESING: PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("singular or ill-conditioned basis")); -#else - PyString_FromString("singular or ill-conditioned basis")); -#endif + PYSTRING_FROMSTRING("singular or ill-conditioned basis")); break; default: PyTuple_SET_ITEM(t, 0, (PyObject *) -#if PY_MAJOR_VERSION >= 3 - PyUnicode_FromString("unknown")); -#else - PyString_FromString("unknown")); -#endif + PYSTRING_FROMSTRING("unknown")); } - lpx_delete_prob(lp); + glp_delete_prob(lp); PyTuple_SET_ITEM(t, 1, Py_BuildValue("")); return (PyObject *) t; + +error: + sprintf(err_str, "invalid value for GLPK parameter: %-.20s", keystr); + PyErr_SetString(PyExc_ValueError, err_str); + glp_delete_prob(lp); + Py_DECREF(param); + return NULL; }