Ticket #7804: trac_7804.patch

File trac_7804.patch, 24.3 KB (added by ncohen, 11 years ago)
  • module_list.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1262350630 28800
    # Node ID 92c22dd90fbf6ac42d7458644620d61bd71f991a
    # Parent  6b537b8b44c72cd792c7da0bbc90db304ee2bbd9
    numerical.mipCoin and numerical.mipGlpk in standard Sage, compiled only if possible
    
    diff -r 6b537b8b44c7 -r 92c22dd90fbf module_list.py
    a b  
    632632              libraries = ["csage", "ntl", "gmp", "gmpxx", "m", "stdc++"],
    633633              language='c++'),
    634634
    635 
    636 
    637635    ################################
    638636    ##
    639637    ## sage.matrix
     
    14031401              depends = [SAGE_ROOT + "/local/include/pynac/ginac.h"],
    14041402              libraries = ["pynac"]),
    14051403
    1406    
    1407 
    1408    
    14091404    ]
    14101405
     1406# Optional extensions :
     1407# These extensions are to be compiled only if the
     1408# corresponding packages have been installed
     1409
     1410from sage.misc.package import is_package_installed
     1411
     1412if is_package_installed('glpk'):
     1413    ext_modules.append(
     1414        Extension("sage.numerical.mip_glpk",
     1415                  ["sage/numerical/mip_glpk.pyx"],
     1416                  include_dirs = [SAGE_ROOT+"/local/include/", "sage/c_lib/include/"],
     1417                  language = 'c++',
     1418                  libraries=["csage", "stdc++", "glpk"])
     1419        )
     1420
     1421if is_package_installed('cbc'):
     1422    ext_modules.append(
     1423        Extension("sage.numerical.mip_coin",
     1424                  ["sage/numerical/mip_coin.pyx"],
     1425                  include_dirs = [SAGE_ROOT+"/local/include/","sage/c_lib/include/"],
     1426                  language = 'c++',
     1427                  libraries = ["csage", "stdc++", "Cbc", "CbcSolver", "Cgl", "Clp", "CoinUtils", "OsiCbc", "OsiClp", "Osi", "OsiVol", "Vol"])
     1428        )
     1429   
    14111430
    14121431# Only include darwin_utilities on OS_X >= 10.5
    14131432UNAME = os.uname()
  • sage/numerical/mip.pyx

    diff -r 6b537b8b44c7 -r 92c22dd90fbf sage/numerical/mip.pyx
    a b  
    6161            sage: p = MixedIntegerLinearProgram(maximization=True)
    6262        """
    6363        try:
    64             from sage.numerical.mipCoin import solveCoin
     64            from sage.numerical.mip_coin import solve_coin
    6565            self._default_solver = "Coin"
    6666        except:
    6767            try:
    68                 from sage.numerical.mipGlpk import solve_glpk
     68                from sage.numerical.mip_glpk import solve_glpk
    6969                self._default_solver = "GLPK"
    7070            except:
    7171                self._default_solver = None
     
    438438        """
    439439       
    440440        try:
    441             from sage.numerical.mipGlpk import write_mps
     441            from sage.numerical.mip_glpk import write_mps
    442442        except:
    443443            raise NotImplementedError("You need GLPK installed to use this function. To install it, you can type in Sage: install_package('glpk')")
    444444
     
    469469        http://lpsolve.sourceforge.net/5.5/lp-format.htm
    470470        """
    471471        try:
    472             from sage.numerical.mipGlpk import write_lp
     472            from sage.numerical.mip_glpk import write_lp
    473473        except:
    474474            raise NotImplementedError("You need GLPK installed to use this function. To install it, you can type in Sage: install_package('glpk')")
    475475
     
    959959            sage: p.solve(solver='GLPK', objective_only=True) # optional - requires GLPK
    960960            Traceback (most recent call last):
    961961            ...
    962             NotImplementedError: ...
     962            RuntimeError
    963963        """
    964964        if self._objective_i == None:
    965965            raise ValueError("No objective function has been defined.")
     
    971971            raise ValueError("There does not seem to be any solver installed. Please visit http://www.sagemath.org/doc/tutorial/tour_LP.html for more informations.")
    972972        elif solver == "Coin":
    973973            try:
    974                 from sage.numerical.mipCoin import solveCoin
     974                from sage.numerical.mip_coin import solve_coin
    975975            except:
    976976                raise NotImplementedError("Coin/CBC is not installed and cannot be used to solve this MixedIntegerLinearProgram. To install it, you can type in Sage: install_package('cbc')")
    977977            _sig_on
    978             r = solveCoin(self, log=log, objective_only=objective_only)
     978            r = solve_coin(self, log=log, objective_only=objective_only)
    979979            _sig_off
    980980            return r
    981981        elif solver == "GLPK":
    982982            try:
    983                 from sage.numerical.mipGlpk import solve_glpk
     983                from sage.numerical.mip_glpk import solve_glpk
    984984            except:
    985985                raise NotImplementedError("GLPK is not installed and cannot be used to solve this MixedIntegerLinearProgram. To install it, you can type in Sage: install_package('glpk')")
    986986            _sig_on
  • new file sage/numerical/mip_coin.pxd

    diff -r 6b537b8b44c7 -r 92c22dd90fbf sage/numerical/mip_coin.pxd
    - +  
     1cdef extern from *:
     2    ctypedef double* const_double_ptr "const double*"
     3
     4cdef extern from "../../local/include/coin/CoinPackedVector.hpp":
     5     ctypedef struct c_CoinPackedVector "CoinPackedVector":
     6         void insert(float, float)
     7     c_CoinPackedVector *new_c_CoinPackedVector "new CoinPackedVector" ()
     8     void del_CoinPackedVector "delete" (c_CoinPackedVector *)
     9cdef extern from "../../local/include/coin/CoinPackedMatrix.hpp":
     10     ctypedef struct c_CoinPackedMatrix "CoinPackedMatrix":
     11         void setDimensions(int, int)
     12         void appendRow(c_CoinPackedVector)
     13     c_CoinPackedMatrix *new_c_CoinPackedMatrix "new CoinPackedMatrix" (bool, double, double)
     14     void del_CoinPackedMatrix "delete" (c_CoinPackedMatrix *)
     15
     16cdef extern from "../../local/include/coin/CoinMessageHandler.hpp":
     17     ctypedef struct c_CoinMessageHandler "CoinMessageHandler":
     18         void setLogLevel (int)
     19     c_CoinMessageHandler *new_c_CoinMessageHandler "new CoinMessageHandler" ()
     20     void del_CoinMessageHandler "delete" (c_CoinMessageHandler *)
     21
     22
     23cdef extern from "../../local/include/coin/CbcModel.hpp":
     24     ctypedef struct c_CbcModel "CbcModel":
     25         c_CoinMessageHandler * messageHandler ()
     26         void setNumberThreads (int)
     27         int getSolutionCount()
     28
     29     c_CbcModel *new_c_CbcModel "new CbcModel" ()
     30     void del_CbcModel "delete" (c_CbcModel *)
     31
     32cdef extern from "../../local/include/coin/OsiCbcSolverInterface.hpp":
     33     ctypedef struct c_OsiCbcSolverInterface "OsiCbcSolverInterface":
     34         double getInfinity()
     35         void loadProblem(c_CoinPackedMatrix, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr)
     36         void assignProblem(c_CoinPackedMatrix *, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr)
     37         void writeMps(char *, char *, double)
     38         void initialSolve()
     39         void branchAndBound()
     40         void readMps(string)
     41         float getObjValue()
     42         double * getColSolution()
     43         void setObjSense (double )
     44         void setLogLevel(int)
     45         void setInteger(int)
     46         void setContinuous(int)
     47         c_CoinMessageHandler * messageHandler ()
     48         c_CbcModel * getModelPtr  ()
     49         int isAbandoned ()
     50         int isProvenOptimal ()
     51         int isProvenPrimalInfeasible ()
     52         int isProvenDualInfeasible ()
     53         int isPrimalObjectiveLimitReached ()
     54         int isDualObjectiveLimitReached ()
     55         int isIterationLimitReached ()
     56         void setMaximumSolutions(int)
     57         int getMaximumSolutions()
     58     c_OsiCbcSolverInterface *new_c_OsiCbcSolverInterface "new OsiCbcSolverInterface" ()
     59     void del_OsiCbcSolverInterface "delete" (c_OsiCbcSolverInterface *)
  • new file sage/numerical/mip_coin.pyx

    diff -r 6b537b8b44c7 -r 92c22dd90fbf sage/numerical/mip_coin.pyx
    - +  
     1include 'mip_coin.pxd'
     2include '../../../../devel/sage/sage/ext/stdsage.pxi'
     3
     4cdef int BINARY = 1
     5cdef int REAL = -1
     6cdef int INTEGER = 0
     7
     8
     9def solve_coin(self,log=False,objective_only=False):
     10    r"""
     11    Solves the MIP using COIN-OR CBC/CLP
     12    """
     13
     14    from itertools import izip
     15
     16    # Creates the solver interfaces
     17    cdef c_OsiCbcSolverInterface* si
     18    si = new_c_OsiCbcSolverInterface();
     19
     20    n_cols = len(self._variables_type);
     21
     22    # Definition of the objective function
     23    cdef double * objective = <double*> sage_malloc(n_cols*sizeof(double))
     24
     25    # a hand-made memset
     26    for 0<= i < n_cols:
     27        objective[i] = 0
     28
     29    for (i,v) in izip(self._objective_i,self._objective_values):
     30        objective[i]=float(v)
     31
     32
     33    # Upper and lower bounds on the variables
     34    cdef double * col_lb = <double*> sage_malloc(n_cols*sizeof(double))
     35    cdef double * col_ub = <double*> sage_malloc(n_cols*sizeof(double))
     36
     37
     38    cdef int id
     39    id=0
     40
     41    for (type,min,max) in izip(self._variables_type,self._variables_bounds_min,self._variables_bounds_max):
     42        if type == BINARY:
     43            col_lb[id] = 0.0
     44            col_ub[id] = 1.0
     45        else:
     46            if min == None:
     47                col_lb[id] = -1.0*si.getInfinity();
     48            else:
     49                col_lb[id] = float(min)
     50
     51            if max == None:
     52                col_ub[id] = 1.0*si.getInfinity();
     53            else:
     54                col_ub[id] = float(max)
     55        id+=1
     56
     57
     58    # Definition of the problem matrix
     59    n_rows = len(self._constraints_bounds_min);
     60    cdef c_CoinPackedMatrix * matrix
     61    matrix = new_c_CoinPackedMatrix(False, 0, 0);
     62    matrix.setDimensions(0, n_cols);
     63
     64
     65    # Upper and lower bounds on the constraints
     66    cdef double * row_lb = <double*> sage_malloc(n_rows*sizeof(double))
     67    cdef double * row_ub = <double*> sage_malloc(n_rows*sizeof(double))
     68
     69    # The constraint to be added
     70    cdef c_CoinPackedVector* row
     71
     72    cdef int a
     73    a = 0
     74
     75    for (min,max) in izip(self._constraints_bounds_min,self._constraints_bounds_max):
     76        if min == None:
     77            row_lb[a] = -1.0*si.getInfinity();
     78        else:
     79            row_lb[a] = float(min)
     80
     81        if max == None:
     82            row_ub[a] = 1.0*si.getInfinity();
     83        else:
     84            row_ub[a] = float(max)
     85        a += 1
     86
     87    cdef int last
     88    last = 0;
     89    row = new_c_CoinPackedVector()
     90
     91    for (i,j,v) in izip (self._constraints_matrix_i,self._constraints_matrix_j,self._constraints_matrix_values):
     92        if i != last:
     93            matrix.appendRow(row[0]);
     94            row = new_c_CoinPackedVector();
     95            last = i
     96        row.insert(j, float(v))
     97
     98    matrix.appendRow(row[0]);
     99
     100    # Direction of the problem : maximization, minimization...
     101    if self._maximization == False:
     102        si.setObjSense(1.0)
     103    else:
     104        si.setObjSense(-1.0)
     105
     106    # stuff related to the loglevel
     107    cdef c_CoinMessageHandler * msg
     108    cdef c_CbcModel * model
     109    model = si.getModelPtr()
     110    msg = model.messageHandler()
     111    msg.setLogLevel(log if False != log else log)
     112
     113    si.assignProblem(matrix, col_lb, col_ub, objective, row_lb, row_ub);
     114
     115    # Sets variables as integers when needed
     116    id = 0;
     117    for type in self._variables_type:
     118        if type == REAL:
     119            si.setContinuous(id)
     120        else:
     121            si.setInteger(id)
     122        id += 1
     123
     124    # Has there been any problem during the computations ?
     125    flag = True
     126
     127    # Solves the MIP
     128    si.branchAndBound();
     129
     130    cdef const_double_ptr solution
     131
     132    if si.isAbandoned():
     133        flag = True
     134        exception_txt = "Coin Branch and Cut: The solver has abandoned!"
     135    elif si.isProvenPrimalInfeasible() or si.isProvenDualInfeasible():
     136        flag = True
     137        exception_txt="Coin Branch and Cut: The problem or its dual has been proven infeasible!"
     138    elif si.isPrimalObjectiveLimitReached() or si.isDualObjectiveLimitReached():
     139        flag = True
     140        exception_txt = "Coin Branch and Cut: The objective limit has been reached for the problem or its dual!"
     141    elif si.isIterationLimitReached():
     142        flag = True
     143        exception_txt = "Coin Branch and Cut: The iteration limit has been reached!"
     144    elif si.isProvenOptimal() == True:
     145        flag = False
     146        return_value = si.getObjValue();
     147        if objective_only == False:
     148            solution = si.getColSolution();
     149
     150            # Builds the returned dictionary of values
     151            for ((v,id),type) in izip(self._variables.iteritems(),self._variables_type):
     152                self._values[v] = solution[id] if type == REAL else round(solution[id])
     153
     154
     155    del_OsiCbcSolverInterface(si)
     156    sage_free(objective)
     157    sage_free(col_lb)
     158    sage_free(col_ub)
     159    sage_free(row_lb)
     160    sage_free(row_ub)
     161    del_CoinPackedMatrix(matrix)
     162
     163    if flag:
     164        from sage.numerical.mip import MIPSolverException
     165        raise MIPSolverException(exception_txt)
     166    return return_value
  • new file sage/numerical/mip_glpk.pxd

    diff -r 6b537b8b44c7 -r 92c22dd90fbf sage/numerical/mip_glpk.pxd
    - +  
     1cdef extern from *:
     2    ctypedef double* const_double_ptr "const double*"
     3
     4cdef extern from "../../local/include/glpk.h":
     5     ctypedef struct c_glp_prob "glp_prob":
     6         pass
     7     ctypedef struct c_glp_iocp "glp_iocp":
     8         int presolve
     9         int msg_lev
     10     c_glp_iocp *new_c_glp_iocp "new glp_iocp" ()
     11     void glp_init_iocp(c_glp_iocp *)
     12     c_glp_prob * glp_create_prob()
     13     void glp_set_prob_name(c_glp_prob *, char *)
     14     void glp_set_obj_dir(c_glp_prob *, int)
     15     void glp_add_rows(c_glp_prob *, int)
     16     void glp_add_cols(c_glp_prob *, int)
     17     void glp_set_row_name(c_glp_prob *, int, char *)
     18     void glp_set_col_name(c_glp_prob *, int, char *)
     19     void glp_set_row_bnds(c_glp_prob *, int, int, double, double)
     20     void glp_set_col_bnds(c_glp_prob *, int, int, double, double)
     21     void glp_set_obj_coef(c_glp_prob *, int, double)
     22     void glp_load_matrix(c_glp_prob *, int, int *, int *, double *)
     23     void glp_simplex(c_glp_prob *, int)
     24     void glp_intopt(c_glp_prob *, c_glp_iocp *)
     25     int lpx_intopt(c_glp_prob *)
     26     void glp_delete_prob(c_glp_prob *)
     27     double glp_get_col_prim(c_glp_prob *, int)
     28     double glp_get_obj_val(c_glp_prob *)
     29     double glp_mip_col_val(c_glp_prob *, int)
     30     double glp_mip_obj_val(c_glp_prob *)
     31     void glp_set_col_kind(c_glp_prob *, int, int)
     32     int glp_write_mps(c_glp_prob *lp, int fmt, void *parm, char *fname)
     33     int glp_write_lp(c_glp_prob *lp, void *parm, char *fname)
     34     void glp_set_prob_name(c_glp_prob *lp, char *name)
     35     void glp_set_obj_name(c_glp_prob *lp, char *name)
     36     void glp_set_row_name(c_glp_prob *lp, int i, char *name)
     37     void glp_set_col_name(c_glp_prob *lp, int i, char *name)
     38     int glp_mip_status(c_glp_prob *lp)
     39
     40     int GLP_ON
     41     int GLP_MAX
     42     int GLP_MIN
     43     int GLP_UP
     44     int GLP_FR
     45     int GLP_DB
     46     int GLP_FX
     47     int GLP_LO
     48     int GLP_CV
     49     int GLP_IV
     50     int GLP_BV
     51     int GLP_MSG_OFF
     52     int GLP_MSG_ERR
     53     int GLP_MSG_ON
     54     int GLP_MSG_ALL
     55     int GLP_MPS_DECK
     56     int GLP_MPS_FILE
     57
     58     int GLP_UNDEF
     59     int GLP_OPT
     60     int GLP_FEAS
     61     int GLP_NOFEAS
  • new file sage/numerical/mip_glpk.pyx

    diff -r 6b537b8b44c7 -r 92c22dd90fbf sage/numerical/mip_glpk.pyx
    - +  
     1"""
     2AUTHOR:
     3
     4- Nathan Cohen (2009): initial version
     5"""
     6
     7include 'mip_glpk.pxd'
     8include '../../../../devel/sage/sage/ext/stdsage.pxi'
     9
     10cdef int BINARY = 1
     11cdef int REAL = -1
     12cdef int INTEGER = 0
     13
     14def solve_glpk(self, log=0, objective_only=False):
     15    """
     16    Solves the ``MixedIntegerLinearProgram`` using GLPK.
     17    Use ``solve()`` instead.
     18
     19    INPUT:
     20   
     21    - ``log`` (integer) -- level of verbosity during the
     22      solving process. Set ``log=3`` for maximal verbosity and
     23      ``log=0`` for no verbosity at all.
     24
     25    - ``objective_only`` (boolean) -- Indicates whether the
     26      values corresponding to an optimal assignment of the
     27      variables should be computed. Setting ``objective_only``
     28      to ``True`` saves some time on the computation when
     29      this information is not needed.
     30
     31    OUTPUT:
     32
     33    This function returns the optimal value of the objective
     34    function given by GLPK.
     35    """
     36
     37    # Raises an exception if no objective has been defined
     38    if self._objective_i is None:
     39        raise ValueError("No objective function has been defined!")
     40
     41    # Creates the structures
     42    cdef c_glp_prob * lp = glp_create_prob()
     43    cdef c_glp_iocp * iocp = new_c_glp_iocp()
     44    glp_init_iocp(iocp)
     45   
     46    # Builds the GLPK version of the problem
     47    build_glp_prob(lp, iocp, self,log, False)
     48
     49    # Solves the problem
     50    glp_intopt(lp, iocp)
     51   
     52    cdef int status = glp_mip_status(lp)
     53    if status == GLP_UNDEF:
     54        glp_delete_prob(lp)
     55        from sage.numerical.mip import MIPSolverException
     56        raise MIPSolverException("GLPK : Solution is undefined")
     57
     58    elif status == GLP_OPT:
     59        # Everything is fine !
     60        obj = glp_mip_obj_val(lp)
     61
     62        # If the users is interested in the variables' value
     63        # fills self._values
     64        if objective_only == False:
     65            for (v, id) in self._variables.items():
     66                self._values[v] = glp_mip_col_val(lp, id+1) if self._variables_type[id]==REAL else round(glp_mip_col_val(lp, id+1))
     67
     68        glp_delete_prob(lp)
     69        return obj
     70
     71    elif status == GLP_FEAS:
     72        glp_delete_prob(lp)
     73        from sage.numerical.mip import MIPSolverException
     74        raise MIPSolverException("GLPK : Feasible solution found, while optimality has not been proven")
     75
     76    elif status == GLP_NOFEAS:
     77        glp_delete_prob(lp)
     78        from sage.numerical.mip import MIPSolverException
     79        raise MIPSolverException("GLPK : There is no feasible integer solution to this Linear Program")
     80
     81    else:
     82        glp_delete_prob(lp)
     83        raise ValueError("The value returned by the solver is unknown!")
     84
     85def write_mps(self, filename,modern=True):
     86    """
     87    Write the linear program as a MPS file.
     88   
     89    INPUT:
     90   
     91    - ``filename`` -- The file in which you want the problem
     92      to be written.
     93    - ``modern`` -- Lets you choose between Fixed MPS and Free MPS
     94        - ``True`` -- Writes the problem in Free MPS
     95        - ``False`` -- Writes the problem in Fixed MPS
     96   
     97    OUTPUT:
     98
     99    This function has no output.
     100
     101    For information about the MPS file format :
     102    http://en.wikipedia.org/wiki/MPS_%28format%29
     103    """
     104
     105    # Raises an exception if no objective has been defined
     106    if self._objective_i is None:
     107        raise ValueError("No objective function has been defined!")
     108
     109    # Creates the structures
     110    cdef c_glp_prob * lp = glp_create_prob()
     111    cdef c_glp_iocp * iocp = new_c_glp_iocp()
     112    glp_init_iocp(iocp)
     113
     114    # Builds the GLPK version of the problem
     115    build_glp_prob(lp, iocp, self, False, True)
     116
     117    if modern:
     118        glp_write_mps(lp, GLP_MPS_FILE, NULL, filename)
     119    else:
     120        glp_write_mps(lp, GLP_MPS_DECK, NULL, filename)
     121
     122def write_lp(self, filename):
     123    """
     124    Write the linear program as a MPS file.
     125   
     126    INPUT:
     127   
     128    - ``filename`` -- The file in which you want the problem
     129      to be written.
     130
     131    OUTPUT:
     132
     133    This function has no output.
     134
     135    For more information about the LP file format :
     136    http://lpsolve.sourceforge.net/5.5/lp-format.htm
     137    """
     138
     139    # Raises an exception if no objective has been defined
     140    if self._objective_i is None:
     141        raise ValueError("No objective function has been defined!")
     142
     143    # Creates the structures
     144    cdef c_glp_prob * lp = glp_create_prob()
     145    cdef c_glp_iocp * iocp = new_c_glp_iocp()
     146    glp_init_iocp(iocp)
     147
     148    # Builds the GLPK version of the problem
     149    build_glp_prob(lp, iocp, self,False,True)
     150
     151    glp_write_lp(lp,NULL,filename)
     152
     153cdef int build_glp_prob(c_glp_prob * lp, c_glp_iocp * iocp, LP, int log, bool names) except -1:
     154    """
     155    Builds the GLPK structure corresponding to the LP
     156
     157    INPUT:
     158
     159    - ``lp`` -- the ``c_glp_prob`` structure to be filled
     160    - ``iocp`` -- the ``c_glp_iocp`` structure to be filled
     161    - ``LP`` -- The data defining the LP
     162    - ``log`` -- integer indicating the level of verbosity
     163    - ``names`` -- should the names ( both variables and constraints ) be included
     164      in the problem ? ( only useful when the problem is to be written in a file )
     165    """
     166    glp_add_rows(lp, len(LP._constraints_bounds_max))
     167    glp_add_cols(lp, len(LP._variables_bounds_min))
     168
     169    cdef int * c_matrix_i = <int*> sage_malloc((len(LP._constraints_matrix_i)+1)*sizeof(int))
     170    cdef int * c_matrix_j = <int*> sage_malloc((len(LP._constraints_matrix_j)+1)*sizeof(int))
     171    cdef double * c_matrix_values = <double*> sage_malloc((len(LP._constraints_matrix_values)+1)*sizeof(double))
     172
     173    # iterator faster than "for 0<= i < len(LP.constraints.matrix.i)" ?
     174
     175    cdef int c
     176    for c,v in enumerate(LP._constraints_matrix_i):
     177        c_matrix_i[c+1]=v+1
     178
     179    for c,v in enumerate(LP._constraints_matrix_j):
     180        c_matrix_j[c+1]=v+1
     181
     182    for c,v in enumerate(LP._constraints_matrix_values):
     183        c_matrix_values[c+1]=v
     184
     185    glp_load_matrix(lp, len(LP._constraints_matrix_i),c_matrix_i,c_matrix_j,c_matrix_values)
     186
     187    cdef int i
     188    for i in range(len(LP._objective_i)):
     189        glp_set_obj_coef(lp, LP._objective_i[i]+1, LP._objective_values[i])
     190       
     191
     192    for i in range(len(LP._variables_bounds_min)):
     193        # Upper and lower bounds on the variables
     194        if LP._variables_bounds_min[i] is not None and LP._variables_bounds_max[i] is not None:
     195            glp_set_col_bnds(lp, i+1, GLP_DB, LP._variables_bounds_min[i], LP._variables_bounds_max[i])
     196
     197        elif LP._variables_bounds_min[i] is None and LP._variables_bounds_max[i] is not None:
     198            glp_set_col_bnds(lp, i+1, GLP_UP, 0, LP._variables_bounds_max[i])
     199
     200        elif LP._variables_bounds_min[i] is not None and LP._variables_bounds_max[i] is None:
     201            glp_set_col_bnds(lp, i+1, GLP_LO, LP._variables_bounds_min[i], 0)
     202
     203        else:
     204            glp_set_col_bnds(lp, i+1, GLP_FR, 0, 0)
     205
     206        # Types
     207        if LP._variables_type[i]==INTEGER:
     208            glp_set_col_kind(lp, i+1, GLP_IV)
     209
     210        elif LP._variables_type[i]==BINARY:
     211            glp_set_col_kind(lp, i+1, GLP_BV)
     212
     213        else:
     214            glp_set_col_kind(lp, i+1, GLP_CV)
     215
     216    for i in range(len(LP._constraints_bounds_max)):
     217        if LP._constraints_bounds_min[i] is not None and LP._constraints_bounds_max[i] is not None:
     218            if LP._constraints_bounds_min[i] == LP._constraints_bounds_max[i]:
     219                glp_set_row_bnds(lp, i+1, GLP_FX, LP._constraints_bounds_min[i], LP._constraints_bounds_max[i])
     220            else:
     221                glp_set_row_bnds(lp, i+1, GLP_DB, LP._constraints_bounds_min[i], LP._constraints_bounds_max[i])
     222
     223        elif LP._constraints_bounds_min[i] is None and LP._constraints_bounds_max[i] is not None:
     224            glp_set_row_bnds(lp, i+1, GLP_UP, 0, LP._constraints_bounds_max[i])
     225
     226        elif LP._constraints_bounds_min[i] is not None and LP._constraints_bounds_max[i] is None:
     227            glp_set_row_bnds(lp, i+1, GLP_LO, LP._constraints_bounds_min[i], 0)
     228
     229        else:
     230            glp_set_row_bnds(lp, i+1, GLP_FR, 0, 0)       
     231
     232    # Direction of the problem : maximization, minimization...
     233    if LP._maximization is False:
     234        glp_set_obj_dir(lp, GLP_MIN)
     235    else:
     236        glp_set_obj_dir(lp, GLP_MAX)
     237
     238    # Writing the names if needed
     239
     240    if names:
     241        if LP._name is not None:
     242            glp_set_prob_name(lp, LP._name)
     243        if LP._objective_name is not None:
     244            glp_set_obj_name(lp, LP._objective_name)
     245
     246        for c,s in enumerate(LP._constraints_name):
     247            if s is not None:
     248                glp_set_row_name(lp,c+1,s)
     249
     250        for c,s in enumerate(LP._variables_name):
     251            if s is not None:
     252                glp_set_col_name(lp,c+1,s)
     253   
     254    iocp.presolve = GLP_ON
     255    # stuff related to the loglevel
     256    if log == 0:
     257        iocp.msg_lev = GLP_MSG_OFF
     258    elif log == 1:
     259        iocp.msg_lev = GLP_MSG_ERR
     260    elif log == 2:
     261        iocp.msg_lev = GLP_MSG_ON
     262    else:
     263        iocp.msg_lev = GLP_MSG_ALL
     264
     265    sage_free(c_matrix_i)
     266    sage_free(c_matrix_j)
     267    sage_free(c_matrix_values)
     268    return 0