| --- src/C/glpk.c.orig 2014-03-24 09:39:39.510214726 -0700 |
| +++ src/C/glpk.c 2014-03-24 09:38:41.251897138 -0700 |
| @@ -23,75 +23,271 @@ |
| #include "misc.h" |
| #include "glpk.h" |
| |
| + |
| PyDoc_STRVAR(glpk__doc__, |
| "Interface to the simplex and mixed integer LP algorithms in GLPK.\n\n" |
| "The GLPK control parameters have the default values listed in \n" |
| - "the GLPK documentation, except for 'LPX_K_PRESOL', which is set\n" |
| + "the GLPK documentation, except for 'presolve', which is set\n" |
| "to 1 and cannot be modified. The other parameters can be\n" |
| - "modified by making an entry in the dictionary glpk.options.\n" |
| - "For example, the command glpk.options['LPX_K_MSGLEV'] = 0 turns\n" |
| - "off the printed output during execution of glpk.simplex().\n" |
| + "modified by passing a smcp or iocp object to the appropriate function\n" |
| + "For example, the commands param = glpk.smcp(msg_lev = 0), or \n" |
| + "param=glpk.smcp(); param.msg_lev=1 turn off the printed output during" |
| + " execution of glpk.simplex().\n" |
| "See the documentation at www.gnu.org/software/glpk/glpk.html for\n" |
| "the list of GLPK control parameters and their default values."); |
| |
| 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 */ |
| +/* Wrappers around the option glpk structs */ |
| +typedef struct{ |
| + PyObject_HEAD |
| + glp_smcp obj; |
| +} pysmcp; |
| |
| +/* Deallocation of smcp object */ |
| +static void smcp_dealloc(pysmcp* self) |
| +{ |
| + Py_TYPE(self)->tp_free((PyObject*)self); |
| +} |
| |
| -#if PY_MAJOR_VERSION >= 3 |
| -static int get_param_idx(const char *str, int *idx, char *type) |
| -#else |
| -static int get_param_idx(char *str, int *idx, char *type) |
| -#endif |
| +/* New smcp method */ |
| +static PyObject * |
| +smcp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
| { |
| - int i; |
| + pysmcp *self; |
| + self = (pysmcp *)type->tp_alloc(type, 0); |
| + return (PyObject *)self; |
| +} |
| + |
| +/* Initialisation of smcp object */ |
| +static int |
| +smcp_init(pysmcp *self, PyObject *args, PyObject *kwds) |
| +{ |
| + /*static char *kwlist[] = {"number", NULL};*/ |
| + static char *kwlist[] = { "msg_lev", "meth", "pricing", "r_test", "tol_bnd", "tol_dj", "tol_piv", "obj_ll", "obj_ul", "it_lim", "tm_lim", "out_frq", "out_dly", "presolve" }; |
| + glp_init_smcp(&self->obj); |
| + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|iiiidddddiiiii", kwlist, |
| + &self->obj.msg_lev, |
| + &self->obj.meth, |
| + &self->obj.pricing, |
| + &self->obj.r_test, |
| + &self->obj.tol_bnd, |
| + &self->obj.tol_dj, |
| + &self->obj.tol_piv, |
| + &self->obj.obj_ll, |
| + &self->obj.obj_ul, |
| + &self->obj.it_lim, |
| + &self->obj.tm_lim, |
| + &self->obj.out_frq, |
| + &self->obj.out_dly, |
| + &self->obj.presolve)) |
| + return -1; |
| |
| - 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; |
| } |
| |
| +/* smcp members declaration */ |
| +static PyMemberDef smcpMembers[] = { |
| + {"msg_lev", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,msg_lev), 0, "message level: "}, |
| + {"meth", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,meth), 0, "simplex method option: "}, |
| + {"pricing", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,pricing), 0, "pricing technique: "}, |
| + {"r_test", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,r_test), 0, "ratio test technique: "}, |
| + {"tol_bnd", T_DOUBLE, offsetof(pysmcp,obj)+offsetof(glp_smcp,tol_bnd), 0, "spx.tol_bnd "}, |
| + {"tol_dj", T_DOUBLE, offsetof(pysmcp,obj)+offsetof(glp_smcp,tol_dj), 0, "spx.tol_dj "}, |
| + {"tol_piv", T_DOUBLE, offsetof(pysmcp,obj)+offsetof(glp_smcp,tol_piv), 0, "spx.tol_piv "}, |
| + {"obj_ll", T_DOUBLE, offsetof(pysmcp,obj)+offsetof(glp_smcp,obj_ll), 0, "spx.obj_ll "}, |
| + {"obj_ul", T_DOUBLE, offsetof(pysmcp,obj)+offsetof(glp_smcp,obj_ul), 0, "spx.obj_ul "}, |
| + {"it_lim", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,it_lim), 0, "spx.it_lim "}, |
| + {"tm_lim", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,tm_lim), 0, "spx.tm_lim (milliseconds) "}, |
| + {"out_frq", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,out_frq), 0, "spx.out_frq "}, |
| + {"out_dly", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,out_dly), 0, "spx.out_dly (milliseconds) "}, |
| + {"presolve", T_INT, offsetof(pysmcp,obj)+offsetof(glp_smcp,presolve), 0, "enable/disable using LP presolver "}, |
| +}; |
| + |
| +static PyTypeObject smcp_t = { |
| + PyVarObject_HEAD_INIT(NULL, 0) |
| + "glpk.smcp", /* tp_name */ |
| + sizeof(pysmcp), /* tp_basicsize */ |
| + 0, /* tp_itemsize */ |
| + (destructor)smcp_dealloc, /* tp_dealloc */ |
| + 0, /* tp_print */ |
| + 0, /* tp_getattr */ |
| + 0, /* tp_setattr */ |
| + 0, /* tp_reserved */ |
| + 0, /* tp_repr */ |
| + 0, /* tp_as_number */ |
| + 0, /* tp_as_sequence */ |
| + 0, /* tp_as_mapping */ |
| + 0, /* tp_hash */ |
| + 0, /* tp_call */ |
| + 0, /* tp_str */ |
| + 0, /* tp_getattro */ |
| + 0, /* tp_setattro */ |
| + 0, /* tp_as_buffer */ |
| + Py_TPFLAGS_DEFAULT | |
| + Py_TPFLAGS_BASETYPE, /* tp_flags */ |
| + "simplex method control parameters", /* tp_doc */ |
| + 0, /* tp_traverse */ |
| + 0, /* tp_clear */ |
| + 0, /* tp_richcompare */ |
| + 0, /* tp_weaklistoffset */ |
| + 0, /* tp_iter */ |
| + 0, /* tp_iternext */ |
| + 0, /* tp_methods */ |
| + smcpMembers, /* tp_members */ |
| + 0, /* tp_getset */ |
| + 0, /* tp_base */ |
| + 0, /* tp_dict */ |
| + 0, /* tp_descr_get */ |
| + 0, /* tp_descr_set */ |
| + 0, /* tp_dictoffset */ |
| + (initproc)smcp_init, /* tp_init */ |
| + 0, /* tp_alloc */ |
| + smcp_new, /* tp_new */ |
| +}; |
| + |
| + |
| +/* Wrappers around the option glpk structs */ |
| +typedef struct{ |
| + PyObject_HEAD |
| + glp_iocp obj; |
| +} pyiocp; |
| + |
| +/* Deallocation of iocp object */ |
| +static void iocp_dealloc(pysmcp* self) |
| +{ |
| + Py_TYPE(self)->tp_free((PyObject*)self); |
| +} |
| + |
| +/* New iocp method */ |
| +static PyObject * |
| +iocp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
| +{ |
| + pyiocp *self; |
| + self = (pyiocp *)type->tp_alloc(type, 0); |
| + return (PyObject *)self; |
| +} |
| + |
| +/* Initialisation of iocp object */ |
| +static int |
| +iocp_init(pyiocp *self, PyObject *args, PyObject *kwds) |
| +{ |
| + /*static char *kwlist[] = {"number", NULL};*/ |
| + static char *kwlist[] = { "msg_lev", "br_tech", "bt_tech", "tol_int", "tol_obj", "tm_lim", "out_frq", "out_dly", "cb_size", "pp_tech", "mip_gap", "mir_cuts", "gmi_cuts", "cov_cuts", "clq_cuts", "presolve", "binarize", "fp_heur", "ps_heur", "ps_tm_lim", "use_sol", "save_sol", "alien",NULL}; |
| + glp_init_iocp(&self->obj); |
| + |
| + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|iiiddiiiiidiiiiiiiiiisi", kwlist, |
| + &self->obj.msg_lev, |
| + &self->obj.br_tech, |
| + &self->obj.bt_tech, |
| + &self->obj.tol_int, |
| + &self->obj.tol_obj, |
| + &self->obj.tm_lim, |
| + &self->obj.out_frq, |
| + &self->obj.out_dly, |
| + &self->obj.cb_size, |
| + &self->obj.pp_tech, |
| + &self->obj.mip_gap, |
| + &self->obj.mir_cuts, |
| + &self->obj.gmi_cuts, |
| + &self->obj.cov_cuts, |
| + &self->obj.clq_cuts, |
| + &self->obj.presolve, |
| + &self->obj.binarize, |
| + &self->obj.fp_heur, |
| + &self->obj.ps_heur, |
| + &self->obj.ps_tm_lim, |
| + &self->obj.use_sol, |
| + &self->obj.save_sol, |
| + &self->obj.alien)) |
| + return -1; |
| + |
| + return 0; |
| +} |
| + |
| +/* iocp members declaration */ |
| +static PyMemberDef iocpMembers[] = { |
| + {"msg_lev", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,msg_lev), 0, "message level (see glp_smcp) "}, |
| + {"br_tech", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,br_tech), 0, "branching technique: "}, |
| + {"bt_tech", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,bt_tech), 0, "backtracking technique: "}, |
| + {"tol_int", T_DOUBLE, offsetof(pysmcp,obj)+offsetof(glp_iocp,tol_int), 0, "mip.tol_int "}, |
| + {"tol_obj", T_DOUBLE, offsetof(pysmcp,obj)+offsetof(glp_iocp,tol_obj), 0, "mip.tol_obj "}, |
| + {"tm_lim", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,tm_lim), 0, "mip.tm_lim (milliseconds) "}, |
| + {"out_frq", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,out_frq), 0, "mip.out_frq (milliseconds) "}, |
| + {"out_dly", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,out_dly), 0, "mip.out_dly (milliseconds) "}, |
| + /*void (*cb_func)(glp_tree *T, void *info); [> mip.cb_func <]*/ |
| + /*void *cb_info; [> mip.cb_info <]*/ |
| + {"cb_size", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,cb_size), 0, "mip.cb_size "}, |
| + {"pp_tech", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,pp_tech), 0, "preprocessing technique: "}, |
| + {"mip_gap", T_DOUBLE, offsetof(pysmcp,obj)+offsetof(glp_iocp,mip_gap), 0, "relative MIP gap tolerance "}, |
| + {"mir_cuts", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,mir_cuts), 0, "MIR cuts (GLP_ON/GLP_OFF) "}, |
| + {"gmi_cuts", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,gmi_cuts), 0, "Gomory's cuts (GLP_ON/GLP_OFF) "}, |
| + {"cov_cuts", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,cov_cuts), 0, "cover cuts (GLP_ON/GLP_OFF) "}, |
| + {"clq_cuts", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,clq_cuts), 0, "clique cuts (GLP_ON/GLP_OFF) "}, |
| + {"presolve", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,presolve), 0, "enable/disable using MIP presolver "}, |
| + {"binarize", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,binarize), 0, "try to binarize integer variables "}, |
| + {"fp_heur", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,fp_heur), 0, "feasibility pump heuristic "}, |
| + {"ps_heur", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,ps_heur), 0, "proximity search heuristic "}, |
| + {"ps_tm_lim", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,ps_tm_lim), 0, "proxy time limit, milliseconds "}, |
| + {"use_sol", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,use_sol), 0, "use existing solution "}, |
| + {"save_sol",T_STRING,offsetof(pysmcp,obj)+offsetof(glp_iocp,save_sol),0, "filename to save every new solution"}, |
| + {"alien", T_INT, offsetof(pysmcp,obj)+offsetof(glp_iocp,alien), 0, "use alien solver "}, |
| +}; |
| + |
| +static PyTypeObject iocp_t = { |
| + PyVarObject_HEAD_INIT(NULL, 0) |
| + "glpk.iocp", /* tp_name */ |
| + sizeof(pyiocp), /* tp_basicsize */ |
| + 0, /* tp_itemsize */ |
| + (destructor)iocp_dealloc, /* tp_dealloc */ |
| + 0, /* tp_print */ |
| + 0, /* tp_getattr */ |
| + 0, /* tp_setattr */ |
| + 0, /* tp_reserved */ |
| + 0, /* tp_repr */ |
| + 0, /* tp_as_number */ |
| + 0, /* tp_as_sequence */ |
| + 0, /* tp_as_mapping */ |
| + 0, /* tp_hash */ |
| + 0, /* tp_call */ |
| + 0, /* tp_str */ |
| + 0, /* tp_getattro */ |
| + 0, /* tp_setattro */ |
| + 0, /* tp_as_buffer */ |
| + Py_TPFLAGS_DEFAULT | |
| + Py_TPFLAGS_BASETYPE, /* tp_flags */ |
| + "integer optimizer control parameters", /* tp_doc */ |
| + 0, /* tp_traverse */ |
| + 0, /* tp_clear */ |
| + 0, /* tp_richcompare */ |
| + 0, /* tp_weaklistoffset */ |
| + 0, /* tp_iter */ |
| + 0, /* tp_iternext */ |
| + 0, /* tp_methods */ |
| + iocpMembers, /* tp_members */ |
| + 0, /* tp_getset */ |
| + 0, /* tp_base */ |
| + 0, /* tp_dict */ |
| + 0, /* tp_descr_get */ |
| + 0, /* tp_descr_set */ |
| + 0, /* tp_dictoffset */ |
| + (initproc)iocp_init, /* tp_init */ |
| + 0, /* tp_alloc */ |
| + iocp_new, /* tp_new */ |
| +}; |
| + |
| + |
| + |
| +/* Small helper function to generate the output string of the simplex function */ |
| +inline static void set_output_string(PyObject* t,const char s[]) { |
| + PyTuple_SET_ITEM(t, 0, (PyObject *) |
| +#if PY_MAJOR_VERSION >= 3 |
| + PyUnicode_FromString(s)); |
| +#else |
| + PyString_FromString(s)); |
| +#endif |
| + } |
| + |
| |
| static char doc_simplex[] = |
| "Solves a linear program using GLPK.\n\n" |
| @@ -126,21 +322,16 @@ |
| PyObject *kwrds) |
| { |
| 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; |
| - int_t pos=0; |
| + 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 param_type, err_str[100]; |
| -#if PY_MAJOR_VERSION >= 3 |
| - const char *keystr; |
| -#else |
| - char *keystr; |
| -#endif |
| - char *kwlist[] = {"c", "G", "h", "A", "b", NULL}; |
| + char *kwlist[] = {"c", "G", "h", "A", "b","options", NULL}; |
| |
| - if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OO", kwlist, &c, |
| - &G, &h, &A, &b)) return 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) || |
| @@ -182,19 +373,30 @@ |
| 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 = 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<n; i++){ |
| - lpx_set_obj_coef(lp, i+1, MAT_BUFD(c)[i]); |
| - lpx_set_col_bnds(lp, i+1, LPX_FR, 0.0, 0.0); |
| + 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++) |
| - lpx_set_row_bnds(lp, i+1, LPX_UP, 0.0, MAT_BUFD(h)[i]); |
| + glp_set_row_bnds(lp, i+1, GLP_UP, 0.0, MAT_BUFD(h)[i]); |
| for (i=0; i<p; i++) |
| - lpx_set_row_bnds(lp, i+m+1, LPX_FX, MAT_BUFD(b)[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 ) + |
| @@ -203,7 +405,7 @@ |
| rn = (int *) calloc(nnzmax+1, sizeof(int)); |
| cn = (int *) calloc(nnzmax+1, sizeof(int)); |
| if (!a || !rn || !cn){ |
| - free(a); free(rn); free(cn); lpx_delete_prob(lp); |
| + free(a); free(rn); free(cn); glp_delete_prob(lp); |
| return PyErr_NoMemory(); |
| } |
| |
| @@ -242,84 +444,18 @@ |
| nnz++; |
| } |
| |
| - lpx_load_matrix(lp, nnz, rn, cn, a); |
| + glp_load_matrix(lp, nnz, rn, cn, a); |
| free(rn); free(cn); free(a); |
| |
| if (!(t = PyTuple_New(A ? 4 : 3))){ |
| - lpx_delete_prob(lp); |
| + glp_delete_prob(lp); |
| return PyErr_NoMemory(); |
| } |
| |
| - if (!(param = PyObject_GetAttrString(glpk_module, "options")) |
| - || !PyDict_Check(param)){ |
| - lpx_delete_prob(lp); |
| - PyErr_SetString(PyExc_AttributeError, |
| - "missing glpk.options dictionary"); |
| - return NULL; |
| - } |
| - |
| - while (PyDict_Next(param, &pos, &key, &value)) |
| -#if PY_MAJOR_VERSION >= 3 |
| - if ((PyUnicode_Check(key)) && |
| - get_param_idx(_PyUnicode_AsString(key), ¶m_id, |
| - ¶m_type)){ |
| - 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){ |
| -#endif |
| - PyErr_Warn(PyExc_UserWarning, "ignoring value of " |
| - "GLPK parameter 'LPX_K_PRESOL'"); |
| - } |
| - 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)); |
| - } |
| - } |
| - lpx_set_int_parm(lp, LPX_K_PRESOL, 1); |
| - Py_DECREF(param); |
| |
| - switch (lpx_simplex(lp)){ |
| + switch (glp_simplex(lp,options)){ |
| |
| - case LPX_E_OK: |
| + case 0: |
| |
| x = (matrix *) Matrix_New(n,1,DOUBLE); |
| z = (matrix *) Matrix_New(m,1,DOUBLE); |
| @@ -329,65 +465,70 @@ |
| Py_XDECREF(z); |
| Py_XDECREF(y); |
| Py_XDECREF(t); |
| - lpx_delete_prob(lp); |
| + Py_XDECREF(smcpParm); |
| + 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 |
| + set_output_string(t,"optimal"); |
| |
| for (i=0; i<n; i++) |
| - MAT_BUFD(x)[i] = lpx_get_col_prim(lp, i+1); |
| + 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] = -lpx_get_row_dual(lp, i+1); |
| + 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] = -lpx_get_row_dual(lp, m+i+1); |
| + MAT_BUFD(y)[i] = -glp_get_row_dual(lp, m+i+1); |
| PyTuple_SET_ITEM(t, 3, (PyObject *) y); |
| } |
| |
| - lpx_delete_prob(lp); |
| + Py_XDECREF(smcpParm); |
| + glp_delete_prob(lp); |
| return (PyObject *) t; |
| - |
| - case LPX_E_NOPFS: |
| - |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("primal infeasible")); |
| -#else |
| - PyString_FromString("primal infeasible")); |
| -#endif |
| + case GLP_EBADB: |
| + set_output_string(t,"incorrect initial basis"); |
| break; |
| - |
| - case LPX_E_NODFS: |
| - |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("dual infeasible")); |
| -#else |
| - PyString_FromString("dual infeasible")); |
| -#endif |
| + 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: |
| - |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("unknown")); |
| -#else |
| - PyString_FromString("unknown")); |
| -#endif |
| + set_output_string(t,"unknown"); |
| + break; |
| } |
| |
| - lpx_delete_prob(lp); |
| + Py_XDECREF(smcpParm); |
| + glp_delete_prob(lp); |
| |
| PyTuple_SET_ITEM(t, 1, Py_BuildValue("")); |
| PyTuple_SET_ITEM(t, 2, Py_BuildValue("")); |
| @@ -427,21 +568,28 @@ |
| { |
| 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; |
| - int_t pos=0; |
| + 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 param_type, err_str[100]; |
| -#if PY_MAJOR_VERSION >= 3 |
| - const char *keystr; |
| -#else |
| - char *keystr; |
| -#endif |
| - char *kwlist[] = {"c", "G", "h", "A", "b", "I", "B", NULL}; |
| + 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 (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OOOO", kwlist, &c, |
| - &G, &h, &A, &b, &IntSet, &BinSet)) 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) || |
| @@ -490,18 +638,18 @@ |
| 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<n; i++){ |
| - lpx_set_obj_coef(lp, i+1, MAT_BUFD(c)[i]); |
| - lpx_set_col_bnds(lp, i+1, LPX_FR, 0.0, 0.0); |
| + 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++) |
| - lpx_set_row_bnds(lp, i+1, LPX_UP, 0.0, MAT_BUFD(h)[i]); |
| + glp_set_row_bnds(lp, i+1, GLP_UP, 0.0, MAT_BUFD(h)[i]); |
| for (i=0; i<p; i++) |
| - lpx_set_row_bnds(lp, i+m+1, LPX_FX, MAT_BUFD(b)[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 ) + |
| @@ -510,7 +658,7 @@ |
| rn = (int *) calloc(nnzmax+1, sizeof(int)); |
| cn = (int *) calloc(nnzmax+1, sizeof(int)); |
| if (!a || !rn || !cn){ |
| - free(a); free(rn); free(cn); lpx_delete_prob(lp); |
| + free(a); free(rn); free(cn); glp_delete_prob(lp); |
| return PyErr_NoMemory(); |
| } |
| |
| @@ -549,79 +697,14 @@ |
| nnz++; |
| } |
| |
| - lpx_load_matrix(lp, nnz, rn, cn, a); |
| + glp_load_matrix(lp, nnz, rn, cn, a); |
| free(rn); free(cn); free(a); |
| |
| if (!(t = PyTuple_New(2))) { |
| - lpx_delete_prob(lp); |
| + glp_delete_prob(lp); |
| return PyErr_NoMemory(); |
| } |
| |
| - if (!(param = PyObject_GetAttrString(glpk_module, "options")) |
| - || !PyDict_Check(param)){ |
| - lpx_delete_prob(lp); |
| - PyErr_SetString(PyExc_AttributeError, |
| - "missing glpk.options dictionary"); |
| - return NULL; |
| - } |
| - |
| - while (PyDict_Next(param, &pos, &key, &value)) |
| -#if PY_MAJOR_VERSION >= 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) && |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyLong_AS_LONG(value) != 1){ |
| -#else |
| - PyInt_AS_LONG(value) != 1){ |
| -#endif |
| - PyErr_Warn(PyExc_UserWarning, "ignoring value of " |
| - "GLPK parameter 'LPX_K_PRESOL'"); |
| - } |
| - 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)); |
| - } |
| - } |
| - lpx_set_int_parm(lp, LPX_K_PRESOL, 1); |
| - Py_DECREF(param); |
| - |
| if (IntSet) { |
| PyObject *iter = PySequence_Fast(IntSet, "Critical error: not sequence"); |
| |
| @@ -633,7 +716,7 @@ |
| #else |
| if (!PyInt_Check(tmp)) { |
| #endif |
| - lpx_delete_prob(lp); |
| + glp_delete_prob(lp); |
| Py_DECREF(iter); |
| PY_ERR_TYPE("non-integer element in I"); |
| } |
| @@ -643,7 +726,7 @@ |
| int k = PyInt_AS_LONG(tmp); |
| #endif |
| 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"); |
| } |
| @@ -664,7 +747,7 @@ |
| #else |
| if (!PyInt_Check(tmp)) { |
| #endif |
| - lpx_delete_prob(lp); |
| + glp_delete_prob(lp); |
| Py_DECREF(iter); |
| PY_ERR_TYPE("non-binary element in I"); |
| } |
| @@ -674,7 +757,7 @@ |
| int k = PyInt_AS_LONG(tmp); |
| #endif |
| 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,114 +769,85 @@ |
| } |
| |
| |
| + switch (glp_intopt(lp,options)){ |
| |
| - switch (lpx_intopt(lp)){ |
| + case 0: |
| |
| - case LPX_E_OK: |
| + 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"); |
| |
| - x = (matrix *) Matrix_New(n,1,DOUBLE); |
| - if (!x) { |
| - Py_XDECREF(t); |
| - lpx_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 |
| + for (i=0; i<n; i++) |
| + MAT_BUFD(x)[i] = glp_mip_col_val(lp, i+1); |
| + PyTuple_SET_ITEM(t, 1, (PyObject *) x); |
| |
| - for (i=0; i<n; i++) |
| - MAT_BUFD(x)[i] = lpx_mip_col_val(lp, i+1); |
| - PyTuple_SET_ITEM(t, 1, (PyObject *) x); |
| + Py_XDECREF(iocpParm); |
| + glp_delete_prob(lp); |
| + return (PyObject *) t; |
| |
| - lpx_delete_prob(lp); |
| - return (PyObject *) t; |
| + case GLP_ETMLIM: |
| |
| - case LPX_E_TMLIM: |
| + 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"); |
| |
| - x = (matrix *) Matrix_New(n,1,DOUBLE); |
| - if (!x) { |
| - Py_XDECREF(t); |
| - lpx_delete_prob(lp); |
| - return PyErr_NoMemory(); |
| - } |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("time limit exceeded")); |
| -#else |
| - PyString_FromString("time limit exceeded")); |
| -#endif |
| + for (i=0; i<n; i++) |
| + MAT_BUFD(x)[i] = glp_mip_col_val(lp, i+1); |
| + PyTuple_SET_ITEM(t, 1, (PyObject *) x); |
| |
| - for (i=0; i<n; i++) |
| - MAT_BUFD(x)[i] = lpx_mip_col_val(lp, i+1); |
| - PyTuple_SET_ITEM(t, 1, (PyObject *) x); |
| - |
| - lpx_delete_prob(lp); |
| - return (PyObject *) t; |
| + Py_XDECREF(iocpParm); |
| + glp_delete_prob(lp); |
| + return (PyObject *) t; |
| |
| |
| - case LPX_E_FAULT: |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("invalid MIP formulation")); |
| -#else |
| - PyString_FromString("invalid MIP formulation")); |
| -#endif |
| - break; |
| + case GLP_EBOUND: |
| + set_output_string(t,"incorrect bounds"); |
| + break; |
| + case GLP_EFAIL: |
| + set_output_string(t,"invalid MIP formulation"); |
| + break; |
| |
| - case LPX_E_NOPFS: |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("primal infeasible")); |
| -#else |
| - PyString_FromString("primal infeasible")); |
| -#endif |
| - break; |
| + case GLP_ENOPFS: |
| + set_output_string(t,"primal infeasible"); |
| + break; |
| |
| - case LPX_E_NODFS: |
| + case GLP_ENODFS: |
| + set_output_string(t,"dual infeasible"); |
| + break; |
| |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("dual infeasible")); |
| -#else |
| - PyString_FromString("dual infeasible")); |
| -#endif |
| - break; |
| + case GLP_EMIPGAP: |
| + set_output_string(t,"Relative mip gap tolerance reached"); |
| + break; |
| |
| - case LPX_E_ITLIM: |
| + /*case LPX_E_ITLIM: |
| |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("maxiters exceeded")); |
| -#else |
| - PyString_FromString("maxiters exceeded")); |
| -#endif |
| - break; |
| + set_output_string(t,"maxiters exceeded"); |
| + break;*/ |
| |
| - case LPX_E_SING: |
| + /*case LPX_E_SING: |
| |
| - 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 |
| - break; |
| + set_output_string(t,"singular or ill-conditioned basis"); |
| + break;*/ |
| |
| |
| - default: |
| + default: |
| |
| - PyTuple_SET_ITEM(t, 0, (PyObject *) |
| -#if PY_MAJOR_VERSION >= 3 |
| - PyUnicode_FromString("unknown")); |
| -#else |
| - PyString_FromString("unknown")); |
| -#endif |
| - } |
| + set_output_string(t,"unknown"); |
| + } |
| |
| - lpx_delete_prob(lp); |
| + Py_XDECREF(iocpParm); |
| + glp_delete_prob(lp); |
| |
| PyTuple_SET_ITEM(t, 1, Py_BuildValue("")); |
| return (PyObject *) t; |
| @@ -819,10 +873,94 @@ |
| 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; |
| - PyModule_AddObject(glpk_module, "options", PyDict_New()); |
| + 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; |
| } |
| @@ -832,8 +970,13 @@ |
| PyMODINIT_FUNC initglpk(void) |
| { |
| glpk_module = Py_InitModule3("cvxopt.glpk", glpk_functions, |
| - glpk__doc__); |
| - PyModule_AddObject(glpk_module, "options", PyDict_New()); |
| + 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; |
| } |
| |