Ticket #10043: trac_10043.patch

File trac_10043.patch, 239.0 KB (added by ncohen, 9 years ago)
  • doc/en/reference/numerical.rst

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1285175958 -7200
    # Node ID 0b5f2ba89540c90760c269b99226082ab52b96d7
    # Parent  7ae7b5175304fea5b08c9ee313c372a3936baa1e
    trac 10043 - Complete rewrite of LP solver interfaces
    
    diff -r 7ae7b5175304 -r 0b5f2ba89540 doc/en/reference/numerical.rst
    a b  
    22======================
    33
    44.. toctree::
    5    :maxdepth: 2
     5   :maxdepth: 1
    66
    77   sage/numerical/knapsack
    88   sage/numerical/mip
    99   sage/numerical/optimize
     10
     11LP Solver backends
     12--------------------------
     13
     14.. toctree::
     15   :maxdepth: 1
     16
     17   sage/numerical/backends/generic_backend
     18   sage/numerical/backends/glpk_backend
     19   sage/numerical/backends/coin_backend
     20   sage/numerical/backends/cplex_backend
     21
  • module_list.py

    diff -r 7ae7b5175304 -r 0b5f2ba89540 module_list.py
    a b  
    10221022            include_dirs=["local/include/"],
    10231023            libraries=["csage","stdc++"]),
    10241024
     1025    Extension("sage.numerical.backends.generic_backend",
     1026              ["sage/numerical/backends/generic_backend.pyx"],
     1027              include_dirs = [SAGE_ROOT+"/local/include/", "sage/c_lib/include/"],
     1028              libraries=["csage", "stdc++"]),
     1029
     1030    Extension("sage.numerical.backends.glpk_backend",
     1031              ["sage/numerical/backends/glpk_backend.pyx"],
     1032              include_dirs = [SAGE_ROOT+"/local/include/", "sage/c_lib/include/"],
     1033              language = 'c++',
     1034              libraries=["csage", "stdc++", "glpk", "gmp", "z"]),
    10251035
    10261036    ################################
    10271037    ##
     
    15861596from sage.misc.package import is_package_installed
    15871597
    15881598
    1589 if is_package_installed('glpk'):
     1599if (os.path.isfile(SAGE_ROOT+"/local/include/cplex.h") and                                                                                                                                                                                   
     1600    os.path.isfile(SAGE_ROOT+"/local/lib/libcplex.a")):
    15901601    ext_modules.append(
    1591         Extension("sage.numerical.mip_glpk",
    1592                   ["sage/numerical/mip_glpk.pyx"],
    1593                   include_dirs = [SAGE_ROOT+"/local/include/", "sage/c_lib/include/"],
    1594                   language = 'c++',
    1595                   libraries=["csage", "stdc++", "glpk", "gmp", "z"])
     1602        Extension("sage.numerical.backends.cplex_backend",                                                                                                                                                                                   
     1603                  ["sage/numerical/backends/cplex_backend.pyx"],                                                                                                                                                                             
     1604                  include_dirs = [SAGE_ROOT+"/local/include/","/sage/c_lib/include/"],                                                                                                                                                       
     1605                  language = 'c',                                                                                                                                                                                                             
     1606                  libraries = ["csage", "stdc++", "cplex"])
    15961607        )
    15971608
    15981609if is_package_installed('cbc'):
    1599 
    16001610    ext_modules.append(
    1601         Extension("sage.numerical.osi_interface",
    1602                   ["sage/numerical/osi_interface.pyx"],
     1611        Extension("sage.numerical.backends.coin_backend",                                                                                                                                                                                     
     1612                  ["sage/numerical/backends/coin_backend.pyx"],
    16031613                  include_dirs = [SAGE_ROOT+"/local/include/","sage/c_lib/include/"],
    16041614                  language = 'c++',
    16051615                  libraries = ["csage", "stdc++", "Cbc", "CbcSolver", "Cgl", "Clp", "CoinUtils", "OsiCbc", "OsiClp", "Osi", "OsiVol", "Vol"])
    16061616        )
    16071617
    16081618
    1609     if os.path.isfile(SAGE_ROOT+"/local/include/coin/OsiCpxSolverInterface.hpp"):
    1610     # if Cplex is installed too
    1611         ext_modules.append(
    1612             Extension("sage.numerical.mip_coin",
    1613                       ["sage/numerical/mip_coin.pyx"],
    1614                       include_dirs = [SAGE_ROOT+"/local/include/","sage/c_lib/include/"],
    1615                       language = 'c++',
    1616                       define_macros=[('BOB','1')],
    1617                       libraries = ["csage", "stdc++", "Cbc", "CbcSolver", "Cgl", "Clp", "CoinUtils", "OsiCbc", "OsiClp", "Osi", "OsiVol", "Vol", "OsiCpx"])
    1618            
    1619             )
    1620         ext_modules.append(
    1621             Extension("sage.numerical.mip_cplex",
    1622                       ["sage/numerical/mip_cplex.pyx"],
    1623                       include_dirs = [SAGE_ROOT+"/local/include/","/sage/c_lib/include/"],
    1624                       language = 'c++',
    1625                       libraries = ["csage", "stdc++", "Cbc", "CbcSolver", "Cgl", "Clp", "CoinUtils", "OsiCbc", "OsiClp", "Osi", "OsiVol", "Vol", "OsiCpx"])
    1626             )   
    1627 
    1628 
    1629     # otherwise
    1630     else:
    1631         ext_modules.append(
    1632             Extension("sage.numerical.mip_coin",
    1633                       ["sage/numerical/mip_coin.pyx"],
    1634                       include_dirs = [SAGE_ROOT+"/local/include/","sage/c_lib/include/"],
    1635                       language = 'c++',
    1636                       libraries = ["csage", "stdc++", "Cbc", "CbcSolver", "Cgl", "Clp", "CoinUtils", "OsiCbc", "OsiClp", "Osi", "OsiVol", "Vol"])
    1637             )
    1638 
    16391619if is_package_installed('mpc'):
    16401620    ext_modules.append(
    16411621        Extension('sage.rings.complex_mpc',
  • sage/graphs/generic_graph.py

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/graphs/generic_graph.py
    a b  
    42014201        else:
    42024202            raise ValueError("Only two algorithms are available : Cliquer and MILP.")
    42034203
    4204     def max_cut(self, value_only=True, use_edge_labels=True, vertices=False, solver=None, verbose=0):
     4204    def max_cut(self, value_only=True, use_edge_labels=False, vertices=False, solver=None, verbose=0):
    42054205        r"""
    42064206        Returns a maximum edge cut of the graph. For more information, see the
    42074207        `Wikipedia article on cuts
     
    42164216          - When set to ``False``, both the value and a maximum edge cut
    42174217            are returned.
    42184218
    4219         - ``use_edge_labels`` -- boolean (default: ``True``)
     4219        - ``use_edge_labels`` -- boolean (default: ``False``)
    42204220           
    42214221          - When set to ``True``, computes a maximum weighted cut
    42224222            where each edge has a weight defined by its label. (If
     
    43214321        p.set_objective(Sum([weight(l ) * in_cut[reorder_edge(u,v)] for (u,v,l ) in g.edge_iterator()]))
    43224322
    43234323        if value_only:
    4324             return p.solve(objective_only=True, solver=solver, log=verbose)
    4325         else:
    4326             val = [p.solve(solver=solver, log=verbose)]
     4324            obj = p.solve(objective_only=True, solver=solver, log=verbose)
     4325            return obj if use_edge_labels else round(obj)
     4326        else:
     4327            obj = p.solve(solver=solver, log=verbose)
     4328            val = [obj if use_edge_labels else round(obj)]
    43274329
    43284330            in_cut = p.get_values(in_cut)
    43294331            in_set = p.get_values(in_set)
     
    58025804        p.set_objective(Sum([weight(l ) * in_cut[reorder_edge(u,v)] for (u,v,l) in g.edge_iterator()]))
    58035805
    58045806        if value_only:
    5805             return p.solve(objective_only=True, solver=solver, log=verbose)
    5806         else:
    5807             val = [p.solve(solver=solver, log=verbose)]
     5807            obj = p.solve(objective_only=True, solver=solver, log=verbose)
     5808            return obj if use_edge_labels else round(obj)
     5809           
     5810        else:
     5811            obj = p.solve(solver=solver, log=verbose)
     5812            val = [obj if use_edge_labels else round(obj)]
    58085813
    58095814            in_cut = p.get_values(in_cut)
    58105815            in_set = p.get_values(in_set)
  • sage/numerical/__init__.py

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/__init__.py
    a b  
    1 # initialization file -- needed so directory is a module.
     1
  • new file sage/numerical/backends/__init__.py

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/__init__.py
    - +  
     1# not an empty file
  • new file sage/numerical/backends/coin_backend.pxd

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/coin_backend.pxd
    - +  
     1from sage.numerical.backends.generic_backend cimport GenericBackend
     2
     3include '../../../../../devel/sage/sage/ext/stdsage.pxi'
     4include '../../ext/cdefs.pxi'           
     5
     6cdef extern from *:
     7    ctypedef double* const_double_ptr "const double*"
     8
     9cdef extern from "../../local/include/coin/CoinPackedVector.hpp":
     10     ctypedef struct c_CoinPackedVector "CoinPackedVector":
     11         void insert(float, float)
     12     c_CoinPackedVector *new_c_CoinPackedVector "new CoinPackedVector" ()
     13     void del_CoinPackedVector "delete" (c_CoinPackedVector *)
     14
     15cdef extern from "../../local/include/coin/CoinShallowPackedVector.hpp":
     16     ctypedef struct c_CoinShallowPackedVector "CoinShallowPackedVector":
     17         void insert(float, float)
     18         int * getIndices ()
     19         double * getElements ()
     20         int getNumElements ()
     21     c_CoinShallowPackedVector *new_c_CoinShallowPackedVector "new CoinShallowPackedVector" ()
     22     void del_CoinShallowPackedVector "delete" (c_CoinShallowPackedVector *)
     23
     24cdef extern from "../../local/include/coin/CoinPackedMatrix.hpp":
     25     ctypedef struct c_CoinPackedMatrix "CoinPackedMatrix":
     26         void setDimensions(int, int)
     27         void appendRow(c_CoinPackedVector)
     28         c_CoinShallowPackedVector getVector(int)
     29     c_CoinPackedMatrix *new_c_CoinPackedMatrix "new CoinPackedMatrix" (bool, double, double)
     30     void del_CoinPackedMatrix "delete" (c_CoinPackedMatrix *)
     31
     32cdef extern from "../../local/include/coin/CoinMessageHandler.hpp":
     33     ctypedef struct c_CoinMessageHandler "CoinMessageHandler":
     34         void setLogLevel (int)
     35     c_CoinMessageHandler *new_c_CoinMessageHandler "new CoinMessageHandler" ()
     36     void del_CoinMessageHandler "delete" (c_CoinMessageHandler *)
     37
     38
     39cdef extern from "../../local/include/coin/CbcModel.hpp":
     40     ctypedef struct c_CbcModel "CbcModel":
     41         c_CoinMessageHandler * messageHandler ()
     42         void setNumberThreads (int)
     43         int getSolutionCount()
     44
     45     c_CbcModel *new_c_CbcModel "new CbcModel" ()
     46     void del_CbcModel "delete" (c_CbcModel *)
     47
     48cdef extern from "../../local/include/coin/OsiCbcSolverInterface.hpp":
     49     ctypedef struct c_OsiCbcSolverInterface "OsiCbcSolverInterface":
     50         double getInfinity()
     51         void loadProblem(c_CoinPackedMatrix, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr)
     52         void assignProblem(c_CoinPackedMatrix *, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr, const_double_ptr)
     53         void writeMps(char *, char *, double)
     54         void initialSolve()
     55         void branchAndBound()
     56         void readMps(string)
     57         double getObjValue()
     58         int getObjSense()
     59         double * getColSolution()
     60         void setObjSense (double )
     61         void setObjCoeff(int, double)
     62         double * getObjCoefficients ()
     63         void setLogLevel(int)
     64         void setInteger(int)
     65         void setContinuous(int)
     66         c_CoinMessageHandler * messageHandler ()
     67         c_CbcModel * getModelPtr  ()
     68         int isContinuous (int)
     69         int isAbandoned ()
     70         int isProvenOptimal ()
     71         int isProvenPrimalInfeasible ()
     72         int isProvenDualInfeasible ()
     73         int isPrimalObjectiveLimitReached ()
     74         int isDualObjectiveLimitReached ()
     75         int isIterationLimitReached ()
     76         void setMaximumSolutions(int)
     77         int getMaximumSolutions()
     78         int getNumCols()
     79         int getNumRows()
     80         void setColLower (int elementIndex, double elementValue)
     81         void setColUpper (int elementIndex, double elementValue)
     82         double * getRowLower()
     83         double * getRowUpper()
     84         double * getColLower()
     85         double * getColUpper()
     86         void addCol (int numberElements, int *rows, double *elements, double collb, double colub, double obj)
     87         void addRow (c_CoinPackedVector vec, double rowlb, double rowub)
     88         c_CoinPackedMatrix * getMatrixByRow()
     89     c_OsiCbcSolverInterface *new_c_OsiCbcSolverInterface "new OsiCbcSolverInterface" ()
     90     void del_OsiCbcSolverInterface "delete" (c_OsiCbcSolverInterface *)
     91
     92cdef class CoinBackend(GenericBackend):
     93    cdef c_OsiCbcSolverInterface* si
  • new file sage/numerical/backends/coin_backend.pyx

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/coin_backend.pyx
    - +  
     1r"""
     2COIN Backend
     3"""
     4
     5from sage.numerical.mip import MIPSolverException
     6
     7cdef class CoinBackend(GenericBackend):
     8
     9    def __cinit__(self, maximization = True):
     10       
     11        self.si = new_c_OsiCbcSolverInterface();
     12        # stuff related to the loglevel
     13        cdef c_CbcModel * model
     14        model = self.si.getModelPtr()
     15
     16        import multiprocessing
     17        model.setNumberThreads(multiprocessing.cpu_count())
     18
     19        self.set_log_level(0)
     20
     21        if maximization:
     22            self.set_direction(+1)
     23        else:
     24            self.set_direction(-1)
     25
     26    cpdef int add_variable(self):
     27        r"""
     28        Adds a variable.
     29
     30        This amounts to adding a new column to the matrix. By default,
     31        the variable is both positive and real.
     32
     33        EXAMPLE::
     34
     35            sage: from sage.numerical.backends.generic_backend import getSolver
     36            sage: p = getSolver(solver = "Coin")    # optional - Coin
     37            sage: p.n_cols()                                         # optional - Coin
     38            0
     39            sage: p.add_variable()                                   # optional - Coin
     40            1
     41            sage: p.n_cols()                                         # optional - Coin
     42            1
     43        """
     44
     45        self.si.addCol(0, NULL, NULL, 0, self.si.getInfinity(), 0)
     46        return self.si.getNumCols()
     47
     48    cpdef int add_variables(self, int number):
     49        r"""
     50        Adds ``number`` variables.
     51
     52        This amounts to adding new columns to the matrix. By default,
     53        the variables are both positive and real.
     54
     55        EXAMPLE::
     56
     57            sage: from sage.numerical.backends.generic_backend import getSolver
     58            sage: p = getSolver(solver = "Coin")    # optional - Coin
     59            sage: p.n_cols()                                         # optional - Coin
     60            0
     61            sage: p.add_variables(5)                                 # optional - Coin
     62            5
     63            sage: p.n_cols()                                         # optional - Coin
     64            5
     65        """
     66
     67        cdef int i
     68        for 0<= i< number:
     69            self.si.addCol(0, NULL, NULL, 0, self.si.getInfinity(), 0)
     70        return self.si.getNumCols()
     71
     72    cpdef set_variable_type(self, int variable, int vtype):
     73        r"""
     74        Sets the type of a variable
     75
     76        INPUT:
     77
     78        - ``variable`` (integer) -- the variable's id
     79
     80        - ``vtype`` (integer) :
     81
     82            *  1  Integer
     83            *  0  Binary
     84            * -1 Real
     85
     86        EXAMPLE::
     87
     88            sage: from sage.numerical.backends.generic_backend import getSolver
     89            sage: p = getSolver(solver = "Coin")   # optional - Coin
     90            sage: p.n_cols()                                        # optional - Coin
     91            0
     92            sage: p.add_variable()                                  # optional - Coin
     93            1
     94            sage: p.set_variable_type(0,1)                          # optional - Coin
     95            sage: p.is_variable_integer(0)                          # optional - Coin
     96            True
     97        """
     98
     99        if vtype == 1:
     100            self.si.setInteger(variable)
     101        elif vtype == 0:
     102            self.si.setColLower(variable, 0)
     103            self.si.setInteger(variable)
     104            self.si.setColUpper(variable, 1)
     105        else:
     106            self.si.setContinuous(variable)
     107
     108    cpdef set_direction(self, int sense):
     109        r"""
     110        Sets the direction (maximization/minimization).
     111
     112        INPUT:
     113
     114        - ``sense`` (integer) :
     115
     116            * +1 => Maximization
     117            * -1 => Minimization
     118
     119        EXAMPLE::
     120
     121            sage: from sage.numerical.backends.generic_backend import getSolver
     122            sage: p = getSolver(solver = "Coin")  # optional - Coin
     123            sage: p.is_maximization()                              # optional - Coin
     124            True
     125            sage: p.set_direction(-1)                              # optional - Coin
     126            sage: p.is_maximization()                              # optional - Coin
     127            False
     128        """
     129        self.si.setObjSense(-sense)
     130
     131    cpdef set_objective_coeff(self, int variable, double coeff):
     132        r"""
     133        Sets the coefficient of a variable in the objective function
     134
     135        INPUT:
     136
     137        - ``variable`` (integer) -- the variable's id
     138
     139        - ``coeff`` (double) -- its coefficient
     140
     141        EXAMPLE::
     142
     143            sage: from sage.numerical.backends.generic_backend import getSolver
     144            sage: p = getSolver(solver = "Coin")  # optional - Coin
     145            sage: p.add_variable()                                 # optional - Coin
     146            1
     147            sage: p.get_objective_coeff(0)                         # optional - Coin
     148            0.0
     149            sage: p.set_objective_coeff(0,2)                       # optional - Coin
     150            sage: p.get_objective_coeff(0)                         # optional - Coin
     151            2.0
     152        """
     153
     154        self.si.setObjCoeff(variable, coeff)
     155
     156    cpdef set_objective(self, list coeff):
     157        r"""
     158        Sets the objective function.
     159
     160        INPUT:
     161
     162        - ``coeff`` -- a list of real values, whose ith element is the
     163          coefficient of the ith variable in the objective function.
     164
     165        EXAMPLE::
     166
     167            sage: from sage.numerical.backends.generic_backend import getSolver
     168            sage: p = getSolver(solver = "Coin")    # optional - Coin
     169            sage: p.add_variables(5)                                 # optional - Coin
     170            5
     171            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - Coin
     172            sage: map(lambda x :p.get_objective_coeff(x), range(5))  # optional - Coin
     173            [1.0, 1.0, 2.0, 1.0, 3.0]
     174        """
     175
     176        cdef int i
     177        for i,v in enumerate(coeff):
     178            self.si.setObjCoeff(i, v)
     179
     180    cpdef set_log_level(self, int level):
     181        r"""
     182        Sets the log (verbosity) level
     183
     184        INPUT:
     185
     186        - ``level`` (integer) -- From 0 (no verbosity) to 3.
     187
     188        EXAMPLE::
     189
     190            sage: from sage.numerical.backends.generic_backend import getSolver
     191            sage: p = getSolver(solver = "Coin")   # optional - Coin
     192            sage: p.set_log_level(2)                                # optional - Coin
     193
     194        """
     195
     196        cdef c_CbcModel * model
     197        cdef c_CoinMessageHandler * msg
     198        model = self.si.getModelPtr()
     199        msg = model.messageHandler()
     200        msg.setLogLevel(level)
     201
     202    cpdef add_constraints(self, int number, int direction, double bound):
     203        r"""
     204        Adds constraints.
     205
     206        INPUT:
     207
     208        - ``number`` (integer) -- the number of constraints to add.
     209
     210        - ``direction`` (integer) -- the direction of the constraint,
     211          where :
     212
     213              * +1 indicates : function `\leq` ``bound``
     214              *  0 indicates : function `=` ``bound``
     215              * -1 indicates : function `\geq` ``bound``
     216
     217        - ``bound`` (double) -- value of the right-hand side (as
     218          illustrated immediately above).
     219
     220        EXAMPLE::
     221
     222            sage: from sage.numerical.backends.generic_backend import getSolver
     223            sage: p = getSolver(solver = "Coin")   # optional - Coin
     224            sage: p.add_variables(5)                                # optional - Coin
     225            5
     226            sage: p.add_constraints(5, +1, 2)                       # optional - Coin
     227            sage: p.get_row(4)                                      # optional - Coin
     228            ([], [])
     229            sage: p.get_row_bounds(4)                               # optional - Coin
     230            (None, 2.0)
     231        """
     232
     233        cdef int i
     234        for 0<= i<number:
     235            self.add_constraint([],[],direction, bound)
     236
     237    cpdef add_constraint(self, list indices, list coeffs, int direction, double bound):
     238        r"""
     239        Adds a constraint.
     240
     241        INPUT:
     242
     243        - ``indices`` (list of integers) -- this list constains the
     244          indices of the variables whose coefficient is nonzero in the
     245          constraint.
     246
     247        - ``coeffs`` (list of real values) -- associates a coefficient
     248          to the variables listed by ``indices``. Namely, the ith
     249          entry of ``coeffs`` corresponds to the coefficient of the
     250          variable represented by the ith entry in ``indices``.
     251
     252        - ``direction`` (integer) -- the direction of the constraint,
     253          where :
     254
     255              * +1 indicates : function `\leq` ``bound``
     256              *  0 indicates : function `=` ``bound``
     257              * -1 indicates : function `\geq` ``bound``
     258
     259        - ``bound`` (double) -- value of the right-hand side (as
     260          illustrated immediately above).
     261
     262        .. NOTE::
     263
     264            ``indices`` and ``coeffs`` are expected to be of the same
     265            length.
     266
     267        EXAMPLE::
     268
     269            sage: from sage.numerical.backends.generic_backend import getSolver
     270            sage: p = getSolver(solver = "Coin") # optional - Coin
     271            sage: p.add_variables(5)                              # optional - Coin
     272            5
     273            sage: p.add_constraint(range(5), range(5), 0, 2)      # optional - Coin
     274            sage: p.get_row(0)                                    # optional - Coin
     275            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
     276            sage: p.get_row_bounds(0)                             # optional - Coin
     277            (2.0, 2.0)
     278        """
     279
     280        cdef int i
     281        cdef int n = len(indices)
     282        cdef c_CoinPackedVector* row
     283        row = new_c_CoinPackedVector();
     284
     285        for 0<= i<n:
     286            row.insert(indices[i], coeffs[i])
     287
     288        self.si.addRow (row[0],
     289                        bound if direction != +1 else -self.si.getInfinity(),
     290                        bound if direction != -1 else +self.si.getInfinity())
     291
     292
     293    cpdef get_row(self, int index):
     294        r"""
     295        Returns a row
     296
     297        INPUT:
     298
     299        - ``index`` (integer) -- the constraint's id.
     300
     301        OUTPUT:
     302
     303        A pair ``(indices, coeffs)`` where ``indices`` lists the
     304        entries whose coefficient is nonzero, and to which ``coeffs``
     305        associates their coefficient on the model of the
     306        ``add_constraint`` method.
     307
     308        EXAMPLE::
     309
     310            sage: from sage.numerical.backends.generic_backend import getSolver
     311            sage: p = getSolver(solver = "Coin")  # optional - Coin
     312            sage: p.add_variables(5)                               # optional - Coin
     313            5
     314            sage: p.add_constraint(range(5), range(5), 0, 2)       # optional - Coin
     315            sage: p.get_row(0)                                     # optional - Coin
     316            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
     317            sage: p.get_row_bounds(0)                              # optional - Coin
     318            (2.0, 2.0)
     319        """
     320
     321        cdef list indices = []
     322        cdef list values = []
     323        cdef int * c_indices
     324        cdef int i
     325        cdef double * c_values
     326        cdef c_CoinPackedMatrix * M = <c_CoinPackedMatrix *> self.si.getMatrixByRow()
     327        cdef c_CoinShallowPackedVector V = <c_CoinShallowPackedVector> M.getVector(index)
     328        cdef int n = V.getNumElements()
     329
     330        c_indices = <int*> V.getIndices()
     331        c_values = <double*> V.getElements()
     332
     333        for 0<= i < n:
     334            indices.append(c_indices[i])
     335            values.append(c_values[i])
     336
     337        return (indices, values)
     338
     339    cpdef get_row_bounds(self, int i):
     340        r"""
     341        Returns the bounds of a specific constraint.
     342
     343        INPUT:
     344
     345        - ``index`` (integer) -- the constraint's id.
     346
     347        OUTPUT:
     348
     349        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     350        to ``None`` if the constraint is not bounded in the
     351        corresponding direction, and is a real value otherwise.
     352
     353        EXAMPLE::
     354
     355            sage: from sage.numerical.backends.generic_backend import getSolver
     356            sage: p = getSolver(solver = "Coin")  # optional - Coin
     357            sage: p.add_variables(5)                               # optional - Coin
     358            5
     359            sage: p.add_constraint(range(5), range(5), 0, 2)       # optional - Coin
     360            sage: p.get_row(0)                                     # optional - Coin
     361            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
     362            sage: p.get_row_bounds(0)                              # optional - Coin
     363            (2.0, 2.0)
     364        """
     365
     366        cdef double * ub
     367        cdef double * lb
     368
     369        ub = <double*> self.si.getRowUpper()
     370        lb = <double*> self.si.getRowLower()
     371
     372        return (lb[i] if lb[i] != - self.si.getInfinity() else None,
     373                ub[i] if ub[i] != + self.si.getInfinity() else None)
     374
     375    cpdef get_col_bounds(self, int i):
     376        r"""
     377        Returns the bounds of a specific variable.
     378
     379        INPUT:
     380
     381        - ``index`` (integer) -- the variable's id.
     382
     383        OUTPUT:
     384
     385        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     386        to ``None`` if the variable is not bounded in the
     387        corresponding direction, and is a real value otherwise.
     388
     389        EXAMPLE::
     390
     391            sage: from sage.numerical.backends.generic_backend import getSolver
     392            sage: p = getSolver(solver = "Coin")  # optional - Coin
     393            sage: p.add_variable()                                 # optional - Coin
     394            1
     395            sage: p.get_col_bounds(0)                              # optional - Coin
     396            (0.0, None)
     397            sage: p.set_variable_max(0, 5)                         # optional - Coin
     398            sage: p.get_col_bounds(0)                              # optional - Coin
     399            (0.0, 5.0)
     400        """
     401
     402        cdef double * ub
     403        cdef double * lb
     404
     405        ub = <double*> self.si.getColUpper()
     406        lb = <double*> self.si.getColLower()
     407
     408        return (lb[i] if lb[i] != - self.si.getInfinity() else None,
     409                ub[i] if ub[i] != + self.si.getInfinity() else None)
     410
     411    cpdef double get_objective_coeff(self, int index):
     412        return self.si.getObjCoefficients()[index]
     413
     414    cpdef add_col(self, list indices, list coeffs):
     415        r"""
     416        Adds a column.
     417
     418        INPUT:
     419
     420        - ``indices`` (list of integers) -- this list constains the
     421          indices of the constraints in which the variable's
     422          coefficient is nonzero
     423
     424        - ``coeffs`` (list of real values) -- associates a coefficient
     425          to the variable in each of the constraints in which it
     426          appears. Namely, the ith entry of ``coeffs`` corresponds to
     427          the coefficient of the variable in the constraint
     428          represented by the ith entry in ``indices``.
     429
     430        .. NOTE::
     431
     432            ``indices`` and ``coeffs`` are expected to be of the same
     433            length.
     434
     435        EXAMPLE::
     436
     437            sage: from sage.numerical.backends.generic_backend import getSolver
     438            sage: p = getSolver(solver = "Coin")  # optional - Coin
     439            sage: p.n_cols()                                       # optional - Coin
     440            0
     441            sage: p.n_rows()                                       # optional - Coin
     442            0
     443            sage: p.add_constraints(5, -1, 0)                      # optional - Coin
     444            sage: p.add_col(range(5), range(5))                    # optional - Coin
     445            sage: p.n_rows()                                       # optional - Coin
     446            5
     447        """
     448
     449        cdef int n = len(indices)
     450        cdef int * c_indices = <int*>sage_malloc(n*sizeof(int))
     451        cdef double * c_values  = <double*>sage_malloc(n*sizeof(double))
     452        cdef int i
     453
     454        for 0<= i< n:
     455            c_indices[i] = indices[i]
     456            c_values[i] = coeffs[i]
     457       
     458
     459        self.si.addCol (1, c_indices, c_values, 0, self.si.getInfinity(), 0)
     460
     461    cpdef int solve(self) except -1:
     462        r"""
     463        Solves the problem.
     464
     465        .. NOTE::
     466
     467            This method raises ``MIPSolverException`` exceptions when
     468            the solution can not be computed for any reason (none
     469            exists, or the LP solver was not able to find it, etc...)
     470
     471        EXAMPLE::
     472
     473            sage: from sage.numerical.backends.generic_backend import getSolver
     474            sage: p = getSolver(solver = "Coin")    # optional - Coin
     475            sage: p.add_constraints(5, -1, 0)       # optional - Coin
     476            sage: p.add_col(range(5), [1,2,3,4,5])  # optional - Coin
     477            sage: p.solve()                         # optional - Coin
     478            0
     479
     480        TESTS::
     481
     482            sage: from sage.numerical.backends.generic_backend import getSolver
     483            sage: p = getSolver(solver = "Coin")    # optional - Coin
     484            sage: p.add_variable()                  # optional - Coin
     485            1
     486            sage: p.add_constraint([0], [1], +1, 4) # optional - Coin
     487            sage: p.add_constraint([0], [1], -1, 6) # optional - Coin
     488            sage: p.set_objective_coeff(0,1)        # optional - Coin
     489            sage: p.solve()                         # optional - Coin
     490            Traceback (most recent call last):
     491            ...
     492            MIPSolverException: ...
     493        """
     494
     495        self.si.branchAndBound()
     496
     497        cdef const_double_ptr solution
     498
     499        if self.si.isAbandoned():
     500            raise MIPSolverException("CBC : The solver has abandoned!")
     501
     502        elif self.si.isProvenPrimalInfeasible() or self.si.isProvenDualInfeasible():
     503            raise MIPSolverException("CBC : The problem or its dual has been proven infeasible!")
     504
     505        elif (self.si.isPrimalObjectiveLimitReached() or self.si.isDualObjectiveLimitReached()):
     506            raise MIPSolverException("CBC : The objective limit has been reached for the problem or its dual!")
     507
     508        elif self.si.isIterationLimitReached():
     509            raise MIPSolverException("CBC : The iteration limit has been reached!")
     510
     511        elif not self.si.isProvenOptimal():
     512            raise MIPSolverException("CBC : Unknown error")
     513
     514    cpdef double get_objective_value(self):
     515        r"""
     516        Returns the value of the objective function.
     517
     518        .. NOTE::
     519
     520           Has no meaning unless ``solve`` has been called before.
     521
     522        EXAMPLE::
     523
     524            sage: from sage.numerical.backends.generic_backend import getSolver
     525            sage: p = getSolver(solver = "Coin")  # optional - Coin
     526            sage: p.add_variables(2)                               # optional - Coin
     527            2
     528            sage: p.add_constraint([0, 1], [1, 2], +1, 3)          # optional - Coin
     529            sage: p.set_objective([2, 5])                          # optional - Coin
     530            sage: p.solve()                                        # optional - Coin
     531            0
     532            sage: p.get_objective_value()                          # optional - Coin
     533            7.5
     534            sage: p.get_variable_value(0)                          # optional - Coin
     535            0.0
     536            sage: p.get_variable_value(1)                          # optional - Coin
     537            1.5
     538        """
     539
     540        return self.si.getObjValue()
     541
     542    cpdef double get_variable_value(self, int variable):
     543        r"""
     544        Returns the value of a variable given by the solver.
     545
     546        .. NOTE::
     547
     548           Has no meaning unless ``solve`` has been called before.
     549
     550        EXAMPLE::
     551
     552            sage: from sage.numerical.backends.generic_backend import getSolver
     553            sage: p = getSolver(solver = "Coin") # optional - Coin
     554            sage: p.add_variables(2)                              # optional - Coin
     555            2
     556            sage: p.add_constraint([0, 1], [1, 2], +1, 3)         # optional - Coin
     557            sage: p.set_objective([2, 5])                         # optional - Coin
     558            sage: p.solve()                                       # optional - Coin
     559            0
     560            sage: p.get_objective_value()                         # optional - Coin
     561            7.5
     562            sage: p.get_variable_value(0)                         # optional - Coin
     563            0.0
     564            sage: p.get_variable_value(1)                         # optional - Coin
     565            1.5
     566        """
     567
     568        cdef double * solution
     569        solution = <double*> self.si.getColSolution()
     570        return solution[variable]
     571
     572    cpdef int n_cols(self):
     573        r"""
     574        Returns the number of columns/variables.
     575
     576        EXAMPLE::
     577
     578            sage: from sage.numerical.backends.generic_backend import getSolver
     579            sage: p = getSolver(solver = "Coin")  # optional - Coin
     580            sage: p.n_cols()                                       # optional - Coin
     581            0
     582            sage: p.add_variables(2)                               # optional - Coin
     583            2
     584            sage: p.n_cols()                                       # optional - Coin
     585            2
     586        """
     587
     588        return self.si.getNumCols()
     589
     590    cpdef int n_rows(self):
     591        r"""
     592        Returns the number of rows/constraints.
     593
     594        EXAMPLE::
     595
     596            sage: from sage.numerical.backends.generic_backend import getSolver
     597            sage: p = getSolver(solver = "Coin") # optional - Coin
     598            sage: p.n_rows()                                      # optional - Coin
     599            0
     600            sage: p.add_constraints(2, -1, 2)                     # optional - Coin
     601            sage: p.n_rows()                                      # optional - Coin
     602            2
     603        """
     604        return self.si.getNumRows()
     605
     606
     607    cpdef bint is_variable_binary(self, int index):
     608        r"""
     609        Tests whether the given variable is of binary type.
     610
     611        INPUT:
     612
     613        - ``index`` (integer) -- the variable's id
     614
     615        EXAMPLE::
     616
     617            sage: from sage.numerical.backends.generic_backend import getSolver
     618            sage: p = getSolver(solver = "Coin")  # optional - Coin
     619            sage: p.n_cols()                                       # optional - Coin
     620            0
     621            sage: p.add_variable()                                 # optional - Coin
     622            1
     623            sage: p.set_variable_type(0,0)                         # optional - Coin
     624            sage: p.is_variable_binary(0)                          # optional - Coin
     625            True
     626
     627        """
     628
     629        return (0 == self.si.isContinuous(index) and
     630                self.get_variable_min(index) == 0 and
     631                self.get_variable_max(index) == 1)     
     632
     633    cpdef bint is_variable_integer(self, int index):
     634        r"""
     635        Tests whether the given variable is of integer type.
     636
     637        INPUT:
     638
     639        - ``index`` (integer) -- the variable's id
     640
     641        EXAMPLE::
     642
     643            sage: from sage.numerical.backends.generic_backend import getSolver
     644            sage: p = getSolver(solver = "Coin")  # optional - Coin
     645            sage: p.n_cols()                                       # optional - Coin
     646            0
     647            sage: p.add_variable()                                 # optional - Coin
     648            1
     649            sage: p.set_variable_type(0,1)                         # optional - Coin
     650            sage: p.is_variable_integer(0)                         # optional - Coin
     651            True
     652        """
     653        return (0 == self.si.isContinuous(index) and
     654                (self.get_variable_min(index) != 0 or
     655                self.get_variable_max(index) != 1))
     656
     657    cpdef bint is_variable_continuous(self, int index):
     658        r"""
     659        Tests whether the given variable is of continuous/real type.
     660
     661        INPUT:
     662
     663        - ``index`` (integer) -- the variable's id
     664
     665        EXAMPLE::
     666
     667            sage: from sage.numerical.backends.generic_backend import getSolver
     668            sage: p = getSolver(solver = "Coin")  # optional - Coin
     669            sage: p.n_cols()                                       # optional - Coin
     670            0
     671            sage: p.add_variable()                                 # optional - Coin
     672            1
     673            sage: p.is_variable_continuous(0)                      # optional - Coin
     674            True
     675            sage: p.set_variable_type(0,1)                         # optional - Coin
     676            sage: p.is_variable_continuous(0)                      # optional - Coin
     677            False
     678
     679        """
     680        return 1 == self.si.isContinuous(index)
     681
     682
     683    cpdef bint is_maximization(self):
     684        r"""
     685        Tests whether the problem is a maximization
     686
     687        EXAMPLE::
     688
     689            sage: from sage.numerical.backends.generic_backend import getSolver
     690            sage: p = getSolver(solver = "Coin") # optional - Coin
     691            sage: p.is_maximization()                             # optional - Coin
     692            True
     693            sage: p.set_direction(-1)                             # optional - Coin
     694            sage: p.is_maximization()                             # optional - Coin
     695            False
     696        """
     697
     698        return self.si.getObjSense() == -1
     699
     700
     701    cpdef get_variable_max(self, int i):
     702        r"""
     703        Returns the upper bound on a variable
     704
     705        INPUT:
     706
     707        - ``index`` (integer) -- the variable's id
     708
     709        OUTPUT:
     710
     711        A real value if the variable has an upper bound, ``None``
     712        otherwise.
     713
     714        EXAMPLE::
     715
     716            sage: from sage.numerical.backends.generic_backend import getSolver
     717            sage: p = getSolver(solver = "Coin")  # optional - Coin
     718            sage: p.add_variable()                                 # optional - Coin
     719            1
     720            sage: p.get_variable_max(0) is None                    # optional - Coin
     721            True
     722            sage: p.set_variable_max(0, 5)                         # optional - Coin
     723            sage: p.get_variable_max(0)                            # optional - Coin
     724            5.0
     725
     726        """
     727
     728        cdef double * ub
     729        ub = <double*> self.si.getColUpper()
     730        return ub[i] if ub[i] != + self.si.getInfinity() else None
     731
     732
     733    cpdef get_variable_min(self, int i):
     734        r"""
     735        Returns the lower bound on a variable
     736
     737        INPUT:
     738
     739        - ``index`` (integer) -- the variable's id
     740
     741        OUTPUT:
     742
     743        A real value if the variable has an lower bound, ``None``
     744        otherwise.
     745
     746        EXAMPLE::
     747
     748            sage: from sage.numerical.backends.generic_backend import getSolver
     749            sage: p = getSolver(solver = "Coin")  # optional - Coin
     750            sage: p.add_variable()                                 # optional - Coin
     751            1
     752            sage: p.get_variable_min(0)                            # optional - Coin
     753            0.0
     754            sage: p.set_variable_min(0, 5)                         # optional - Coin
     755            sage: p.get_variable_min(0)                            # optional - Coin
     756            5.0
     757        """
     758
     759        cdef double * lb
     760        lb = <double*> self.si.getColLower()
     761        return lb[i] if lb[i] != - self.si.getInfinity() else None
     762
     763    cpdef set_variable_max(self, int index, value):
     764        r"""
     765        Sets the upper bound on a variable
     766
     767        INPUT:
     768
     769        - ``index`` (integer) -- the variable's id
     770
     771        - ``value`` -- real value, or ``None`` to mean that the
     772          variable has not upper bound.
     773
     774        EXAMPLE::
     775
     776            sage: from sage.numerical.backends.generic_backend import getSolver
     777            sage: p = getSolver(solver = "Coin")  # optional - Coin
     778            sage: p.add_variable()                                 # optional - Coin
     779            1
     780            sage: p.get_col_bounds(0)                              # optional - Coin
     781            (0.0, None)
     782            sage: p.set_variable_max(0, 5)                         # optional - Coin
     783            sage: p.get_col_bounds(0)                              # optional - Coin
     784            (0.0, 5.0)
     785        """
     786
     787        self.si.setColUpper(index, value if value is not None else +self.si.getInfinity())
     788
     789    cpdef set_variable_min(self, int index, value):
     790        r"""
     791        Sets the lower bound on a variable
     792
     793        INPUT:
     794
     795        - ``index`` (integer) -- the variable's id
     796
     797        - ``value`` -- real value, or ``None`` to mean that the
     798          variable has not lower bound.
     799
     800        EXAMPLE::
     801
     802            sage: from sage.numerical.backends.generic_backend import getSolver
     803            sage: p = getSolver(solver = "Coin")  # optional - Coin
     804            sage: p.add_variable()                                 # optional - Coin
     805            1
     806            sage: p.get_col_bounds(0)                              # optional - Coin
     807            (0.0, None)
     808            sage: p.set_variable_min(0, 5)                         # optional - Coin
     809            sage: p.get_col_bounds(0)                              # optional - Coin
     810            (5.0, None)
     811        """
     812
     813        self.si.setColLower(index, value if value is not None else -self.si.getInfinity())
     814   
     815    cpdef write_mps(self, char * filename, int modern):
     816        r"""
     817        Writes the problem to a .mps file
     818
     819        INPUT:
     820       
     821        - ``filename`` (string)
     822
     823        EXAMPLE::
     824
     825            sage: from sage.numerical.backends.generic_backend import getSolver
     826            sage: p = getSolver(solver = "Coin")  # optional - Coin
     827            sage: p.add_variables(2)                               # optional - Coin
     828            2
     829            sage: p.add_constraint([0, 1], [1, 2], +1, 3)          # optional - Coin
     830            sage: p.set_objective([2, 5])                          # optional - Coin
     831            sage: p.write_mps(SAGE_TMP+"/lp_problem.mps", 0)       # optional - Coin
     832        """
     833
     834        cdef char * mps = "mps"
     835        self.si.writeMps(filename, mps, -1 if self.is_maximization() else 1)
     836
     837    cpdef set_problem_name(self, char * name):
     838        r"""
     839        Sets the problem's name
     840
     841        INPUT:
     842
     843        - ``name`` (``char *``) -- the problem's name
     844
     845        EXAMPLE::
     846
     847            sage: from sage.numerical.backends.generic_backend import getSolver
     848            sage: p = getSolver(solver = "Coin")   # optional - Coin
     849            sage: p.set_problem_name("There once was a french fry") # optional - Coin
     850            sage: print p.get_problem_name()                        # optional - Coin
     851            <BLANKLINE>
     852        """
     853
     854        pass
     855
     856    cpdef get_problem_name(self):
     857        r"""
     858        Returns the problem's name
     859
     860        EXAMPLE::
     861
     862            sage: from sage.numerical.backends.generic_backend import getSolver
     863            sage: p = getSolver(solver = "Coin")   # optional - Coin
     864            sage: p.set_problem_name("There once was a french fry") # optional - Coin
     865            sage: print p.get_problem_name()                        # optional - Coin
     866            <BLANKLINE>
     867        """
     868
     869        return ""
     870
     871    cpdef get_row_name(self, int index):
     872        r"""
     873        Returns the ``index`` th row name
     874
     875        INPUT:
     876
     877        - ``index`` (integer) -- the row's id
     878
     879        EXAMPLE::
     880
     881            sage: from sage.numerical.backends.generic_backend import getSolver
     882            sage: p = getSolver(solver = "Coin")           # optional - Coin
     883            sage: p.add_variable()                         # optional - Coin
     884            1
     885            sage: p.set_row_name(0, "I am a constraint")   # optional - Coin
     886            sage: print p.get_row_name(0)                  # optional - Coin
     887            <BLANKLINE>
     888        """
     889
     890        return ""
     891
     892
     893    cpdef set_row_name(self, int index, char * name):
     894        r"""
     895        Sets the ``index`` th row name
     896
     897        INPUT:
     898
     899        - ``index`` (integer) -- the row's id
     900
     901        - ``name`` (``char *``) -- its name
     902
     903        EXAMPLE::
     904
     905            sage: from sage.numerical.backends.generic_backend import getSolver
     906            sage: p = getSolver(solver = "Coin")  # optional - Coin
     907            sage: p.add_constraints(1, -1, 2)                      # optional - Coin
     908            sage: p.set_row_name(0, "Empty constraint 1")          # optional - Coin
     909            sage: print p.get_row_name(0)                          # optional - Coin
     910            <BLANKLINE>
     911        """
     912
     913        pass
     914
     915    cpdef set_objective_name(self, name):
     916        pass
     917
     918    cpdef set_col_name(self, int index, char * name):
     919        r"""
     920        Sets the ``index`` th col name
     921
     922        INPUT:
     923
     924        - ``index`` (integer) -- the col's id
     925
     926        - ``name`` (``char *``) -- its name
     927
     928        EXAMPLE::
     929
     930            sage: from sage.numerical.backends.generic_backend import getSolver
     931            sage: p = getSolver(solver = "Coin")  # optional - Coin
     932            sage: p.add_variable()                                 # optional - Coin
     933            1
     934            sage: p.set_col_name(0, "I am a variable")             # optional - Coin
     935            sage: print p.get_col_name(0)                          # optional - Coin
     936            <BLANKLINE>
     937        """
     938        pass
     939
     940    cpdef get_col_name(self, int index):
     941        r"""
     942        Returns the ``index`` th col name
     943
     944        INPUT:
     945
     946        - ``index`` (integer) -- the col's id
     947
     948        EXAMPLE::
     949
     950            sage: from sage.numerical.backends.generic_backend import getSolver
     951            sage: p = getSolver(solver = "Coin")  # optional - Coin
     952            sage: p.add_variable()                                 # optional - Coin
     953            1
     954            sage: p.set_col_name(0, "I am a variable")             # optional - Coin
     955            sage: print p.get_col_name(0)                          # optional - Coin
     956            <BLANKLINE>
     957        """
     958
     959        return ""
  • new file sage/numerical/backends/cplex_backend.pxd

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/cplex_backend.pxd
    - +  
     1from sage.numerical.backends.generic_backend cimport GenericBackend
     2
     3include '../../../../../devel/sage/sage/ext/stdsage.pxi'
     4include '../../ext/cdefs.pxi'           
     5
     6cdef struct c_cpxlp
     7
     8cdef extern from *:
     9    ctypedef double* const_double_ptr "double*"
     10
     11
     12cdef class CPLEXBackend(GenericBackend):
     13    cdef bint _mixed
     14    cdef c_cpxlp * env
     15    cdef c_cpxlp * lp
     16    cdef current_sol
     17
     18
     19cdef extern from "../../local/include/cplex.h":
     20
     21     # Create problem
     22     c_cpxlp * CPXcreateprob (c_cpxlp *  env, int *status_p,
     23                              char *probname_str)
     24
     25     # Add constraints
     26     int CPXaddrows (c_cpxlp * env, c_cpxlp *  lp, int ccnt, int rcnt,
     27                   int nzcnt, double *rhs, char *sense,
     28                   int *rmatbeg, int *rmatind,
     29                   double *rmatval, char **colname,
     30                   char **rowname)
     31
     32     # Solve MILP
     33     int CPXmipopt (c_cpxlp * env, c_cpxlp * lp)
     34
     35     # Solve LP
     36     int CPXlpopt (c_cpxlp * env, c_cpxlp * lp)
     37
     38     # Solve MILP through filling the solution pool
     39     int CPXpopulate (c_cpxlp * env, c_cpxlp * lp)
     40
     41     # Number of solutions in the pool
     42     int CPXgetsolnpoolx (c_cpxlp * env, c_cpxlp * lp, int id, double * x, int beg, int end)
     43
     44     # Set the sense of the optimization problem
     45     int CPXchgobjsen(c_cpxlp * env, c_cpxlp * lp, int)
     46
     47     # Gets the sense of the optimization problem
     48     int CPXgetobjsen(c_cpxlp * env, c_cpxlp * lp)
     49
     50     # Change the coefficient of a variable in the objective function
     51     int CPXchgobj(c_cpxlp * env, c_cpxlp * lp, int cnt, int * indices, double * values)
     52
     53     # Sets the problem's name
     54     int CPXchgprobname(c_cpxlp * env, c_cpxlp * lp, char * probname_str)
     55
     56     # Gets the problem's name
     57     int CPXgetprobname(c_cpxlp * env, c_cpxlp * lp, char * buf_str, int bufspace, int * surplus_p)
     58
     59     # Get a col's name
     60     int CPXgetcolname(c_cpxlp * env, c_cpxlp * lp, char ** name, char * namestore, int storespace, int * surplus_p, int begin, int end)
     61
     62     # Get a row's name
     63     int CPXgetrowname(c_cpxlp * env, c_cpxlp * lp, char ** name, char * namestore, int storespace, int * surplus_p, int begin, int end)
     64
     65     # Sets a row's name
     66     int CPXchgrowname(c_cpxlp * env, c_cpxlp * lp, int cnt, int * indices, char ** newname)
     67
     68     # Sets a col's name
     69     int CPXchgcolname(c_cpxlp * env, c_cpxlp * lp, int cnt, int * indices, char ** newname)
     70
     71     # Set a "double" parameter
     72     int CPXsetdblparam (c_cpxlp * env, int, double)
     73
     74     # Set an integer parameter
     75     int CPXsetintparam  (c_cpxlp * env, int whichparam, int newvalue)
     76
     77     # Number of solutions in the pool
     78     int CPXgetsolnpoolnumsolns (c_cpxlp * env, c_cpxlp * lp)
     79
     80     # Number of replaces solutions in the pool
     81     int CPXgetsolnpoolnumreplaced(c_cpxlp * env, c_cpxlp * lp)
     82     
     83     # Remove a solution from the pool
     84     int CPXdelsolnpoolsolns (c_cpxlp * env, c_cpxlp * lp, int begin, int end)
     85
     86     int CPXgetsubstat (c_cpxlp * env, c_cpxlp * lp)
     87
     88     # Get the objective value
     89     int CPXgetobjval (c_cpxlp *, c_cpxlp *, double *)
     90
     91     # Add columns
     92     int CPXnewcols(c_cpxlp * env, c_cpxlp * lp, int, double *, double *, double *, char *, char **)
     93
     94     # Add rows
     95     int CPXnewrows(c_cpxlp * env, c_cpxlp * lp, int rcnt, double * rhs, char * sense, double * rngval, char ** rowname)
     96
     97     # Get the right hand side of a row
     98     int CPXgetrhs(c_cpxlp * env, c_cpxlp * lp, double * rhs, int begin, int end)
     99
     100     # Get the sense of a constraint
     101     int CPXgetsense(c_cpxlp * env, c_cpxlp * lp, char * sense, int begin, int end)
     102     
     103     # Get rows
     104     int CPXgetrows(c_cpxlp * env, c_cpxlp * lp, int * nzcnt_p, int * rmatbeg, int * rmatind, double * rmatval, int rmatspace, int * surplus_p, int begin, int end)
     105
     106     # Get a variable's maximum value
     107     int CPXgetub(c_cpxlp * env, c_cpxlp * lp, double * ub, int begin, int end)
     108
     109     # Get a variable's minimum value
     110     int CPXgetlb(c_cpxlp * env, c_cpxlp * lp, double * lb, int begin, int end)
     111     
     112     # Changes the bounds of a variable
     113     int CPXchgbds(c_cpxlp * env, c_cpxlp * lp, int cnt, int * indices, char * lu, double * bd)
     114
     115     # Get a coefficient of the objective function
     116     int CPXgetobj(c_cpxlp * env, c_cpxlp * lp, double * obj, int begin, int end)
     117
     118     # Change coefficients in the matrix
     119     int CPXchgcoeflist(c_cpxlp * env, c_cpxlp * lp, int numcoefs, int * rowlist, int * collist, double * vallist)
     120
     121     # get solution of a MILP
     122     int CPXsolution(c_cpxlp * env, c_cpxlp * lp, int * lpstat, double * obj, double * x, double *, double *, double *)
     123
     124     # get the value of some variables in the solution of a LP
     125     int CPXgetx(c_cpxlp * env, c_cpxlp * lp, double * x, int begin, int end)
     126
     127     # Create a CPLEX enviromnment
     128     c_cpxlp * CPXopenCPLEX (int *status_p)
     129
     130     # Close a CPLEX enviromnment
     131     int * CPXcloseCPLEX (c_cpxlp * env)
     132
     133     # Change the type of a variable
     134     int CPXchgctype(c_cpxlp * env, c_cpxlp * lp, int cnt, int * indices, char * xctype)
     135
     136     # Gets the type of a variable
     137     int CPXgetctype(c_cpxlp * env, c_cpxlp * lp, char * xctype, int begin, int end)
     138
     139     # Get information about the solution computed
     140     int CPXsolninfo(c_cpxlp * env, c_cpxlp * lp, int * solnmethod_p, int * solntype_p, int * pfeasind_p, int * dfeasind_p)
     141
     142     # Returns the number of rows
     143     int CPXgetnumrows(c_cpxlp * env, c_cpxlp * lp)
     144
     145     # Returns the number of columns
     146     int CPXgetnumcols(c_cpxlp * env, c_cpxlp * lp)
     147     
     148     # Write the problem to a file
     149     int CPXwriteprob(c_cpxlp * env, c_cpxlp * lp, char * filename_str, char * filetype_str)
     150
     151     # Get the problem's type
     152     int CPXgetprobtype(c_cpxlp * env, c_cpxlp * lp)
     153
     154     # CONSTANTS
     155     int CPX_ON = 1
     156     int CPX_PARAM_SCRIND = 1035
     157     int CPX_INFBOUND = 1.0E+20
     158     int CPX_PARAM_POPULATELIM = 2108
     159     int CPX_PARAM_SOLNPOOLGAP = 2105
     160     int CPX_PARAM_SOLNPOOLINTENSITY = 2107
     161     int CPX_MAX = -1
     162     int CPX_MIN = 1
     163
     164
     165   
  • new file sage/numerical/backends/cplex_backend.pyx

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/cplex_backend.pyx
    - +  
     1r"""
     2CPLEX Backend
     3"""
     4
     5from sage.numerical.mip import MIPSolverException
     6
     7cdef class CPLEXBackend(GenericBackend):
     8
     9    def __cinit__(self, maximization = True):
     10
     11        cdef int status
     12        self.env = CPXopenCPLEX (&status)
     13        check(status)
     14
     15        cdef char * tmp = ""
     16        self.lp = CPXcreateprob (self.env, &status, tmp);
     17        check(status)
     18
     19        if maximization:
     20            self.set_direction(+1)
     21        else:
     22            self.set_direction(-1)
     23
     24    cpdef int add_variable(self):
     25        r"""
     26        Adds a variable.
     27
     28        This amounts to adding a new column to the matrix. By default,
     29        the variable is both positive and real.
     30
     31        EXAMPLE::
     32
     33            sage: from sage.numerical.backends.generic_backend import getSolver
     34            sage: p = getSolver(solver = "CPLEX")                    # optional - CPLEX
     35            sage: p.n_cols()                                         # optional - CPLEX
     36            0
     37            sage: p.add_variable()                                   # optional - CPLEX
     38            1
     39            sage: p.n_cols()                                         # optional - CPLEX
     40            1
     41        """
     42
     43        cdef int status
     44        status = CPXnewcols(self.env, self.lp, 1, NULL, NULL, NULL, NULL, NULL)
     45        check(status)
     46        return CPXgetnumcols(self.env, self.lp)
     47
     48    cpdef int add_variables(self, int number):
     49        r"""
     50        Adds ``number`` variables.
     51
     52        This amounts to adding new columns to the matrix. By default,
     53        the variables are both positive and real.
     54
     55        EXAMPLE::
     56
     57            sage: from sage.numerical.backends.generic_backend import getSolver
     58            sage: p = getSolver(solver = "CPLEX")                    # optional - CPLEX
     59            sage: p.n_cols()                                         # optional - CPLEX
     60            0
     61            sage: p.add_variables(5)                                 # optional - CPLEX
     62            5
     63            sage: p.n_cols()                                         # optional - CPLEX
     64            5
     65        """
     66
     67        cdef int status
     68        status = CPXnewcols(self.env, self.lp, number, NULL, NULL, NULL, NULL, NULL)
     69        check(status)
     70        return CPXgetnumcols(self.env, self.lp)
     71
     72    cpdef set_variable_type(self, int variable, int vtype):
     73        r"""
     74        Sets the type of a variable
     75
     76        INPUT:
     77
     78        - ``variable`` (integer) -- the variable's id
     79
     80        - ``vtype`` (integer) :
     81
     82            *  1  Integer
     83            *  0  Binary
     84            * -1 Real
     85
     86        EXAMPLE::
     87
     88            sage: from sage.numerical.backends.generic_backend import getSolver
     89            sage: p = getSolver(solver = "CPLEX")   # optional - CPLEX
     90            sage: p.n_cols()                                        # optional - CPLEX
     91            0
     92            sage: p.add_variable()                                  # optional - CPLEX
     93            1
     94            sage: p.set_variable_type(0,1)                          # optional - CPLEX
     95            sage: p.is_variable_integer(0)                          # optional - CPLEX
     96            True
     97        """
     98
     99        cdef int status
     100
     101        cdef char type
     102        if vtype == 1:
     103            type = 'I'
     104        elif vtype == 0:
     105            type = 'B'
     106        else:
     107            type = 'C'
     108
     109        status = CPXchgctype(self.env, self.lp, 1, &variable, &type)
     110        check(status)
     111     
     112    cpdef set_direction(self, int sense):
     113        r"""
     114        Sets the direction (maximization/minimization).
     115
     116        INPUT:
     117
     118        - ``sense`` (integer) :
     119
     120            * +1 => Maximization
     121            * -1 => Minimization
     122
     123        EXAMPLE::
     124
     125            sage: from sage.numerical.backends.generic_backend import getSolver
     126            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     127            sage: p.is_maximization()                              # optional - CPLEX
     128            True
     129            sage: p.set_direction(-1)                              # optional - CPLEX
     130            sage: p.is_maximization()                              # optional - CPLEX
     131            False
     132        """
     133
     134        CPXchgobjsen(self.env, self.lp, -sense)
     135
     136    cpdef set_objective_coeff(self, int variable, double coeff):
     137        r"""
     138        Sets the coefficient of a variable in the objective function
     139
     140        INPUT:
     141
     142        - ``variable`` (integer) -- the variable's id
     143
     144        - ``coeff`` (double) -- its coefficient
     145
     146        EXAMPLE::
     147
     148            sage: from sage.numerical.backends.generic_backend import getSolver
     149            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     150            sage: p.add_variable()                                 # optional - CPLEX
     151            1
     152            sage: p.get_objective_coeff(0)                         # optional - CPLEX
     153            0.0
     154            sage: p.set_objective_coeff(0,2)                       # optional - CPLEX
     155            sage: p.get_objective_coeff(0)                         # optional - CPLEX
     156            2.0
     157        """
     158
     159        cdef int status
     160        status = CPXchgobj(self.env, self.lp, 1, &variable, &coeff)
     161        check(status)
     162
     163    cpdef set_problem_name(self, char * name):
     164        r"""
     165        Sets the problem's name
     166
     167        INPUT:
     168
     169        - ``name`` (``char *``) -- the problem's name
     170
     171        EXAMPLE::
     172
     173            sage: from sage.numerical.backends.generic_backend import getSolver
     174            sage: p = getSolver(solver = "CPLEX")   # optional - CPLEX
     175            sage: p.set_problem_name("There once was a french fry") # optional - CPLEX
     176            sage: print p.get_problem_name()                        # optional - CPLEX
     177            There once was a french fry
     178        """
     179
     180        cdef int status
     181        status = CPXchgprobname(self.env, self.lp, name)
     182        check(status)
     183
     184
     185    cpdef get_problem_name(self):
     186        r"""
     187        Returns the problem's name
     188
     189        EXAMPLE::
     190
     191            sage: from sage.numerical.backends.generic_backend import getSolver
     192            sage: p = getSolver(solver = "CPLEX")   # optional - CPLEX
     193            sage: p.set_problem_name("There once was a french fry") # optional - CPLEX
     194            sage: print p.get_problem_name()                        # optional - CPLEX
     195            There once was a french fry
     196        """
     197
     198        cdef int status
     199        cdef int zero
     200        cdef char * name = <char*> sage_malloc(500*sizeof(char))
     201        status = CPXgetprobname(self.env, self.lp, name, 500, &zero)
     202        check(status)
     203
     204        s = str(name)
     205        sage_free(name)
     206
     207        return s
     208
     209    cpdef set_objective(self, list coeff):
     210        r"""
     211        Sets the objective function.
     212
     213        INPUT:
     214
     215        - ``coeff`` -- a list of real values, whose ith element is the
     216          coefficient of the ith variable in the objective function.
     217
     218        EXAMPLE::
     219
     220            sage: from sage.numerical.backends.generic_backend import getSolver
     221            sage: p = getSolver(solver = "CPLEX")    # optional - CPLEX
     222            sage: p.add_variables(5)                                 # optional - CPLEX
     223            5
     224            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - CPLEX
     225            sage: map(lambda x :p.get_objective_coeff(x), range(5))  # optional - CPLEX
     226            [1.0, 1.0, 2.0, 1.0, 3.0]
     227        """
     228
     229        cdef int status
     230        cdef int n = self.n_cols()
     231        cdef double * c_coeff = <double *> sage_malloc(n * sizeof(double))
     232        cdef int * c_indices = <int *> sage_malloc(n * sizeof(int))
     233       
     234        for i,v in enumerate(coeff):
     235            c_coeff[i] = v
     236            c_indices[i] = i
     237
     238        status = CPXchgobj(self.env, self.lp, n, c_indices, c_coeff)
     239        check(status)
     240
     241
     242    cpdef set_log_level(self, int level):
     243        r"""
     244        Sets the log (verbosity) level
     245
     246        INPUT:
     247
     248        - ``level`` (integer) -- From 0 (no verbosity) to 3.
     249
     250        EXAMPLE::
     251
     252            sage: from sage.numerical.backends.generic_backend import getSolver
     253            sage: p = getSolver(solver = "CPLEX")   # optional - CPLEX
     254            sage: p.set_log_level(2)                                # optional - CPLEX
     255
     256        """
     257
     258        cdef int status
     259        if level == 0:
     260            status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, 0)
     261            check(status)
     262        else:
     263            status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, CPX_ON)
     264            check(status)
     265
     266    cpdef add_constraints(self, int number, int direction, double bound):
     267        r"""
     268        Adds constraints.
     269
     270        INPUT:
     271
     272        - ``number`` (integer) -- the number of constraints to add.
     273
     274        - ``direction`` (integer) -- the direction of the constraint,
     275          where :
     276
     277              * +1 indicates : function `\leq` ``bound``
     278              *  0 indicates : function `=` ``bound``
     279              * -1 indicates : function `\geq` ``bound``
     280
     281        - ``bound`` (double) -- value of the right-hand side (as
     282          illustrated immediately above).
     283
     284        EXAMPLE::
     285
     286            sage: from sage.numerical.backends.generic_backend import getSolver
     287            sage: p = getSolver(solver = "CPLEX")   # optional - CPLEX
     288            sage: p.add_variables(5)                                # optional - CPLEX
     289            5
     290            sage: p.add_constraints(5, +1, 2)                       # optional - CPLEX
     291            sage: p.get_row(4)                                      # optional - CPLEX
     292            ([], [])
     293            sage: p.get_row_bounds(4)                               # optional - CPLEX
     294            (None, 2.0)
     295        """
     296
     297        cdef char * c_types = <char *> sage_malloc(number * sizeof(char))
     298        cdef double * c_bounds = <double *> sage_malloc(number * sizeof(double))
     299        cdef int i
     300        cdef int status
     301
     302        c_bounds[0] = bound
     303       
     304        if direction == +1:
     305            c_types[0] = 'L'
     306        elif direction == -1:
     307            c_types[0] = 'G'
     308        else:
     309            c_types[0] = 'E'
     310
     311        for 1<= i < number:
     312            c_types[i] = c_types[0]
     313            c_bounds[i] = c_bounds[0]
     314       
     315
     316        status = CPXnewrows(self.env, self.lp, number, c_bounds, c_types, NULL, NULL)
     317        check(status)
     318
     319    cpdef add_constraint(self, list indices, list coeffs, int direction, double bound):
     320        r"""
     321        Adds a constraint.
     322
     323        INPUT:
     324
     325        - ``indices`` (list of integers) -- this list constains the
     326          indices of the variables whose coefficient is nonzero in the
     327          constraint.
     328
     329        - ``coeffs`` (list of real values) -- associates a coefficient
     330          to the variables listed by ``indices``. Namely, the ith
     331          entry of ``coeffs`` corresponds to the coefficient of the
     332          variable represented by the ith entry in ``indices``.
     333
     334        - ``direction`` (integer) -- the direction of the constraint,
     335          where :
     336
     337              * +1 indicates : function `\leq` ``bound``
     338              *  0 indicates : function `=` ``bound``
     339              * -1 indicates : function `\geq` ``bound``
     340
     341        - ``bound`` (double) -- value of the right-hand side (as
     342          illustrated immediately above).
     343
     344        .. NOTE::
     345
     346            ``indices`` and ``coeffs`` are expected to be of the same
     347            length.
     348
     349        EXAMPLE::
     350
     351            sage: from sage.numerical.backends.generic_backend import getSolver
     352            sage: p = getSolver(solver = "CPLEX") # optional - CPLEX
     353            sage: p.add_variables(5)                              # optional - CPLEX
     354            5
     355            sage: p.add_constraint(range(5), range(5), 0, 2)      # optional - CPLEX
     356            sage: p.get_row(0)                                    # optional - CPLEX
     357            ([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])
     358            sage: p.get_row_bounds(0)                             # optional - CPLEX
     359            (2.0, 2.0)
     360        """
     361
     362        cdef int status
     363        cdef int i
     364        cdef int n = len(indices)
     365        cdef int n_rows = self.n_rows()
     366        cdef char sense
     367
     368        if direction == 1:
     369            sense = 'L'
     370        elif direction == -1:
     371            sense = 'G'
     372        else:
     373            sense = 'E'
     374       
     375        status = CPXnewrows(self.env, self.lp, 1, &bound, &sense, NULL, NULL)
     376        check(status)
     377
     378        cdef double * c_coeff = <double *> sage_malloc(n * sizeof(double))
     379        cdef int * c_indices = <int *> sage_malloc(n * sizeof(int))
     380        cdef int * c_row = <int *> sage_malloc(n * sizeof(int))
     381       
     382        for 0<= i < n:
     383            c_coeff[i] = coeffs[i]
     384            c_indices[i] = indices[i]
     385            c_row[i] = n_rows
     386
     387
     388        status = CPXchgcoeflist(self.env, self.lp, n, c_row, c_indices, c_coeff)
     389        check(status)
     390
     391    cpdef get_row(self, int index):
     392        r"""
     393        Returns a row
     394
     395        INPUT:
     396
     397        - ``index`` (integer) -- the constraint's id.
     398
     399        OUTPUT:
     400
     401        A pair ``(indices, coeffs)`` where ``indices`` lists the
     402        entries whose coefficient is nonzero, and to which ``coeffs``
     403        associates their coefficient on the model of the
     404        ``add_constraint`` method.
     405
     406        EXAMPLE::
     407
     408            sage: from sage.numerical.backends.generic_backend import getSolver
     409            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     410            sage: p.add_variables(5)                               # optional - CPLEX
     411            5
     412            sage: p.add_constraint(range(5), range(5), 0, 2)       # optional - CPLEX
     413            sage: p.get_row(0)                                     # optional - CPLEX
     414            ([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])
     415            sage: p.get_row_bounds(0)                              # optional - CPLEX
     416            (2.0, 2.0)
     417        """
     418
     419        cdef int status
     420        cdef int n,i
     421        cdef int zero
     422        cdef list indices = []
     423        cdef list values = []
     424
     425        cdef double * c_coeff = <double *> sage_malloc((self.n_cols()+10) * sizeof(double))
     426        cdef int * c_indices = <int *> sage_malloc((self.n_cols()+10) * sizeof(int))
     427
     428        status = CPXgetrows(self.env, self.lp, &n, &zero, c_indices, c_coeff, self.n_cols()+3, &zero, index, index)
     429
     430        check(status)
     431
     432        for 0<= i<n:
     433            indices.append(c_indices[i])
     434            values.append(c_coeff[i])
     435
     436        sage_free(c_coeff)
     437        sage_free(c_indices)
     438
     439        return (indices, values)
     440
     441    cpdef get_row_bounds(self, int index):
     442        r"""
     443        Returns the bounds of a specific constraint.
     444
     445        INPUT:
     446
     447        - ``index`` (integer) -- the constraint's id.
     448
     449        OUTPUT:
     450
     451        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     452        to ``None`` if the constraint is not bounded in the
     453        corresponding direction, and is a real value otherwise.
     454
     455        EXAMPLE::
     456
     457            sage: from sage.numerical.backends.generic_backend import getSolver
     458            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     459            sage: p.add_variables(5)                               # optional - CPLEX
     460            5
     461            sage: p.add_constraint(range(5), range(5), 0, 2)       # optional - CPLEX
     462            sage: p.get_row(0)                                     # optional - CPLEX
     463            ([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])
     464            sage: p.get_row_bounds(0)                              # optional - CPLEX
     465            (2.0, 2.0)
     466        """
     467
     468        cdef int status
     469        cdef double value
     470        status = CPXgetrhs(self.env, self.lp, &value, index, index)
     471        check(status)
     472
     473        cdef char direction
     474        status = CPXgetsense(self.env, self.lp, &direction, index, index)
     475        check(status)
     476
     477        if direction == 'L':
     478            return (None, value)
     479        elif direction == 'G':
     480            return (value, None)
     481        else:
     482            return (value, value)
     483
     484    cpdef get_col_bounds(self, int index):
     485        r"""
     486        Returns the bounds of a specific variable.
     487
     488        INPUT:
     489
     490        - ``index`` (integer) -- the variable's id.
     491
     492        OUTPUT:
     493
     494        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     495        to ``None`` if the variable is not bounded in the
     496        corresponding direction, and is a real value otherwise.
     497
     498        EXAMPLE::
     499
     500            sage: from sage.numerical.backends.generic_backend import getSolver
     501            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     502            sage: p.add_variable()                                 # optional - CPLEX
     503            1
     504            sage: p.get_col_bounds(0)                              # optional - CPLEX
     505            (0.0, None)
     506            sage: p.set_variable_max(0, 5)                         # optional - CPLEX
     507            sage: p.get_col_bounds(0)                              # optional - CPLEX
     508            (0.0, 5.0)
     509        """
     510
     511        cdef int status
     512        cdef double ub
     513        cdef double lb
     514
     515        status = CPXgetub(self.env, self.lp, &ub, index, index)
     516        check(status)
     517
     518        status = CPXgetlb(self.env, self.lp, &lb, index, index)
     519        check(status)
     520
     521        return (lb if lb != -CPX_INFBOUND else None,
     522                ub if ub != +CPX_INFBOUND else None)
     523
     524    cpdef double get_objective_coeff(self, int index):
     525        r"""
     526        Sets the coefficient of a variable in the objective function
     527
     528        INPUT:
     529
     530        - ``variable`` (integer) -- the variable's id
     531
     532        - ``coeff`` (double) -- its coefficient
     533
     534        EXAMPLE::
     535
     536            sage: from sage.numerical.backends.generic_backend import getSolver
     537            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     538            sage: p.add_variable()                                 # optional - CPLEX
     539            1
     540            sage: p.get_objective_coeff(0)                         # optional - CPLEX
     541            0.0
     542            sage: p.set_objective_coeff(0,2)                       # optional - CPLEX
     543            sage: p.get_objective_coeff(0)                         # optional - CPLEX
     544            2.0
     545        """
     546
     547        cdef int status
     548        cdef double value
     549        status = CPXgetobj(self.env, self.lp, &value, index, index)
     550        check(status)
     551        return value
     552           
     553
     554    cpdef add_col(self, list indices, list coeffs):
     555        r"""
     556        Adds a column.
     557
     558        INPUT:
     559
     560        - ``indices`` (list of integers) -- this list constains the
     561          indices of the constraints in which the variable's
     562          coefficient is nonzero
     563
     564        - ``coeffs`` (list of real values) -- associates a coefficient
     565          to the variable in each of the constraints in which it
     566          appears. Namely, the ith entry of ``coeffs`` corresponds to
     567          the coefficient of the variable in the constraint
     568          represented by the ith entry in ``indices``.
     569
     570        .. NOTE::
     571
     572            ``indices`` and ``coeffs`` are expected to be of the same
     573            length.
     574
     575        EXAMPLE::
     576
     577            sage: from sage.numerical.backends.generic_backend import getSolver
     578            sage: p = getSolver(solver = "CPLEX")                  # optional - CPLEX
     579            sage: p.n_cols()                                       # optional - CPLEX
     580            0
     581            sage: p.n_rows()                                       # optional - CPLEX
     582            0
     583            sage: p.add_constraints(5, -1, 0)                      # optional - CPLEX
     584            sage: p.add_col(range(5), range(5))                    # optional - CPLEX
     585            sage: p.n_rows()                                       # optional - CPLEX
     586            5
     587        """
     588
     589        cdef int status
     590        cdef int i
     591        cdef int n = len(indices)
     592        cdef int n_cols = self.n_cols()
     593
     594        status = CPXnewcols(self.env, self.lp, 1, NULL, NULL, NULL, NULL, NULL)
     595
     596
     597        check(status)
     598
     599        cdef double * c_coeff = <double *> sage_malloc(n * sizeof(double))
     600        cdef int * c_indices = <int *> sage_malloc(n * sizeof(int))
     601        cdef int * c_col = <int *> sage_malloc(n * sizeof(int))
     602       
     603        for 0<= i < n:
     604            c_coeff[i] = coeffs[i]
     605            c_indices[i] = indices[i]
     606            c_col[i] = n_cols
     607
     608
     609        status = CPXchgcoeflist(self.env, self.lp, n, c_indices, c_col, c_coeff)
     610        check(status)
     611
     612    cpdef int solve(self) except -1:
     613        r"""
     614        Solves the problem.
     615
     616        .. NOTE::
     617
     618            This method raises ``MIPSolverException`` exceptions when
     619            the solution can not be computed for any reason (none
     620            exists, or the LP solver was not able to find it, etc...)
     621
     622        EXAMPLE::
     623
     624            sage: from sage.numerical.backends.generic_backend import getSolver
     625            sage: p = getSolver(solver = "CPLEX") # optional - CPLEX
     626            sage: p.add_constraints(5, -1, 0)                     # optional - CPLEX
     627            sage: p.add_col(range(5), range(5))                   # optional - CPLEX
     628            sage: p.solve()                                       # optional - CPLEX
     629            0
     630            sage: p.set_objective_coeff(0,1)                      # optional - CPLEX
     631            sage: p.solve()                                       # optional - CPLEX
     632            Traceback (most recent call last):
     633            ...
     634            MIPSolverException: ...
     635        """
     636   
     637        cdef int status
     638        cdef int ptype
     639        cdef int solnmethod_p, solntype_p, pfeasind_p, dfeasind_p
     640
     641        ptype = CPXgetprobtype(self.env, self.lp)
     642
     643        if ptype == 1:
     644            status = CPXmipopt(self.env, self.lp)
     645        elif ptype == 0:
     646            status = CPXlpopt(self.env, self.lp)
     647        else:
     648            raise MIPSolverException("CPLEX: Unknown problem type")
     649
     650        check(status)
     651
     652        status = CPXsolninfo(self.env, self.lp, &solnmethod_p, &solntype_p, &pfeasind_p, &dfeasind_p)
     653        check(status)
     654
     655        if not pfeasind_p:
     656            raise MIPSolverException("CPLEX: The primal has no feasible solution")
     657        if not dfeasind_p:
     658            raise MIPSolverException("CPLEX: The problem is unbounded")
     659
     660
     661        return 0
     662
     663
     664    cpdef double get_objective_value(self):
     665        r"""
     666        Returns the value of the objective function.
     667
     668        .. NOTE::
     669
     670           Has no meaning unless ``solve`` has been called before.
     671
     672        EXAMPLE::
     673
     674            sage: from sage.numerical.backends.generic_backend import getSolver
     675            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     676            sage: p.add_variables(2)                               # optional - CPLEX
     677            2
     678            sage: p.add_constraint([0, 1], [1, 2], +1, 3)          # optional - CPLEX
     679            sage: p.set_objective([2, 5])                          # optional - CPLEX
     680            sage: p.solve()                                        # optional - CPLEX
     681            0
     682            sage: p.get_objective_value()                          # optional - CPLEX
     683            7.5
     684            sage: p.get_variable_value(0)                          # optional - CPLEX
     685            0.0
     686            sage: p.get_variable_value(1)                          # optional - CPLEX
     687            1.5
     688        """
     689
     690        cdef int status
     691        cdef double value
     692        status = CPXgetobjval (self.env, self.lp, &value)
     693        check(status)
     694
     695        return value
     696
     697
     698    cpdef double get_variable_value(self, int variable):
     699        r"""
     700        Returns the value of a variable given by the solver.
     701
     702        .. NOTE::
     703
     704           Has no meaning unless ``solve`` has been called before.
     705
     706        EXAMPLE::
     707
     708            sage: from sage.numerical.backends.generic_backend import getSolver
     709            sage: p = getSolver(solver = "CPLEX") # optional - CPLEX
     710            sage: p.add_variables(2)                              # optional - CPLEX
     711            2
     712            sage: p.add_constraint([0, 1], [1, 2], +1, 3)         # optional - CPLEX
     713            sage: p.set_objective([2, 5])                         # optional - CPLEX
     714            sage: p.solve()                                       # optional - CPLEX
     715            0
     716            sage: p.get_objective_value()                         # optional - CPLEX
     717            7.5
     718            sage: p.get_variable_value(0)                         # optional - CPLEX
     719            0.0
     720            sage: p.get_variable_value(1)                         # optional - CPLEX
     721            1.5
     722        """
     723
     724        cdef int status
     725        cdef int zero
     726        cdef double value
     727        status = CPXgetx(self.env, self.lp, &value, variable, variable)
     728        check(status)
     729
     730        return value
     731
     732
     733    cpdef int n_cols(self):
     734        r"""
     735        Returns the number of columns/variables.
     736
     737        EXAMPLE::
     738
     739            sage: from sage.numerical.backends.generic_backend import getSolver
     740            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     741            sage: p.n_cols()                                       # optional - CPLEX
     742            0
     743            sage: p.add_variables(2)                               # optional - CPLEX
     744            2
     745            sage: p.n_cols()                                       # optional - CPLEX
     746            2
     747        """
     748
     749        return CPXgetnumcols(self.env, self.lp)
     750
     751    cpdef int n_rows(self):
     752        r"""
     753        Returns the number of rows/constraints.
     754
     755        EXAMPLE::
     756
     757            sage: from sage.numerical.backends.generic_backend import getSolver
     758            sage: p = getSolver(solver = "CPLEX") # optional - CPLEX
     759            sage: p.n_rows()                                      # optional - CPLEX
     760            0
     761            sage: p.add_constraints(2, -1, 2)                     # optional - CPLEX
     762            sage: p.n_rows()                                      # optional - CPLEX
     763            2
     764        """
     765
     766        return CPXgetnumrows(self.env, self.lp)
     767
     768    cpdef get_row_name(self, int index):
     769        r"""
     770        Returns the ``index`` th row name
     771
     772        INPUT:
     773
     774        - ``index`` (integer) -- the row's id
     775
     776        EXAMPLE::
     777
     778            sage: from sage.numerical.backends.generic_backend import getSolver
     779            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     780            sage: p.add_variable()                                 # optional - CPLEX
     781            1
     782            sage: p.set_col_name(0, "I am a variable")             # optional - CPLEX
     783            sage: p.get_col_name(0)                                # optional - CPLEX
     784            'I am a variable'
     785        """
     786
     787        cdef int status
     788        cdef int zero
     789        cdef char * name = <char *>sage_malloc(500*sizeof(char))
     790        status = CPXgetrowname(self.env, self.lp, &name, name, 500, &zero, index, index)
     791        if status == 1219:
     792            sage_free(name)
     793            return ""
     794        check(status)
     795
     796        s = str(name)
     797        sage_free(name)
     798
     799        return s
     800
     801    cpdef set_row_name(self, int index, char * name):
     802        r"""
     803        Sets the ``index`` th row name
     804
     805        INPUT:
     806
     807        - ``index`` (integer) -- the row's id
     808
     809        - ``name`` (``char *``) -- its name
     810
     811        EXAMPLE::
     812
     813            sage: from sage.numerical.backends.generic_backend import getSolver
     814            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     815            sage: p.add_constraints(1, -1, 2)                      # optional - CPLEX
     816            sage: p.set_row_name(0, "Empty constraint 1")          # optional - CPLEX
     817            sage: p.get_row_name(0)                                # optional - CPLEX
     818            'Empty constraint 1'
     819
     820        """
     821
     822        cdef int status
     823
     824        status = CPXchgrowname(self.env, self.lp, 1, &index, &name)
     825        check(status)
     826
     827    cpdef set_col_name(self, int index, char * name):
     828        r"""
     829        Sets the ``index`` th col name
     830
     831        INPUT:
     832
     833        - ``index`` (integer) -- the col's id
     834
     835        - ``name`` (``char *``) -- its name
     836
     837        EXAMPLE::
     838
     839            sage: from sage.numerical.backends.generic_backend import getSolver
     840            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     841            sage: p.add_variable()                                 # optional - CPLEX
     842            1
     843            sage: p.set_col_name(0, "I am a variable")             # optional - CPLEX
     844            sage: p.get_col_name(0)                                # optional - CPLEX
     845            'I am a variable'
     846        """
     847
     848        cdef int status
     849        status = CPXchgcolname(self.env, self.lp, 1, &index, &name)
     850        check(status)
     851
     852
     853    cpdef get_col_name(self, int index):
     854        r"""
     855        Returns the ``index`` th variable name
     856
     857        INPUT:
     858
     859        - ``index`` (integer) -- the variable's id
     860
     861        EXAMPLE::
     862
     863            sage: from sage.numerical.backends.generic_backend import getSolver
     864            sage: p = getSolver(solver = "CPLEX")                  # optional - CPLEX
     865            sage: p.add_variable()                                 # optional - CPLEX
     866            1
     867            sage: p.set_col_name(0, "I am a variable")             # optional - CPLEX
     868            sage: p.get_col_name(0)                                # optional - CPLEX
     869            'I am a variable'
     870        """
     871
     872        cdef int status
     873        cdef int zero
     874        cdef char * name = <char *>sage_malloc(500*sizeof(char))
     875        status = CPXgetcolname(self.env, self.lp, &name, name, 500, &zero, index, index)
     876        if status == 1219:
     877            sage_free(name)
     878            return ""
     879        check(status)
     880
     881        s = str(name)
     882        sage_free(name)
     883
     884
     885        return s
     886
     887
     888    cpdef bint is_variable_binary(self, int index):
     889        r"""
     890        Tests whether the given variable is of binary type.
     891
     892        INPUT:
     893
     894        - ``index`` (integer) -- the variable's id
     895
     896        EXAMPLE::
     897
     898            sage: from sage.numerical.backends.generic_backend import getSolver
     899            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     900            sage: p.n_cols()                                       # optional - CPLEX
     901            0
     902            sage: p.add_variable()                                 # optional - CPLEX
     903            1
     904            sage: p.set_variable_type(0,0)                         # optional - CPLEX
     905            sage: p.is_variable_binary(0)                          # optional - CPLEX
     906            True
     907
     908        """
     909
     910        cdef int status
     911        cdef char ctype
     912
     913        status = CPXgetctype(self.env, self.lp, &ctype, index, index)
     914
     915        # status = 3003 when the problem is a LP and not a MILP
     916        if status == 3003:
     917            return False
     918
     919        check(status)
     920
     921        return ctype == 'B'
     922
     923
     924    cpdef bint is_variable_integer(self, int index):
     925        r"""
     926        Tests whether the given variable is of integer type.
     927
     928        INPUT:
     929
     930        - ``index`` (integer) -- the variable's id
     931
     932        EXAMPLE::
     933
     934            sage: from sage.numerical.backends.generic_backend import getSolver
     935            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     936            sage: p.n_cols()                                       # optional - CPLEX
     937            0
     938            sage: p.add_variable()                                 # optional - CPLEX
     939            1
     940            sage: p.set_variable_type(0,1)                         # optional - CPLEX
     941            sage: p.is_variable_integer(0)                         # optional - CPLEX
     942            True
     943        """
     944
     945        cdef int status
     946        cdef char ctype
     947
     948        status = CPXgetctype(self.env, self.lp, &ctype, index, index)
     949
     950        # status = 3003 when the problem is a LP and not a MILP
     951        if status == 3003:
     952            return False
     953
     954        check(status)
     955
     956        return ctype == 'I'
     957
     958
     959    cpdef bint is_variable_continuous(self, int index):
     960        r"""
     961        Tests whether the given variable is of continuous/real type.
     962
     963        INPUT:
     964
     965        - ``index`` (integer) -- the variable's id
     966
     967        EXAMPLE::
     968
     969            sage: from sage.numerical.backends.generic_backend import getSolver
     970            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     971            sage: p.n_cols()                                       # optional - CPLEX
     972            0
     973            sage: p.add_variable()                                 # optional - CPLEX
     974            1
     975            sage: p.is_variable_continuous(0)                      # optional - CPLEX
     976            True
     977            sage: p.set_variable_type(0,1)                         # optional - CPLEX
     978            sage: p.is_variable_continuous(0)                      # optional - CPLEX
     979            False
     980
     981        """
     982
     983        cdef int status
     984        cdef char ctype
     985
     986        status = CPXgetctype(self.env, self.lp, &ctype, index, index)
     987
     988        # status = 3003 when the problem is a LP and not a MILP
     989        if status == 3003:
     990            return True
     991
     992        check(status)
     993
     994        return ctype == 'C'
     995
     996
     997    cpdef bint is_maximization(self):
     998        r"""
     999        Tests whether the problem is a maximization
     1000
     1001        EXAMPLE::
     1002
     1003            sage: from sage.numerical.backends.generic_backend import getSolver
     1004            sage: p = getSolver(solver = "CPLEX") # optional - CPLEX
     1005            sage: p.is_maximization()                             # optional - CPLEX
     1006            True
     1007            sage: p.set_direction(-1)                             # optional - CPLEX
     1008            sage: p.is_maximization()                             # optional - CPLEX
     1009            False
     1010        """
     1011
     1012        return -1 == CPXgetobjsen(self.env, self.lp)
     1013
     1014    cpdef get_variable_max(self, int index):
     1015        r"""
     1016        Returns the upper bound on a variable
     1017
     1018        INPUT:
     1019
     1020        - ``index`` (integer) -- the variable's id
     1021
     1022        OUTPUT:
     1023
     1024        A real value if the variable has an upper bound, ``None``
     1025        otherwise.
     1026
     1027        EXAMPLE::
     1028
     1029            sage: from sage.numerical.backends.generic_backend import getSolver
     1030            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     1031            sage: p.add_variable()                                 # optional - CPLEX
     1032            1
     1033            sage: p.get_variable_max(0) is None                    # optional - CPLEX
     1034            True
     1035            sage: p.set_variable_max(0, 5)                         # optional - CPLEX
     1036            sage: p.get_variable_max(0)                            # optional - CPLEX
     1037            5.0
     1038
     1039        """
     1040
     1041        cdef int status
     1042        cdef double ub
     1043
     1044        status = CPXgetub(self.env, self.lp, &ub, index, index)
     1045        check(status)
     1046
     1047        return ub if ub != CPX_INFBOUND else None
     1048
     1049    cpdef get_variable_min(self, int index):
     1050        r"""
     1051        Returns the lower bound on a variable
     1052
     1053        INPUT:
     1054
     1055        - ``index`` (integer) -- the variable's id
     1056
     1057        OUTPUT:
     1058
     1059        A real value if the variable has an lower bound, ``None``
     1060        otherwise.
     1061
     1062        EXAMPLE::
     1063
     1064            sage: from sage.numerical.backends.generic_backend import getSolver
     1065            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     1066            sage: p.add_variable()                                 # optional - CPLEX
     1067            1
     1068            sage: p.get_variable_min(0)                            # optional - CPLEX
     1069            0.0
     1070            sage: p.set_variable_min(0, 5)                         # optional - CPLEX
     1071            sage: p.get_variable_min(0)                            # optional - CPLEX
     1072            5.0
     1073        """
     1074
     1075        cdef int status
     1076        cdef double lb
     1077
     1078        status = CPXgetlb(self.env, self.lp, &lb, index, index)
     1079        check(status)
     1080
     1081        return lb if lb != -CPX_INFBOUND else None
     1082
     1083    cpdef set_variable_max(self, int index, value):
     1084        r"""
     1085        Sets the upper bound on a variable
     1086
     1087        INPUT:
     1088
     1089        - ``index`` (integer) -- the variable's id
     1090
     1091        - ``value`` -- real value, or ``None`` to mean that the
     1092          variable has not upper bound.
     1093
     1094        EXAMPLE::
     1095
     1096            sage: from sage.numerical.backends.generic_backend import getSolver
     1097            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     1098            sage: p.add_variable()                                 # optional - CPLEX
     1099            1
     1100            sage: p.get_col_bounds(0)                              # optional - CPLEX
     1101            (0.0, None)
     1102            sage: p.set_variable_max(0, 5)                         # optional - CPLEX
     1103            sage: p.get_col_bounds(0)                              # optional - CPLEX
     1104            (0.0, 5.0)
     1105        """
     1106
     1107        cdef int status
     1108        cdef char x = 'U'
     1109        cdef double c_value = value if value is not None else +CPX_INFBOUND
     1110        status = CPXchgbds(self.env, self.lp, 1, &index, &x, &c_value)
     1111        check(status)
     1112
     1113    cpdef set_variable_min(self, int index, value):
     1114        r"""
     1115        Sets the lower bound on a variable
     1116
     1117        INPUT:
     1118
     1119        - ``index`` (integer) -- the variable's id
     1120
     1121        - ``value`` -- real value, or ``None`` to mean that the
     1122          variable has not lower bound.
     1123
     1124        EXAMPLE::
     1125
     1126            sage: from sage.numerical.backends.generic_backend import getSolver
     1127            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     1128            sage: p.add_variable()                                 # optional - CPLEX
     1129            1
     1130            sage: p.get_col_bounds(0)                              # optional - CPLEX
     1131            (0.0, None)
     1132            sage: p.set_variable_min(0, 5)                         # optional - CPLEX
     1133            sage: p.get_col_bounds(0)                              # optional - CPLEX
     1134            (5.0, None)
     1135        """
     1136
     1137        cdef int status
     1138        cdef char x = 'L'
     1139        cdef double c_value = value if value is not None else -CPX_INFBOUND
     1140        status = CPXchgbds(self.env, self.lp, 1, &index, &x, &c_value)
     1141        check(status)
     1142   
     1143    cpdef write_lp(self, char * filename):
     1144        r"""
     1145        Writes the problem to a .lp file
     1146
     1147        INPUT:
     1148       
     1149        - ``filename`` (string)
     1150
     1151        EXAMPLE::
     1152
     1153            sage: from sage.numerical.backends.generic_backend import getSolver
     1154            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     1155            sage: p.add_variables(2)                               # optional - CPLEX
     1156            2
     1157            sage: p.add_constraint([0, 1], [1, 2], +1, 3)          # optional - CPLEX
     1158            sage: p.set_objective([2, 5])                          # optional - CPLEX
     1159            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")            # optional - CPLEX
     1160        """
     1161
     1162        cdef int status
     1163        cdef char * ext = "LP"
     1164        status = CPXwriteprob(self.env, self.lp, filename, ext)
     1165        check(status)
     1166
     1167    cpdef write_mps(self, char * filename, int modern):
     1168        r"""
     1169        Writes the problem to a .mps file
     1170
     1171        INPUT:
     1172       
     1173        - ``filename`` (string)
     1174
     1175        EXAMPLE::
     1176
     1177            sage: from sage.numerical.backends.generic_backend import getSolver
     1178            sage: p = getSolver(solver = "CPLEX")  # optional - CPLEX
     1179            sage: p.add_variables(2)                               # optional - CPLEX
     1180            2
     1181            sage: p.add_constraint([0, 1], [1, 2], +1, 3)          # optional - CPLEX
     1182            sage: p.set_objective([2, 5])                          # optional - CPLEX
     1183            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")            # optional - CPLEX
     1184        """
     1185
     1186        cdef int status
     1187        cdef char * ext = "MPS"
     1188        status = CPXwriteprob(self.env, self.lp, filename, ext)
     1189        check(status)
     1190
     1191    def __dealloc__(self):
     1192        r"""
     1193        Destructor for the class
     1194        """
     1195        CPXcloseCPLEX(self.env)
     1196
     1197cdef check(number):
     1198    r"""
     1199    Given a number, raises the corresponding exception or does nothing
     1200    if ``number == 0``.
     1201
     1202    - ``number`` (integer) -- number corresponding to the error. If
     1203      this number is unknown, the message contained in the raised
     1204      exception will mention it.
     1205    """
     1206
     1207    # Below 1000 are 0 (no error), and some quality reports (but the
     1208    # ERR* codes are above 1000)
     1209    if number > 1000:
     1210        from sage.numerical.mip import MIPSolverException
     1211        default = "Error reported by the solver (unknown error number : "+str(number)+")"
     1212        raise MIPSolverException("CPLEX: "+errors.get(number,default))
     1213
     1214# Error codes
     1215#
     1216# Todo : when common error codes are returned, rewrite the message to
     1217# be more meaningful
     1218
     1219errors = {
     1220    1001 : "CPXERR_NO_MEMORY",
     1221    1002 : "CPXERR_NO_ENVIRONMENT",
     1222    1003 : "CPXERR_BAD_ARGUMENT",
     1223    1004 : "CPXERR_NULL_POINTER",
     1224    1006 : "CPXERR_CALLBACK",
     1225    1009 : "CPXERR_NO_PROBLEM",
     1226    1012 : "CPXERR_LIMITS_TOO_BIG",
     1227    1013 : "CPXERR_BAD_PARAM_NUM",
     1228    1014 : "CPXERR_PARAM_TOO_SMALL",
     1229    1015 : "CPXERR_PARAM_TOO_BIG",
     1230    1016 : "CPXERR_RESTRICTED_VERSION",
     1231    1017 : "CPXERR_NOT_FOR_MIP",
     1232    1018 : "CPXERR_NOT_FOR_QP",
     1233    1019 : "CPXERR_CHILD_OF_CHILD",
     1234    1020 : "CPXERR_TOO_MANY_THREADS",
     1235    1021 : "CPXERR_CANT_CLOSE_CHILD",
     1236    1022 : "CPXERR_BAD_PROB_TYPE",
     1237    1023 : "CPXERR_NOT_ONE_PROBLEM",
     1238    1024 : "CPXERR_NOT_MILPCLASS",
     1239    1026 : "CPXERR_STR_PARAM_TOO_LONG",
     1240    1027 : "CPXERR_DECOMPRESSION",
     1241    1028 : "CPXERR_BAD_PARAM_NAME",
     1242    1029 : "CPXERR_NOT_MIQPCLASS",
     1243    1031 : "CPXERR_NOT_FOR_QCP",
     1244    1051 : "CPXERR_MSG_NO_CHANNEL",
     1245    1052 : "CPXERR_MSG_NO_FILEPTR",
     1246    1053 : "CPXERR_MSG_NO_FUNCTION",
     1247    1101 : "CPXERR_PRESLV_INForUNBD",
     1248    1103 : "CPXERR_PRESLV_NO_PROB",
     1249    1106 : "CPXERR_PRESLV_ABORT",
     1250    1107 : "CPXERR_PRESLV_BASIS_MEM",
     1251    1108 : "CPXERR_PRESLV_COPYSOS",
     1252    1109 : "CPXERR_PRESLV_COPYORDER",
     1253    1110 : "CPXERR_PRESLV_SOLN_MIP",
     1254    1111 : "CPXERR_PRESLV_SOLN_QP",
     1255    1112 : "CPXERR_PRESLV_START_LP",
     1256    1114 : "CPXERR_PRESLV_FAIL_BASIS",
     1257    1115 : "CPXERR_PRESLV_NO_BASIS",
     1258    1117 : "CPXERR_PRESLV_INF",
     1259    1118 : "CPXERR_PRESLV_UNBD",
     1260    1119 : "CPXERR_PRESLV_DUAL",
     1261    1120 : "CPXERR_PRESLV_UNCRUSHFORM",
     1262    1121 : "CPXERR_PRESLV_CRUSHFORM",
     1263    1122 : "CPXERR_PRESLV_BAD_PARAM",
     1264    1123 : "CPXERR_PRESLV_TIME_LIM",
     1265    1200 : "CPXERR_INDEX_RANGE",
     1266    1201 : "CPXERR_COL_INDEX_RANGE",
     1267    1203 : "CPXERR_ROW_INDEX_RANGE",
     1268    1205 : "CPXERR_INDEX_RANGE_LOW",
     1269    1206 : "CPXERR_INDEX_RANGE_HIGH",
     1270    1207 : "CPXERR_NEGATIVE_SURPLUS",
     1271    1208 : "CPXERR_ARRAY_TOO_LONG",
     1272    1209 : "CPXERR_NAME_CREATION",
     1273    1210 : "CPXERR_NAME_NOT_FOUND",
     1274    1211 : "CPXERR_NO_RHS_IN_OBJ",
     1275    1215 : "CPXERR_BAD_SENSE",
     1276    1216 : "CPXERR_NO_RNGVAL",
     1277    1217 : "CPXERR_NO_SOLN",
     1278    1219 : "CPXERR_NO_NAMES",
     1279    1221 : "CPXERR_NOT_FIXED",
     1280    1222 : "CPXERR_DUP_ENTRY",
     1281    1223 : "CPXERR_NO_BARRIER_SOLN",
     1282    1224 : "CPXERR_NULL_NAME",
     1283    1225 : "CPXERR_NAN",
     1284    1226 : "CPXERR_ARRAY_NOT_ASCENDING",
     1285    1227 : "CPXERR_COUNT_RANGE",
     1286    1228 : "CPXERR_COUNT_OVERLAP",
     1287    1229 : "CPXERR_BAD_LUB",
     1288    1230 : "CPXERR_NODE_INDEX_RANGE",
     1289    1231 : "CPXERR_ARC_INDEX_RANGE",
     1290    1232 : "CPXERR_NO_DUAL_SOLN",
     1291    1233 : "CPXERR_DBL_MAX",
     1292    1234 : "CPXERR_THREAD_FAILED",
     1293    1251 : "CPXERR_INDEX_NOT_BASIC",
     1294    1252 : "CPXERR_NEED_OPT_SOLN",
     1295    1253 : "CPXERR_BAD_STATUS",
     1296    1254 : "CPXERR_NOT_UNBOUNDED",
     1297    1255 : "CPXERR_SBASE_INCOMPAT",
     1298    1256 : "CPXERR_SINGULAR",
     1299    1257 : "CPXERR_PRIIND",
     1300    1258 : "CPXERR_NO_LU_FACTOR",
     1301    1260 : "CPXERR_NO_SENSIT",
     1302    1261 : "CPXERR_NO_BASIC_SOLN",
     1303    1262 : "CPXERR_NO_BASIS",
     1304    1263 : "CPXERR_ABORT_STRONGBRANCH",
     1305    1264 : "CPXERR_NO_NORMS",
     1306    1265 : "CPXERR_NOT_DUAL_UNBOUNDED",
     1307    1266 : "CPXERR_TILIM_STRONGBRANCH",
     1308    1267 : "CPXERR_BAD_PIVOT",
     1309    1268 : "CPXERR_TILIM_CONDITION_NO",
     1310    1292 : "CPXERR_BAD_METHOD",
     1311    1421 : "CPXERR_NO_FILENAME",
     1312    1422 : "CPXERR_FAIL_OPEN_WRITE",
     1313    1423 : "CPXERR_FAIL_OPEN_READ",
     1314    1424 : "CPXERR_BAD_FILETYPE",
     1315    1425 : "CPXERR_XMLPARSE",
     1316    1431 : "CPXERR_TOO_MANY_ROWS",
     1317    1432 : "CPXERR_TOO_MANY_COLS",
     1318    1433 : "CPXERR_TOO_MANY_COEFFS",
     1319    1434 : "CPXERR_BAD_NUMBER",
     1320    1435 : "CPXERR_BAD_EXPO_RANGE",
     1321    1436 : "CPXERR_NO_OBJ_SENSE",
     1322    1437 : "CPXERR_QCP_SENSE_FILE",
     1323    1438 : "CPXERR_BAD_LAZY_UCUT",
     1324    1439 : "CPXERR_BAD_INDCONSTR",
     1325    1441 : "CPXERR_NO_NAME_SECTION",
     1326    1442 : "CPXERR_BAD_SOS_TYPE",
     1327    1443 : "CPXERR_COL_ROW_REPEATS",
     1328    1444 : "CPXERR_RIM_ROW_REPEATS",
     1329    1445 : "CPXERR_ROW_REPEATS",
     1330    1446 : "CPXERR_COL_REPEATS",
     1331    1447 : "CPXERR_RIM_REPEATS",
     1332    1448 : "CPXERR_ROW_UNKNOWN",
     1333    1449 : "CPXERR_COL_UNKNOWN",
     1334    1453 : "CPXERR_NO_ROW_SENSE",
     1335    1454 : "CPXERR_EXTRA_FX_BOUND",
     1336    1455 : "CPXERR_EXTRA_FR_BOUND",
     1337    1456 : "CPXERR_EXTRA_BV_BOUND",
     1338    1457 : "CPXERR_BAD_BOUND_TYPE",
     1339    1458 : "CPXERR_UP_BOUND_REPEATS",
     1340    1459 : "CPXERR_LO_BOUND_REPEATS",
     1341    1460 : "CPXERR_NO_BOUND_TYPE",
     1342    1461 : "CPXERR_NO_QMATRIX_SECTION",
     1343    1462 : "CPXERR_BAD_SECTION_ENDATA",
     1344    1463 : "CPXERR_INT_TOO_BIG_INPUT",
     1345    1464 : "CPXERR_NAME_TOO_LONG",
     1346    1465 : "CPXERR_LINE_TOO_LONG",
     1347    1471 : "CPXERR_NO_ROWS_SECTION",
     1348    1472 : "CPXERR_NO_COLUMNS_SECTION",
     1349    1473 : "CPXERR_BAD_SECTION_BOUNDS",
     1350    1474 : "CPXERR_RANGE_SECTION_ORDER",
     1351    1475 : "CPXERR_BAD_SECTION_QMATRIX",
     1352    1476 : "CPXERR_NO_OBJECTIVE",
     1353    1477 : "CPXERR_ROW_REPEAT_PRINT",
     1354    1478 : "CPXERR_COL_REPEAT_PRINT",
     1355    1479 : "CPXERR_RIMNZ_REPEATS",
     1356    1480 : "CPXERR_EXTRA_INTORG",
     1357    1481 : "CPXERR_EXTRA_INTEND",
     1358    1482 : "CPXERR_EXTRA_SOSORG",
     1359    1483 : "CPXERR_EXTRA_SOSEND",
     1360    1484 : "CPXERR_TOO_MANY_RIMS",
     1361    1485 : "CPXERR_TOO_MANY_RIMNZ",
     1362    1486 : "CPXERR_NO_ROW_NAME",
     1363    1487 : "CPXERR_BAD_OBJ_SENSE",
     1364    1550 : "CPXERR_BAS_FILE_SHORT",
     1365    1551 : "CPXERR_BAD_INDICATOR",
     1366    1552 : "CPXERR_NO_ENDATA",
     1367    1553 : "CPXERR_FILE_ENTRIES",
     1368    1554 : "CPXERR_SBASE_ILLEGAL",
     1369    1555 : "CPXERR_BAS_FILE_SIZE",
     1370    1556 : "CPXERR_NO_VECTOR_SOLN",
     1371    1560 : "CPXERR_NOT_SAV_FILE",
     1372    1561 : "CPXERR_SAV_FILE_DATA",
     1373    1562 : "CPXERR_SAV_FILE_WRITE",
     1374    1563 : "CPXERR_FILE_FORMAT",
     1375    1602 : "CPXERR_ADJ_SIGNS",
     1376    1603 : "CPXERR_RHS_IN_OBJ",
     1377    1604 : "CPXERR_ADJ_SIGN_SENSE",
     1378    1605 : "CPXERR_QUAD_IN_ROW",
     1379    1606 : "CPXERR_ADJ_SIGN_QUAD",
     1380    1607 : "CPXERR_NO_OPERATOR",
     1381    1608 : "CPXERR_NO_OP_OR_SENSE",
     1382    1609 : "CPXERR_NO_ID_FIRST",
     1383    1610 : "CPXERR_NO_RHS_COEFF",
     1384    1611 : "CPXERR_NO_NUMBER_FIRST",
     1385    1612 : "CPXERR_NO_QUAD_EXP",
     1386    1613 : "CPXERR_QUAD_EXP_NOT_2",
     1387    1614 : "CPXERR_NO_QP_OPERATOR",
     1388    1615 : "CPXERR_NO_NUMBER",
     1389    1616 : "CPXERR_NO_ID",
     1390    1617 : "CPXERR_BAD_ID",
     1391    1618 : "CPXERR_BAD_EXPONENT",
     1392    1619 : "CPXERR_Q_DIVISOR",
     1393    1621 : "CPXERR_NO_BOUND_SENSE",
     1394    1622 : "CPXERR_BAD_BOUND_SENSE",
     1395    1623 : "CPXERR_NO_NUMBER_BOUND",
     1396    1627 : "CPXERR_NO_SOS_SEPARATOR",
     1397    1650 : "CPXERR_INVALID_NUMBER",
     1398    1660 : "CPXERR_PRM_DATA",
     1399    1661 : "CPXERR_PRM_HEADER",
     1400    1719 : "CPXERR_NO_CONFLICT",
     1401    1720 : "CPXERR_CONFLICT_UNSTABLE",
     1402    1801 : "CPXERR_WORK_FILE_OPEN",
     1403    1802 : "CPXERR_WORK_FILE_READ",
     1404    1803 : "CPXERR_WORK_FILE_WRITE",
     1405    1804 : "CPXERR_IN_INFOCALLBACK",
     1406    1805 : "CPXERR_MIPSEARCH_WITH_CALLBACKS",
     1407    1806 : "CPXERR_LP_NOT_IN_ENVIRONMENT",
     1408    1807 : "CPXERR_PARAM_INCOMPATIBLE",
     1409    32000 : "CPXERR_LICENSE_MIN",
     1410    32201 : "CPXERR_ILOG_LICENSE",
     1411    32301 : "CPXERR_NO_MIP_LIC",
     1412    32302 : "CPXERR_NO_BARRIER_LIC",
     1413    32305 : "CPXERR_NO_MIQP_LIC",
     1414    32018 : "CPXERR_BADLDWID",
     1415    32023 : "CPXERR_BADPRODUCT",
     1416    32024 : "CPXERR_ALGNOTLICENSED",
     1417    32999 : "CPXERR_LICENSE_MAX",
     1418    1701 : "CPXERR_IIS_NO_INFO",
     1419    1702 : "CPXERR_IIS_NO_SOLN",
     1420    1703 : "CPXERR_IIS_FEAS",
     1421    1704 : "CPXERR_IIS_NOT_INFEAS",
     1422    1705 : "CPXERR_IIS_OPT_INFEAS",
     1423    1706 : "CPXERR_IIS_DEFAULT",
     1424    1707 : "CPXERR_IIS_NO_BASIC",
     1425    1709 : "CPXERR_IIS_NO_LOAD",
     1426    1710 : "CPXERR_IIS_SUB_OBJ_LIM",
     1427    1711 : "CPXERR_IIS_SUB_IT_LIM",
     1428    1712 : "CPXERR_IIS_SUB_TIME_LIM",
     1429    1713 : "CPXERR_IIS_NUM_BEST",
     1430    1714 : "CPXERR_IIS_SUB_ABORT",
     1431    3003 : "CPXERR_NOT_MIP",
     1432    3006 : "CPXERR_BAD_PRIORITY",
     1433    3007 : "CPXERR_ORDER_BAD_DIRECTION",
     1434    3009 : "CPXERR_ARRAY_BAD_SOS_TYPE",
     1435    3010 : "CPXERR_UNIQUE_WEIGHTS",
     1436    3012 : "CPXERR_BAD_DIRECTION",
     1437    3015 : "CPXERR_NO_SOS",
     1438    3016 : "CPXERR_NO_ORDER",
     1439    3018 : "CPXERR_INT_TOO_BIG",
     1440    3019 : "CPXERR_SUBPROB_SOLVE",
     1441    3020 : "CPXERR_NO_MIPSTART",
     1442    3021 : "CPXERR_BAD_CTYPE",
     1443    3023 : "CPXERR_NO_INT_X",
     1444    3024 : "CPXERR_NO_SOLNPOOL",
     1445    3301 : "CPXERR_MISS_SOS_TYPE",
     1446    3412 : "CPXERR_NO_TREE",
     1447    3413 : "CPXERR_TREE_MEMORY_LIMIT",
     1448    3414 : "CPXERR_FILTER_VARIABLE_TYPE",
     1449    3504 : "CPXERR_NODE_ON_DISK",
     1450    3601 : "CPXERR_PTHREAD_MUTEX_INIT",
     1451    3603 : "CPXERR_PTHREAD_CREATE",
     1452    1212 : "CPXERR_UNSUPPORTED_CONSTRAINT_TYPE",
     1453    1213 : "CPXERR_ILL_DEFINED_PWL",
     1454    1530 : "CPXERR_NET_DATA",
     1455    1531 : "CPXERR_NOT_MIN_COST_FLOW",
     1456    1532 : "CPXERR_BAD_ROW_ID",
     1457    1537 : "CPXERR_BAD_CHAR",
     1458    1538 : "CPXERR_NET_FILE_SHORT",
     1459    5002 : "CPXERR_Q_NOT_POS_DEF",
     1460    5004 : "CPXERR_NOT_QP",
     1461    5011 : "CPXERR_Q_DUP_ENTRY",
     1462    5012 : "CPXERR_Q_NOT_SYMMETRIC",
     1463    5014 : "CPXERR_Q_NOT_INDEF",
     1464    6002 : "CPXERR_QCP_SENSE"
     1465    }
     1466   
  • new file sage/numerical/backends/generic_backend.pxd

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/generic_backend.pxd
    - +  
     1cdef class GenericBackend:
     2    cpdef int add_variable(self)
     3    cpdef int add_variables(self, int)
     4    cpdef  set_variable_type(self, int variable, int vtype)
     5    cpdef  set_direction(self, int sense)
     6    cpdef  set_objective_coeff(self, int variable, double coeff)
     7    cpdef  set_objective(self, list coeff)
     8    cpdef set_log_level(self, int level)
     9    cpdef add_constraint(self, list indices, list coeffs, int direction, double bound)
     10    cpdef add_col(self, list indices, list coeffs)
     11    cpdef add_constraints(self, int number, int direction, double bound)
     12    cpdef int solve(self) except -1
     13    cpdef double get_objective_value(self)
     14    cpdef double get_variable_value(self, int variable)
     15    cpdef int n_rows(self)
     16    cpdef int n_cols(self)
     17    cpdef name(self)
     18    cpdef bint is_maximization(self)
     19    cpdef  set_problem_name(self, char * name)
     20    cpdef get_problem_name(self)
     21    cpdef  set_objective_name(self, name)
     22    cpdef  write_lp(self, char * name)
     23    cpdef  write_mps(self, char * name, int modern)
     24    cpdef get_row(self, int i)
     25    cpdef double get_objective_coeff(self, int i)
     26    cpdef int n_cols(self)
     27    cpdef int n_rows(self)
     28    cpdef get_row_name(self, int)
     29    cpdef bint is_variable_binary(self, int)
     30    cpdef bint is_variable_integer(self, int)
     31    cpdef bint is_variable_continuous(self, int)
     32    cpdef get_row_bounds(self, int index)
     33    cpdef get_col_bounds(self, int index)
     34    cpdef  set_row_name(self, int index, char * name)
     35    cpdef  set_col_name(self, int index, char * name)
     36    cpdef get_col_name(self, int index)
     37
     38    cpdef get_variable_max(self, int index)
     39    cpdef get_variable_min(self, int index)
     40    cpdef  set_variable_max(self, int index, value)
     41    cpdef  set_variable_min(self, int index, value)
     42
  • new file sage/numerical/backends/generic_backend.pyx

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/generic_backend.pyx
    - +  
     1r"""
     2Generic Backend for LP solvers
     3
     4This class only lists the methods that should be defined by any
     5interface with a LP Solver. All these methods immediately raise
     6``NotImplementedError`` exceptions when called, and are obviously
     7meant to be replaced by the solver-specific method. This file can also
     8be used as a template to create a new interface : one would only need
     9to replace the occurences of ``"Nonexistent_LP_solver"`` by the
     10solver's name, and replace ``GenericBackend`` by
     11``SolverName(GenericBackend)`` so that the new solver extends this
     12class.
     13"""
     14
     15cdef class GenericBackend:
     16
     17    cpdef int add_variable(self):
     18        r"""
     19        Adds a variable.
     20
     21        This amounts to adding a new column to the matrix. By default,
     22        the variable is both positive and real.
     23
     24        EXAMPLE::
     25
     26            sage: from sage.numerical.backends.generic_backend import getSolver
     27            sage: p = getSolver(solver = "Nonexistent_LP_solver")    # optional - Nonexistent_LP_solver
     28            sage: p.n_cols()                                         # optional - Nonexistent_LP_solver
     29            0
     30            sage: p.add_variable()                                   # optional - Nonexistent_LP_solver
     31            1
     32            sage: p.n_cols()                                         # optional - Nonexistent_LP_solver
     33            1
     34        """
     35        raise NotImplementedError()
     36
     37    cpdef int add_variables(self, int n):
     38        r"""
     39        Adds ``number`` variables.
     40
     41        This amounts to adding new columns to the matrix. By default,
     42        the variables are both positive and real.
     43
     44        EXAMPLE::
     45
     46            sage: from sage.numerical.backends.generic_backend import getSolver
     47            sage: p = getSolver(solver = "Nonexistent_LP_solver")    # optional - Nonexistent_LP_solver
     48            sage: p.n_cols()                                         # optional - Nonexistent_LP_solver
     49            0
     50            sage: p.add_variables(5)                                 # optional - Nonexistent_LP_solver
     51            5
     52            sage: p.n_cols()                                         # optional - Nonexistent_LP_solver
     53            5
     54        """
     55
     56        raise NotImplementedError()
     57
     58    cpdef  set_variable_type(self, int variable, int vtype):
     59        r"""
     60        Sets the type of a variable
     61
     62        INPUT:
     63
     64        - ``variable`` (integer) -- the variable's id
     65
     66        - ``vtype`` (integer) :
     67
     68            *  1  Integer
     69            *  0  Binary
     70            * -1 Real
     71
     72        EXAMPLE::
     73
     74            sage: from sage.numerical.backends.generic_backend import getSolver
     75            sage: p = getSolver(solver = "Nonexistent_LP_solver")   # optional - Nonexistent_LP_solver
     76            sage: p.n_cols()                                        # optional - Nonexistent_LP_solver
     77            0
     78            sage: p.add_variable()                                  # optional - Nonexistent_LP_solver
     79            1
     80            sage: p.set_variable_type(0,1)                          # optional - Nonexistent_LP_solver
     81            sage: p.is_variable_integer(0)                          # optional - Nonexistent_LP_solver
     82            True
     83        """
     84
     85        raise NotImplementedError()
     86
     87    cpdef set_direction(self, int sense):
     88        r"""
     89        Sets the direction (maximization/minimization).
     90
     91        INPUT:
     92
     93        - ``sense`` (integer) :
     94
     95            * +1 => Maximization
     96            * -1 => Minimization
     97
     98        EXAMPLE::
     99
     100            sage: from sage.numerical.backends.generic_backend import getSolver
     101            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     102            sage: p.is_maximization()                              # optional - Nonexistent_LP_solver
     103            True
     104            sage: p.set_direction(-1)                              # optional - Nonexistent_LP_solver
     105            sage: p.is_maximization()                              # optional - Nonexistent_LP_solver
     106            False
     107        """
     108
     109        raise NotImplementedError()
     110
     111    cpdef  set_objective_coeff(self, int variable, double coeff):
     112        r"""
     113        Sets the coefficient of a variable in the objective function
     114
     115        INPUT:
     116
     117        - ``variable`` (integer) -- the variable's id
     118
     119        - ``coeff`` (double) -- its coefficient
     120
     121        EXAMPLE::
     122
     123            sage: from sage.numerical.backends.generic_backend import getSolver
     124            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     125            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     126            1
     127            sage: p.get_objective_coeff(0)                         # optional - Nonexistent_LP_solver
     128            0.0
     129            sage: p.set_objective_coeff(0,2)                       # optional - Nonexistent_LP_solver
     130            sage: p.get_objective_coeff(0)                         # optional - Nonexistent_LP_solver
     131            2.0
     132        """
     133
     134        raise NotImplementedError()
     135
     136    cpdef  set_objective(self, list coeff):
     137        r"""
     138        Sets the objective function.
     139
     140        INPUT:
     141
     142        - ``coeff`` -- a list of real values, whose ith element is the
     143          coefficient of the ith variable in the objective function.
     144
     145        EXAMPLE::
     146
     147            sage: from sage.numerical.backends.generic_backend import getSolver
     148            sage: p = getSolver(solver = "Nonexistent_LP_solver")    # optional - Nonexistent_LP_solver
     149            sage: p.add_variables(5)                                 # optional - Nonexistent_LP_solver
     150            5
     151            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - Nonexistent_LP_solver
     152            sage: map(lambda x :p.get_objective_coeff(x), range(5))  # optional - Nonexistent_LP_solver
     153            [1.0, 1.0, 2.0, 1.0, 3.0]
     154        """
     155
     156        raise NotImplementedError()
     157
     158    cpdef set_log_level(self, int level):
     159        r"""
     160        Sets the log (verbosity) level
     161
     162        INPUT:
     163
     164        - ``level`` (integer) -- From 0 (no verbosity) to 3.
     165
     166        EXAMPLE::
     167
     168            sage: from sage.numerical.backends.generic_backend import getSolver
     169            sage: p = getSolver(solver = "Nonexistent_LP_solver")   # optional - Nonexistent_LP_solver
     170            sage: p.set_log_level(2)                                # optional - Nonexistent_LP_solver
     171
     172        """
     173
     174        raise NotImplementedError()
     175
     176    cpdef add_constraint(self, list indices, list coeffs, int direction, double bound):
     177        r"""
     178        Adds a constraint.
     179
     180        INPUT:
     181
     182        - ``indices`` (list of integers) -- this list constains the
     183          indices of the variables whose coefficient is nonzero in the
     184          constraint.
     185
     186        - ``coeffs`` (list of real values) -- associates a coefficient
     187          to the variables listed by ``indices``. Namely, the ith
     188          entry of ``coeffs`` corresponds to the coefficient of the
     189          variable represented by the ith entry in ``indices``.
     190
     191        - ``direction`` (integer) -- the direction of the constraint,
     192          where :
     193
     194              * +1 indicates : function `\leq` ``bound``
     195              *  0 indicates : function `=` ``bound``
     196              * -1 indicates : function `\geq` ``bound``
     197
     198        - ``bound`` (double) -- value of the right-hand side (as
     199          illustrated immediately above).
     200
     201        .. NOTE::
     202
     203            ``indices`` and ``coeffs`` are expected to be of the same
     204            length.
     205
     206        EXAMPLE::
     207
     208            sage: from sage.numerical.backends.generic_backend import getSolver
     209            sage: p = getSolver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
     210            sage: p.add_variables(5)                              # optional - Nonexistent_LP_solver
     211            5
     212            sage: p.add_constraint(range(5), range(5), 0, 2)      # optional - Nonexistent_LP_solver
     213            sage: p.get_row(0)                                    # optional - Nonexistent_LP_solver
     214            ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
     215            sage: p.get_row_bounds(0)                             # optional - Nonexistent_LP_solver
     216            (2.0, 2.0)
     217        """
     218        raise NotImplementedError()
     219
     220    cpdef add_col(self, list indices, list coeffs):
     221        r"""
     222        Adds a column.
     223
     224        INPUT:
     225
     226        - ``indices`` (list of integers) -- this list constains the
     227          indices of the constraints in which the variable's
     228          coefficient is nonzero
     229
     230        - ``coeffs`` (list of real values) -- associates a coefficient
     231          to the variable in each of the constraints in which it
     232          appears. Namely, the ith entry of ``coeffs`` corresponds to
     233          the coefficient of the variable in the constraint
     234          represented by the ith entry in ``indices``.
     235
     236        .. NOTE::
     237
     238            ``indices`` and ``coeffs`` are expected to be of the same
     239            length.
     240
     241        EXAMPLE::
     242
     243            sage: from sage.numerical.backends.generic_backend import getSolver
     244            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     245            sage: p.n_cols()                                       # optional - Nonexistent_LP_solver
     246            0
     247            sage: p.n_rows()                                       # optional - Nonexistent_LP_solver
     248            0
     249            sage: p.add_constraints(5, -1, 0)                      # optional - Nonexistent_LP_solver
     250            sage: p.add_col(range(5), range(5))                    # optional - Nonexistent_LP_solver
     251            sage: p.n_rows()                                       # optional - Nonexistent_LP_solver
     252            5
     253        """
     254
     255        raise NotImplementedError()
     256
     257    cpdef add_constraints(self, int number, int direction, double bound):
     258        r"""
     259        Adds constraints.
     260
     261        INPUT:
     262
     263        - ``number`` (integer) -- the number of constraints to add.
     264
     265        - ``direction`` (integer) -- the direction of the constraint,
     266          where :
     267
     268              * +1 indicates : function `\leq` ``bound``
     269              *  0 indicates : function `=` ``bound``
     270              * -1 indicates : function `\geq` ``bound``
     271
     272        - ``bound`` (double) -- value of the right-hand side (as
     273          illustrated immediately above).
     274
     275        EXAMPLE::
     276
     277            sage: from sage.numerical.backends.generic_backend import getSolver
     278            sage: p = getSolver(solver = "Nonexistent_LP_solver")   # optional - Nonexistent_LP_solver
     279            sage: p.add_variables(5)                                # optional - Nonexistent_LP_solver
     280            5
     281            sage: p.add_constraints(5, +1, 2)                       # optional - Nonexistent_LP_solver
     282            sage: p.get_row(4)                                      # optional - Nonexistent_LP_solver
     283            ([], [])
     284            sage: p.get_row_bounds(4)                               # optional - Nonexistent_LP_solver
     285            (None, 2.0)
     286        """
     287
     288        raise NotImplementedError()
     289
     290    cpdef int solve(self) except -1:
     291        r"""
     292        Solves the problem.
     293
     294        .. NOTE::
     295
     296            This method raises ``MIPSolverException`` exceptions when
     297            the solution can not be computed for any reason (none
     298            exists, or the LP solver was not able to find it, etc...)
     299
     300        EXAMPLE::
     301
     302            sage: from sage.numerical.backends.generic_backend import getSolver
     303            sage: p = getSolver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
     304            sage: p.add_constraints(5, -1, 0)                     # optional - Nonexistent_LP_solver
     305            sage: p.add_col(range(5), range(5))                   # optional - Nonexistent_LP_solver
     306            sage: p.solve()                                       # optional - Nonexistent_LP_solver
     307            0
     308            sage: p.set_objective_coeff(0,1)                      # optional - Nonexistent_LP_solver
     309            sage: p.solve()                                       # optional - Nonexistent_LP_solver
     310            Traceback (most recent call last):
     311            ...
     312            MIPSolverException: ...
     313        """
     314        raise NotImplementedError()
     315
     316    cpdef double get_objective_value(self):
     317        r"""
     318        Returns the value of the objective function.
     319
     320        .. NOTE::
     321
     322           Has no meaning unless ``solve`` has been called before.
     323
     324        EXAMPLE::
     325
     326            sage: from sage.numerical.backends.generic_backend import getSolver
     327            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     328            sage: p.add_variables(2)                               # optional - Nonexistent_LP_solver
     329            2
     330            sage: p.add_constraint([0, 1], [1, 2], +1, 3)          # optional - Nonexistent_LP_solver
     331            sage: p.set_objective([2, 5])                          # optional - Nonexistent_LP_solver
     332            sage: p.solve()                                        # optional - Nonexistent_LP_solver
     333            0
     334            sage: p.get_objective_value()                          # optional - Nonexistent_LP_solver
     335            7.5
     336            sage: p.get_variable_value(0)                          # optional - Nonexistent_LP_solver
     337            0.0
     338            sage: p.get_variable_value(1)                          # optional - Nonexistent_LP_solver
     339            1.5
     340        """
     341
     342        raise NotImplementedError()
     343
     344    cpdef double get_variable_value(self, int variable):
     345        r"""
     346        Returns the value of a variable given by the solver.
     347
     348        .. NOTE::
     349
     350           Has no meaning unless ``solve`` has been called before.
     351
     352        EXAMPLE::
     353
     354            sage: from sage.numerical.backends.generic_backend import getSolver
     355            sage: p = getSolver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
     356            sage: p.add_variables(2)                              # optional - Nonexistent_LP_solver
     357            2
     358            sage: p.add_constraint([0, 1], [1, 2], +1, 3)         # optional - Nonexistent_LP_solver
     359            sage: p.set_objective([2, 5])                         # optional - Nonexistent_LP_solver
     360            sage: p.solve()                                       # optional - Nonexistent_LP_solver
     361            0
     362            sage: p.get_objective_value()                         # optional - Nonexistent_LP_solver
     363            7.5
     364            sage: p.get_variable_value(0)                         # optional - Nonexistent_LP_solver
     365            0.0
     366            sage: p.get_variable_value(1)                         # optional - Nonexistent_LP_solver
     367            1.5
     368        """
     369
     370        raise NotImplementedError()
     371
     372    cpdef int n_cols(self):
     373        r"""
     374        Returns the number of columns/variables.
     375
     376        EXAMPLE::
     377
     378            sage: from sage.numerical.backends.generic_backend import getSolver
     379            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     380            sage: p.n_cols()                                       # optional - Nonexistent_LP_solver
     381            0
     382            sage: p.add_variables(2)                               # optional - Nonexistent_LP_solver
     383            2
     384            sage: p.n_cols()                                       # optional - Nonexistent_LP_solver
     385            2
     386        """
     387
     388        raise NotImplementedError()
     389
     390    cpdef int n_rows(self):
     391        r"""
     392        Returns the number of rows/constraints.
     393
     394        EXAMPLE::
     395
     396            sage: from sage.numerical.backends.generic_backend import getSolver
     397            sage: p = getSolver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
     398            sage: p.n_rows()                                      # optional - Nonexistent_LP_solver
     399            0
     400            sage: p.add_constraints(2, -1, 2)                     # optional - Nonexistent_LP_solver
     401            sage: p.n_rows()                                      # optional - Nonexistent_LP_solver
     402            2
     403        """
     404
     405        raise NotImplementedError()
     406
     407    cpdef name(self):
     408        raise NotImplementedError()
     409
     410    cpdef bint is_maximization(self):
     411        r"""
     412        Tests whether the problem is a maximization
     413
     414        EXAMPLE::
     415
     416            sage: from sage.numerical.backends.generic_backend import getSolver
     417            sage: p = getSolver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver
     418            sage: p.is_maximization()                             # optional - Nonexistent_LP_solver
     419            True
     420            sage: p.set_direction(-1)                             # optional - Nonexistent_LP_solver
     421            sage: p.is_maximization()                             # optional - Nonexistent_LP_solver
     422            False
     423        """
     424        raise NotImplementedError()
     425
     426    cpdef  set_problem_name(self, char * name):
     427        r"""
     428        Sets the problem's name
     429
     430        INPUT:
     431
     432        - ``name`` (``char *``) -- the problem's name
     433
     434        EXAMPLE::
     435
     436            sage: from sage.numerical.backends.generic_backend import getSolver
     437            sage: p = getSolver(solver = "Nonexistent_LP_solver")   # optional - Nonexistent_LP_solver
     438            sage: p.set_problem_name("There once was a french fry") # optional - Nonexistent_LP_solver
     439            sage: print p.get_problem_name()                        # optional - Nonexistent_LP_solver
     440            There once was a french fry
     441        """
     442
     443        raise NotImplementedError()
     444
     445    cpdef get_problem_name(self):
     446        r"""
     447        Returns the problem's name
     448
     449        EXAMPLE::
     450
     451            sage: from sage.numerical.backends.generic_backend import getSolver
     452            sage: p = getSolver(solver = "Nonexistent_LP_solver")   # optional - Nonexistent_LP_solver
     453            sage: p.set_problem_name("There once was a french fry") # optional - Nonexistent_LP_solver
     454            sage: print p.get_problem_name()                        # optional - Nonexistent_LP_solver
     455            There once was a french fry
     456        """
     457
     458        raise NotImplementedError()
     459
     460    cpdef  set_objective_name(self, name):
     461        raise NotImplementedError()
     462
     463    cpdef write_lp(self, char * name):
     464        r"""
     465        Writes the problem to a .lp file
     466
     467        INPUT:
     468       
     469        - ``filename`` (string)
     470
     471        EXAMPLE::
     472
     473            sage: from sage.numerical.backends.generic_backend import getSolver
     474            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     475            sage: p.add_variables(2)                               # optional - Nonexistent_LP_solver
     476            2
     477            sage: p.add_constraint([0, 1], [1, 2], +1, 3)          # optional - Nonexistent_LP_solver
     478            sage: p.set_objective([2, 5])                          # optional - Nonexistent_LP_solver
     479            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")            # optional - Nonexistent_LP_solver
     480        """
     481        raise NotImplementedError()
     482
     483    cpdef write_mps(self, char * name, int modern):
     484        r"""
     485        Writes the problem to a .mps file
     486
     487        INPUT:
     488       
     489        - ``filename`` (string)
     490
     491        EXAMPLE::
     492
     493            sage: from sage.numerical.backends.generic_backend import getSolver
     494            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     495            sage: p.add_variables(2)                               # optional - Nonexistent_LP_solver
     496            2
     497            sage: p.add_constraint([0, 1], [1, 2], +1, 3)          # optional - Nonexistent_LP_solver
     498            sage: p.set_objective([2, 5])                          # optional - Nonexistent_LP_solver
     499            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")            # optional - Nonexistent_LP_solver
     500        """
     501        raise NotImplementedError()
     502
     503    cpdef get_row(self, int i):
     504        r"""
     505        Returns a row
     506
     507        INPUT:
     508
     509        - ``index`` (integer) -- the constraint's id.
     510
     511        OUTPUT:
     512
     513        A pair ``(indices, coeffs)`` where ``indices`` lists the
     514        entries whose coefficient is nonzero, and to which ``coeffs``
     515        associates their coefficient on the model of the
     516        ``add_constraint`` method.
     517
     518        EXAMPLE::
     519
     520            sage: from sage.numerical.backends.generic_backend import getSolver
     521            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     522            sage: p.add_variables(5)                               # optional - Nonexistent_LP_solver
     523            5
     524            sage: p.add_constraint(range(5), range(5), 0, 2)       # optional - Nonexistent_LP_solver
     525            sage: p.get_row(0)                                     # optional - Nonexistent_LP_solver
     526            ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
     527            sage: p.get_row_bounds(0)                              # optional - Nonexistent_LP_solver
     528            (2.0, 2.0)
     529        """
     530
     531        raise NotImplementedError()
     532
     533    cpdef double get_objective_coeff(self, int i):
     534        r"""
     535        Sets the coefficient of a variable in the objective function
     536
     537        INPUT:
     538
     539        - ``variable`` (integer) -- the variable's id
     540
     541        - ``coeff`` (double) -- its coefficient
     542
     543        EXAMPLE::
     544
     545            sage: from sage.numerical.backends.generic_backend import getSolver
     546            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     547            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     548            1
     549            sage: p.get_objective_coeff(0)                         # optional - Nonexistent_LP_solver
     550            0.0
     551            sage: p.set_objective_coeff(0,2)                       # optional - Nonexistent_LP_solver
     552            sage: p.get_objective_coeff(0)                         # optional - Nonexistent_LP_solver
     553            2.0
     554        """
     555
     556        raise NotImplementedError()
     557
     558    cpdef get_row_name(self, int index):
     559        r"""
     560        Returns the ``index`` th row name
     561
     562        INPUT:
     563
     564        - ``index`` (integer) -- the row's id
     565
     566        EXAMPLE::
     567
     568            sage: from sage.numerical.backends.generic_backend import getSolver
     569            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     570            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     571            1
     572            sage: p.set_col_name(0, "I am a variable")             # optional - Nonexistent_LP_solver
     573            sage: p.get_col_name(0)                                # optional - Nonexistent_LP_solver
     574            'I am a variable'
     575        """
     576
     577        raise NotImplementedError()
     578
     579    cpdef get_row_bounds(self, int index):
     580        r"""
     581        Returns the bounds of a specific constraint.
     582
     583        INPUT:
     584
     585        - ``index`` (integer) -- the constraint's id.
     586
     587        OUTPUT:
     588
     589        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     590        to ``None`` if the constraint is not bounded in the
     591        corresponding direction, and is a real value otherwise.
     592
     593        EXAMPLE::
     594
     595            sage: from sage.numerical.backends.generic_backend import getSolver
     596            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     597            sage: p.add_variables(5)                               # optional - Nonexistent_LP_solver
     598            5
     599            sage: p.add_constraint(range(5), range(5), 0, 2)       # optional - Nonexistent_LP_solver
     600            sage: p.get_row(0)                                     # optional - Nonexistent_LP_solver
     601            ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
     602            sage: p.get_row_bounds(0)                              # optional - Nonexistent_LP_solver
     603            (2.0, 2.0)
     604        """
     605        raise NotImplementedError()
     606
     607    cpdef get_col_bounds(self, int index):
     608        r"""
     609        Returns the bounds of a specific variable.
     610
     611        INPUT:
     612
     613        - ``index`` (integer) -- the variable's id.
     614
     615        OUTPUT:
     616
     617        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     618        to ``None`` if the variable is not bounded in the
     619        corresponding direction, and is a real value otherwise.
     620
     621        EXAMPLE::
     622
     623            sage: from sage.numerical.backends.generic_backend import getSolver
     624            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     625            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     626            1
     627            sage: p.get_col_bounds(0)                              # optional - Nonexistent_LP_solver
     628            (0.0, None)
     629            sage: p.set_variable_max(0, 5)                         # optional - Nonexistent_LP_solver
     630            sage: p.get_col_bounds(0)                              # optional - Nonexistent_LP_solver
     631            (0.0, 5.0)
     632        """
     633
     634        raise NotImplementedError()
     635
     636    cpdef bint is_variable_binary(self, int index):
     637        r"""
     638        Tests whether the given variable is of binary type.
     639
     640        INPUT:
     641
     642        - ``index`` (integer) -- the variable's id
     643
     644        EXAMPLE::
     645
     646            sage: from sage.numerical.backends.generic_backend import getSolver
     647            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     648            sage: p.n_cols()                                       # optional - Nonexistent_LP_solver
     649            0
     650            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     651            1
     652            sage: p.set_variable_type(0,0)                         # optional - Nonexistent_LP_solver
     653            sage: p.is_variable_binary(0)                          # optional - Nonexistent_LP_solver
     654            True
     655
     656        """
     657
     658        raise NotImplementedError()
     659
     660    cpdef bint is_variable_integer(self, int index):
     661        r"""
     662        Tests whether the given variable is of integer type.
     663
     664        INPUT:
     665
     666        - ``index`` (integer) -- the variable's id
     667
     668        EXAMPLE::
     669
     670            sage: from sage.numerical.backends.generic_backend import getSolver
     671            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     672            sage: p.n_cols()                                       # optional - Nonexistent_LP_solver
     673            0
     674            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     675            1
     676            sage: p.set_variable_type(0,1)                         # optional - Nonexistent_LP_solver
     677            sage: p.is_variable_integer(0)                         # optional - Nonexistent_LP_solver
     678            True
     679        """
     680
     681        raise NotImplementedError()
     682
     683    cpdef bint is_variable_continuous(self, int index):
     684        r"""
     685        Tests whether the given variable is of continuous/real type.
     686
     687        INPUT:
     688
     689        - ``index`` (integer) -- the variable's id
     690
     691        EXAMPLE::
     692
     693            sage: from sage.numerical.backends.generic_backend import getSolver
     694            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     695            sage: p.n_cols()                                       # optional - Nonexistent_LP_solver
     696            0
     697            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     698            1
     699            sage: p.is_variable_continuous(0)                      # optional - Nonexistent_LP_solver
     700            True
     701            sage: p.set_variable_type(0,1)                         # optional - Nonexistent_LP_solver
     702            sage: p.is_variable_continuous(0)                      # optional - Nonexistent_LP_solver
     703            False
     704
     705        """
     706
     707        raise NotImplementedError()
     708
     709    cpdef set_row_name(self, int index, char * name):
     710        r"""
     711        Sets the ``index`` th row name
     712
     713        INPUT:
     714
     715        - ``index`` (integer) -- the row's id
     716
     717        - ``name`` (``char *``) -- its name
     718
     719        EXAMPLE::
     720
     721            sage: from sage.numerical.backends.generic_backend import getSolver
     722            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     723            sage: p.add_constraints(1, -1, 2)                      # optional - Nonexistent_LP_solver
     724            sage: p.set_row_name(0, "Empty constraint 1")          # optional - Nonexistent_LP_solver
     725            sage: p.get_row_name(0)                                # optional - Nonexistent_LP_solver
     726            'Empty constraint 1'
     727
     728        """
     729
     730        raise NotImplementedError()
     731
     732    cpdef set_col_name(self, int index, char * name):
     733        r"""
     734        Sets the ``index`` th col name
     735
     736        INPUT:
     737
     738        - ``index`` (integer) -- the col's id
     739
     740        - ``name`` (``char *``) -- its name
     741
     742        EXAMPLE::
     743
     744            sage: from sage.numerical.backends.generic_backend import getSolver
     745            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     746            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     747            1
     748            sage: p.set_col_name(0, "I am a variable")             # optional - Nonexistent_LP_solver
     749            sage: p.get_col_name(0)                                # optional - Nonexistent_LP_solver
     750            'I am a variable'
     751        """
     752
     753        raise NotImplementedError()
     754
     755    cpdef get_col_name(self, int index):
     756        r"""
     757        Returns the ``index`` th variable name
     758
     759        INPUT:
     760
     761        - ``index`` (integer) -- the variable's id
     762
     763        EXAMPLE::
     764
     765            sage: from sage.numerical.backends.generic_backend import getSolver
     766            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     767            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     768            1
     769            sage: p.set_col_name(0, "I am a variable")             # optional - Nonexistent_LP_solver
     770            sage: p.get_col_name(0)                                # optional - Nonexistent_LP_solver
     771            'I am a variable'
     772        """
     773
     774        raise NotImplementedError()
     775
     776    cpdef get_variable_max(self, int index):
     777        r"""
     778        Returns the upper bound on a variable
     779
     780        INPUT:
     781
     782        - ``index`` (integer) -- the variable's id
     783
     784        OUTPUT:
     785
     786        A real value if the variable has an upper bound, ``None``
     787        otherwise.
     788
     789        EXAMPLE::
     790
     791            sage: from sage.numerical.backends.generic_backend import getSolver
     792            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     793            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     794            1
     795            sage: p.get_variable_max(0) is None                    # optional - Nonexistent_LP_solver
     796            True
     797            sage: p.set_variable_max(0, 5)                         # optional - Nonexistent_LP_solver
     798            sage: p.get_variable_max(0)                            # optional - Nonexistent_LP_solver
     799            5.0
     800
     801        """
     802
     803        raise NotImplementedError()
     804
     805    cpdef get_variable_min(self, int index):
     806        r"""
     807        Returns the lower bound on a variable
     808
     809        INPUT:
     810
     811        - ``index`` (integer) -- the variable's id
     812
     813        OUTPUT:
     814
     815        A real value if the variable has an lower bound, ``None``
     816        otherwise.
     817
     818        EXAMPLE::
     819
     820            sage: from sage.numerical.backends.generic_backend import getSolver
     821            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     822            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     823            1
     824            sage: p.get_variable_min(0)                            # optional - Nonexistent_LP_solver
     825            0.0
     826            sage: p.set_variable_min(0, 5)                         # optional - Nonexistent_LP_solver
     827            sage: p.get_variable_min(0)                            # optional - Nonexistent_LP_solver
     828            5.0
     829        """
     830        raise NotImplementedError()
     831
     832    cpdef  set_variable_max(self, int index, value):
     833        r"""
     834        Sets the upper bound on a variable
     835
     836        INPUT:
     837
     838        - ``index`` (integer) -- the variable's id
     839
     840        - ``value`` -- real value, or ``None`` to mean that the
     841          variable has not upper bound.
     842
     843        EXAMPLE::
     844
     845            sage: from sage.numerical.backends.generic_backend import getSolver
     846            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     847            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     848            1
     849            sage: p.get_col_bounds(0)                              # optional - Nonexistent_LP_solver
     850            (0.0, None)
     851            sage: p.set_variable_max(0, 5)                         # optional - Nonexistent_LP_solver
     852            sage: p.get_col_bounds(0)                              # optional - Nonexistent_LP_solver
     853            (0.0, 5.0)
     854        """
     855
     856        raise NotImplementedError()
     857
     858    cpdef  set_variable_min(self, int index, value):
     859        r"""
     860        Sets the lower bound on a variable
     861
     862        INPUT:
     863
     864        - ``index`` (integer) -- the variable's id
     865
     866        - ``value`` -- real value, or ``None`` to mean that the
     867          variable has not lower bound.
     868
     869        EXAMPLE::
     870
     871            sage: from sage.numerical.backends.generic_backend import getSolver
     872            sage: p = getSolver(solver = "Nonexistent_LP_solver")  # optional - Nonexistent_LP_solver
     873            sage: p.add_variable()                                 # optional - Nonexistent_LP_solver
     874            1
     875            sage: p.get_col_bounds(0)                              # optional - Nonexistent_LP_solver
     876            (0.0, None)
     877            sage: p.set_variable_min(0, 5)                         # optional - Nonexistent_LP_solver
     878            sage: p.get_col_bounds(0)                              # optional - Nonexistent_LP_solver
     879            (5.0, None)
     880        """
     881
     882        raise NotImplementedError()
     883   
     884
     885cpdef GenericBackend getSolver(constraint_generation = False, solver = None):
     886    r"""
     887    Returns a solver according to the given preferences
     888
     889    INPUT:
     890
     891    - ``solver`` -- 3 solvers should be available through this class:
     892   
     893        - GLPK (``solver="GLPK"``). See the `GLPK
     894          <http://www.gnu.org/software/glpk/>`_ web site.
     895
     896        - COIN Branch and Cut (``solver="Coin"``). See the `COIN-OR
     897          <http://www.coin-or.org>`_ web site.
     898
     899        - CPLEX (``solver="CPLEX"``). See the
     900          `CPLEX <http://www.ilog.com/products/cplex/>`_ web site.
     901          An interface to CPLEX is not yet implemented.
     902
     903        ``solver`` should then be equal to one of ``"GLPK"``,
     904        ``"Coin"``, ``"CPLEX"``, or ``None``. If ``solver=None``
     905        (default), the solvers are tried in this order :
     906   
     907            * CPLEX
     908            * Coin
     909            * GLPK
     910
     911        A backend corresponding to the first solver available is then
     912        returned
     913
     914    - ``constraint_generation`` (boolean) -- whether the solver
     915      returned is to be used for constraint/variable generation. As
     916      the interface with Coin does not support constraint/variable
     917      generation, setting ``constraint_generation`` to ``False``
     918      ensures that the backend to Coin is not returned when ``solver =
     919      None``. This is set to ``False`` by default.
     920
     921    EXAMPLE::
     922
     923        sage: from sage.numerical.backends.generic_backend import getSolver
     924        sage: p = getSolver()
     925
     926    """
     927
     928    if solver is None:
     929
     930        try:
     931            from sage.numerical.backends.cplex_backend import CPLEXBackend
     932            return CPLEXBackend()
     933        except ImportError:
     934            pass
     935
     936        try:
     937            if not constraint_generation:
     938                from sage.numerical.backends.coin_backend import CoinBackend
     939                return CoinBackend()
     940        except ImportError:
     941            pass
     942       
     943        from sage.numerical.backends.glpk_backend import GLPKBackend
     944        return GLPKBackend()
     945
     946    elif solver == "Coin":
     947        from sage.numerical.backends.coin_backend import CoinBackend
     948        return CoinBackend()
     949
     950    elif solver == "GLPK":
     951        from sage.numerical.backends.glpk_backend import GLPKBackend
     952        return GLPKBackend()
     953
     954    elif solver == "CPLEX":
     955        from sage.numerical.backends.cplex_backend import CPLEXBackend
     956        return CPLEXBackend()
     957
     958    else:
     959        raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX' or None (in which case the default one is used).")
     960
     961
  • new file sage/numerical/backends/glpk_backend.pxd

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/glpk_backend.pxd
    - +  
     1from generic_backend cimport GenericBackend
     2include '../../../../../devel/sage/sage/ext/stdsage.pxi'
     3
     4
     5cdef extern from *:
     6    ctypedef double* const_double_ptr "const double*"
     7    ctypedef char * const_char_ptr "const char*"
     8
     9cdef extern from "float.h":
     10    cdef double DBL_MAX
     11
     12cdef extern from "../../../local/include/glpk.h":
     13     ctypedef struct c_glp_prob "glp_prob":
     14         pass
     15     ctypedef struct c_glp_iocp "glp_iocp":
     16         int presolve
     17         int msg_lev
     18         int gmi_cuts
     19         int fp_heur
     20         int mir_cuts
     21     c_glp_iocp * new_c_glp_iocp "new glp_iocp" ()
     22     void glp_init_iocp(c_glp_iocp *)
     23     c_glp_prob * glp_create_prob()
     24     void glp_set_prob_name(c_glp_prob *, char *)
     25     const_char_ptr glp_get_prob_name(c_glp_prob *)
     26     void glp_set_obj_dir(c_glp_prob *, int)
     27     void glp_add_rows(c_glp_prob *, int)
     28     void glp_add_cols(c_glp_prob *, int)
     29     void glp_set_row_name(c_glp_prob *, int, char *)
     30     void glp_set_col_name(c_glp_prob *, int, char *)
     31     void glp_set_row_bnds(c_glp_prob *, int, int, double, double)
     32     void glp_set_col_bnds(c_glp_prob *, int, int, double, double)
     33     void glp_set_obj_coef(c_glp_prob *, int, double)
     34     void glp_load_matrix(c_glp_prob *, int, int *, int *, double *)
     35     void glp_simplex(c_glp_prob *, int)
     36     int glp_intopt(c_glp_prob *, c_glp_iocp *)
     37     int lpx_intopt(c_glp_prob *)
     38     void glp_delete_prob(c_glp_prob *)
     39     double glp_get_col_prim(c_glp_prob *, int)
     40     double glp_get_obj_val(c_glp_prob *)
     41     int glp_get_num_rows(c_glp_prob *)
     42     int glp_get_num_cols(c_glp_prob *)
     43     double glp_mip_col_val(c_glp_prob *, int)
     44     double glp_mip_obj_val(c_glp_prob *)
     45     void glp_set_col_kind(c_glp_prob *, int, int)
     46     int glp_write_mps(c_glp_prob *lp, int fmt, void *parm, char *fname)
     47     int glp_write_lp(c_glp_prob *lp, void *parm, char *fname)
     48     void glp_set_prob_name(c_glp_prob *lp, char *name)
     49     void glp_set_obj_name(c_glp_prob *lp, char *name)
     50     void glp_set_row_name(c_glp_prob *lp, int i, char *name)
     51     void glp_set_col_name(c_glp_prob *lp, int i, char *name)
     52
     53     double glp_get_row_ub(c_glp_prob *lp, int i)
     54     double glp_get_row_lb(c_glp_prob *lp, int i)
     55
     56     double glp_get_col_ub(c_glp_prob *lp, int i)
     57     double glp_get_col_lb(c_glp_prob *lp, int i)
     58     void glp_set_col_ub(c_glp_prob *lp, int i, double value)
     59     void glp_set_col_lb(c_glp_prob *lp, int i, double value)
     60
     61
     62     const_char_ptr glp_get_row_name(c_glp_prob *lp, int i)
     63     const_char_ptr glp_get_col_name(c_glp_prob *lp, int i)
     64
     65     void glp_create_index(c_glp_prob *lp)
     66
     67     double glp_get_col_lb(c_glp_prob *lp, int i)
     68     double glp_get_col_ub(c_glp_prob *lp, int i)
     69
     70     int glp_mip_status(c_glp_prob *lp)
     71     int glp_set_mat_row(c_glp_prob *lp, int, int, int *, double * )
     72     int glp_set_mat_col(c_glp_prob *lp, int, int, int *, double * )
     73     int glp_get_mat_row(c_glp_prob *lp, int, int *, double * )
     74     double glp_get_row_ub(c_glp_prob *lp, int)
     75     double glp_get_row_lb(c_glp_prob *lp, int)
     76     int glp_get_col_kind(c_glp_prob *lp, int)
     77     double glp_get_obj_coef(c_glp_prob *lp, int)
     78     int glp_get_obj_dir(c_glp_prob *lp)
     79
     80
     81
     82     int GLP_ON
     83     int GLP_MAX
     84     int GLP_MIN
     85     int GLP_UP
     86     int GLP_FR
     87     int GLP_DB
     88     int GLP_FX
     89     int GLP_LO
     90     int GLP_CV
     91     int GLP_IV
     92     int GLP_BV
     93     int GLP_MSG_OFF
     94     int GLP_MSG_ERR
     95     int GLP_MSG_ON
     96     int GLP_MSG_ALL
     97     int GLP_MPS_DECK
     98     int GLP_MPS_FILE
     99
     100     int GLP_UNDEF
     101     int GLP_OPT
     102     int GLP_FEAS
     103     int GLP_NOFEAS
     104
     105cdef class GLPKBackend(GenericBackend):
     106    cdef c_glp_prob * lp
     107    cdef c_glp_iocp * iocp
     108
  • new file sage/numerical/backends/glpk_backend.pyx

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/backends/glpk_backend.pyx
    - +  
     1r"""
     2GLPK Backend
     3"""
     4
     5from sage.numerical.mip import MIPSolverException
     6
     7cdef class GLPKBackend(GenericBackend):
     8
     9    def __cinit__(self):
     10        r"""
     11        Constructor
     12
     13        EXAMPLE::
     14
     15            sage: p = MixedIntegerLinearProgram(solver="GLPK")
     16        """
     17
     18        self.lp = glp_create_prob()
     19        self.iocp = new_c_glp_iocp()
     20        glp_init_iocp(self.iocp)
     21        self.iocp.presolve = GLP_ON
     22        glp_set_obj_dir(self.lp, GLP_MAX)
     23        self.set_log_level(0)
     24        #self.iocp.gmi_cuts = GLP_ON
     25        #self.iocp.fp_heur = GLP_ON
     26        #self.iocp.mir_cuts = GLP_ON
     27
     28    cpdef int add_variable(self):
     29        r"""
     30        Adds a variable.
     31
     32        This amounts to adding a new column to the matrix. By default,
     33        the variable is both positive and real.
     34
     35        EXAMPLE::
     36
     37            sage: from sage.numerical.backends.generic_backend import getSolver
     38            sage: p = getSolver(solver = "GLPK")
     39            sage: p.n_cols()
     40            0
     41            sage: p.add_variable()
     42            1
     43            sage: p.n_cols()
     44            1
     45        """
     46
     47        glp_add_cols(self.lp, 1)
     48        cdef int n_var = glp_get_num_cols(self.lp)
     49        glp_set_col_bnds(self.lp, n_var, GLP_LO, 0, 0)
     50        glp_set_col_kind(self.lp, n_var, GLP_CV)
     51       
     52        return n_var
     53
     54    cpdef int add_variables(self, int number):
     55        r"""
     56        Adds ``number`` variables.
     57
     58        This amounts to adding new columns to the matrix. By default,
     59        the variables are both positive and real.
     60
     61        EXAMPLE::
     62
     63            sage: from sage.numerical.backends.generic_backend import getSolver
     64            sage: p = getSolver(solver = "GLPK")
     65            sage: p.n_cols()
     66            0
     67            sage: p.add_variables(5)
     68            5
     69            sage: p.n_cols()
     70            5
     71        """
     72
     73        glp_add_cols(self.lp, number)
     74
     75        cdef int n_var
     76        n_var = glp_get_num_cols(self.lp)
     77
     78
     79        cdef int i
     80       
     81        for 0<= i < number:
     82            glp_set_col_bnds(self.lp, n_var-i, GLP_LO, 0, 0)
     83            glp_set_col_kind(self.lp, n_var-i, GLP_CV)
     84       
     85        return n_var
     86
     87    cpdef set_variable_type(self, int variable, int vtype):
     88        r"""
     89        Sets the type of a variable
     90
     91        INPUT:
     92
     93        - ``variable`` (integer) -- the variable's id
     94
     95        - ``vtype`` (integer) :
     96
     97            *  1  Integer
     98            *  0  Binary
     99            * -1 Real
     100
     101        EXAMPLE::
     102
     103            sage: from sage.numerical.backends.generic_backend import getSolver
     104            sage: p = getSolver(solver = "GLPK")
     105            sage: p.n_cols()
     106            0
     107            sage: p.add_variable()
     108            1
     109            sage: p.set_variable_type(0,1)
     110            sage: p.is_variable_integer(0)
     111            True
     112        """
     113
     114        if vtype==1:
     115            glp_set_col_kind(self.lp, variable+1, GLP_IV)
     116
     117        elif vtype==0:
     118            glp_set_col_kind(self.lp, variable+1, GLP_BV)
     119
     120        else:
     121            glp_set_col_kind(self.lp, variable+1, GLP_CV)
     122
     123    cpdef set_direction(self, int sense):
     124        r"""
     125        Sets the direction (maximization/minimization).
     126
     127        INPUT:
     128
     129        - ``sense`` (integer) :
     130
     131            * +1 => Maximization
     132            * -1 => Minimization
     133
     134        EXAMPLE::
     135
     136            sage: from sage.numerical.backends.generic_backend import getSolver
     137            sage: p = getSolver(solver = "GLPK")
     138            sage: p.is_maximization()
     139            True
     140            sage: p.set_direction(-1)
     141            sage: p.is_maximization()
     142            False
     143        """
     144        if sense == 1:
     145            glp_set_obj_dir(self.lp, GLP_MAX)
     146        else:
     147            glp_set_obj_dir(self.lp, GLP_MIN)
     148
     149    cpdef set_objective_coeff(self, int variable, double coeff):
     150        r"""
     151        Sets the coefficient of a variable in the objective function
     152
     153        INPUT:
     154
     155        - ``variable`` (integer) -- the variable's id
     156
     157        - ``coeff`` (double) -- its coefficient
     158
     159        EXAMPLE::
     160
     161            sage: from sage.numerical.backends.generic_backend import getSolver
     162            sage: p = getSolver(solver = "GLPK")
     163            sage: p.add_variable()
     164            1
     165            sage: p.get_objective_coeff(0)
     166            0.0
     167            sage: p.set_objective_coeff(0,2)
     168            sage: p.get_objective_coeff(0)
     169            2.0
     170        """
     171
     172        glp_set_obj_coef(self.lp, variable + 1, coeff)
     173
     174
     175    cpdef set_problem_name(self, char * name):
     176        r"""
     177        Sets the problem's name
     178
     179        INPUT:
     180
     181        - ``name`` (``char *``) -- the problem's name
     182
     183        EXAMPLE::
     184
     185            sage: from sage.numerical.backends.generic_backend import getSolver
     186            sage: p = getSolver(solver = "GLPK")
     187            sage: p.set_problem_name("There once was a french fry")
     188            sage: print p.get_problem_name()
     189            There once was a french fry
     190        """
     191
     192        glp_set_prob_name(self.lp, name)
     193
     194    cpdef  get_problem_name(self):
     195        r"""
     196        Returns the problem's name
     197
     198        EXAMPLE::
     199
     200            sage: from sage.numerical.backends.generic_backend import getSolver
     201            sage: p = getSolver(solver = "GLPK")
     202            sage: p.set_problem_name("There once was a french fry")
     203            sage: print p.get_problem_name()
     204            There once was a french fry
     205        """
     206
     207        cdef char * name = <char *> glp_get_prob_name(self.lp)
     208        if name == NULL:
     209            return ""
     210        else:
     211            return name
     212
     213    cpdef set_objective(self, list coeff):
     214        r"""
     215        Sets the objective function.
     216
     217        INPUT:
     218
     219        - ``coeff`` -- a list of real values, whose ith element is the
     220          coefficient of the ith variable in the objective function.
     221
     222        EXAMPLE::
     223
     224            sage: from sage.numerical.backends.generic_backend import getSolver
     225            sage: p = getSolver(solver = "GLPK")
     226            sage: p.add_variables(5)
     227            5
     228            sage: p.set_objective([1, 1, 2, 1, 3])
     229            sage: map(lambda x :p.get_objective_coeff(x), range(5))
     230            [1.0, 1.0, 2.0, 1.0, 3.0]
     231        """
     232
     233        cdef int i
     234
     235        for i,v in enumerate(coeff):
     236            glp_set_obj_coef(self.lp, i+1, v)
     237
     238    cpdef set_log_level(self, int level):
     239        r"""
     240        Sets the log (verbosity) level
     241
     242        INPUT:
     243
     244        - ``level`` (integer) -- From 0 (no verbosity) to 3.
     245
     246        EXAMPLE::
     247
     248            sage: from sage.numerical.backends.generic_backend import getSolver
     249            sage: p = getSolver(solver = "GLPK")
     250            sage: p.set_log_level(2)
     251
     252        """
     253        if level == 0:
     254            self.iocp.msg_lev = GLP_MSG_OFF
     255        elif level == 1:
     256            self.iocp.msg_lev = GLP_MSG_ERR
     257        elif level == 2:
     258            self.iocp.msg_lev = GLP_MSG_ON
     259        else:
     260            self.iocp.msg_lev = GLP_MSG_ALL
     261
     262    cpdef add_constraints(self, int number, int direction, double bound):
     263        r"""
     264        Adds constraints.
     265
     266        INPUT:
     267
     268        - ``number`` (integer) -- the number of constraints to add.
     269
     270        - ``direction`` (integer) -- the direction of the constraint,
     271          where :
     272
     273              * +1 indicates : function `\leq` ``bound``
     274              *  0 indicates : function `=` ``bound``
     275              * -1 indicates : function `\geq` ``bound``
     276
     277        - ``bound`` (double) -- value of the right-hand side (as
     278          illustrated immediately above).
     279
     280        EXAMPLE::
     281
     282            sage: from sage.numerical.backends.generic_backend import getSolver
     283            sage: p = getSolver(solver = "GLPK")
     284            sage: p.add_variables(5)
     285            5
     286            sage: p.add_constraints(5, +1, 2)
     287            sage: p.get_row(4)
     288            ([], [])
     289            sage: p.get_row_bounds(4)
     290            (None, 2.0)
     291        """
     292
     293        glp_add_rows(self.lp, number)
     294        cdef int n = glp_get_num_rows(self.lp)
     295
     296        if direction == +1:
     297            direction = GLP_UP
     298        elif direction == -1:
     299            direction = GLP_LO
     300        else:
     301            direction = GLP_FX
     302       
     303        cdef int i
     304        for 0<= i < number:
     305            glp_set_row_bnds(self.lp, n-i, direction, bound, bound)
     306
     307    cpdef add_constraint(self, list indices, list coeffs, int direction, double bound):
     308        r"""
     309        Adds a constraint.
     310
     311        INPUT:
     312
     313        - ``indices`` (list of integers) -- this list constains the
     314          indices of the variables whose coefficient is nonzero in the
     315          constraint.
     316
     317        - ``coeffs`` (list of real values) -- associates a coefficient
     318          to the variables listed by ``indices``. Namely, the ith
     319          entry of ``coeffs`` corresponds to the coefficient of the
     320          variable represented by the ith entry in ``indices``.
     321
     322        - ``direction`` (integer) -- the direction of the constraint,
     323          where :
     324
     325              * +1 indicates : function `\leq` ``bound``
     326              *  0 indicates : function `=` ``bound``
     327              * -1 indicates : function `\geq` ``bound``
     328
     329        - ``bound`` (double) -- value of the right-hand side (as
     330          illustrated immediately above).
     331
     332        .. NOTE::
     333
     334            ``indices`` and ``coeffs`` are expected to be of the same
     335            length.
     336
     337        EXAMPLE::
     338
     339            sage: from sage.numerical.backends.generic_backend import getSolver
     340            sage: p = getSolver(solver = "GLPK")
     341            sage: p.add_variables(5)
     342            5
     343            sage: p.add_constraint(range(5), range(5), 0, 2)
     344            sage: p.get_row(0)
     345            ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
     346            sage: p.get_row_bounds(0)
     347            (2.0, 2.0)
     348        """
     349
     350        glp_add_rows(self.lp, 1)
     351        cdef int n = glp_get_num_rows(self.lp)
     352
     353        if direction == +1:
     354            direction = GLP_UP
     355        elif direction == -1:
     356            direction = GLP_LO
     357        else:
     358            direction = GLP_FX
     359
     360        cdef int * row_i
     361        cdef double * row_values
     362
     363        row_i = <int *> sage_malloc((len(indices)+1) * sizeof(int))
     364        row_values = <double *> sage_malloc((len(indices)+1) * sizeof(double))
     365
     366        for i,v in enumerate(indices):
     367            row_i[i+1] = v+1
     368        for i,v in enumerate(coeffs):
     369            row_values[i+1] = v
     370       
     371        glp_set_mat_row(self.lp, n, len(indices), row_i, row_values)
     372        glp_set_row_bnds(self.lp, n, direction, bound, bound)
     373
     374    cpdef get_row(self, int index):
     375        r"""
     376        Returns a row
     377
     378        INPUT:
     379
     380        - ``index`` (integer) -- the constraint's id.
     381
     382        OUTPUT:
     383
     384        A pair ``(indices, coeffs)`` where ``indices`` lists the
     385        entries whose coefficient is nonzero, and to which ``coeffs``
     386        associates their coefficient on the model of the
     387        ``add_constraint`` method.
     388
     389        EXAMPLE::
     390
     391            sage: from sage.numerical.backends.generic_backend import getSolver
     392            sage: p = getSolver(solver = "GLPK")
     393            sage: p.add_variables(5)
     394            5
     395            sage: p.add_constraint(range(5), range(5), 0, 2)
     396            sage: p.get_row(0)
     397            ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
     398            sage: p.get_row_bounds(0)
     399            (2.0, 2.0)
     400        """
     401        cdef int n = glp_get_num_cols(self.lp)
     402        cdef int * c_indices = <int*> sage_malloc((n+1)*sizeof(int))
     403        cdef double * c_values = <double*> sage_malloc((n+1)*sizeof(double))
     404        cdef list indices = []
     405        cdef list values = []
     406        cdef int i,j
     407
     408        i = glp_get_mat_row(self.lp, index + 1, c_indices, c_values)
     409        for 0 < j <= i:
     410            indices.append(c_indices[j]-1)
     411            values.append(c_values[j])
     412
     413        sage_free(c_indices)
     414        sage_free(c_values)
     415
     416        return (indices, values)
     417
     418    cpdef get_row_bounds(self, int index):
     419        r"""
     420        Returns the bounds of a specific constraint.
     421
     422        INPUT:
     423
     424        - ``index`` (integer) -- the constraint's id.
     425
     426        OUTPUT:
     427
     428        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     429        to ``None`` if the constraint is not bounded in the
     430        corresponding direction, and is a real value otherwise.
     431
     432        EXAMPLE::
     433
     434            sage: from sage.numerical.backends.generic_backend import getSolver
     435            sage: p = getSolver(solver = "GLPK")
     436            sage: p.add_variables(5)
     437            5
     438            sage: p.add_constraint(range(5), range(5), 0, 2)
     439            sage: p.get_row(0)
     440            ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0])
     441            sage: p.get_row_bounds(0)
     442            (2.0, 2.0)
     443        """
     444        cdef double ub
     445        cdef double lb
     446
     447        ub = glp_get_row_ub(self.lp, index + 1)
     448        lb = glp_get_row_lb(self.lp, index +1)
     449
     450        return (
     451            (lb if lb != -DBL_MAX else None),
     452            (ub if ub != +DBL_MAX else None)
     453            )
     454
     455    cpdef get_col_bounds(self, int index):
     456        r"""
     457        Returns the bounds of a specific variable.
     458
     459        INPUT:
     460
     461        - ``index`` (integer) -- the variable's id.
     462
     463        OUTPUT:
     464
     465        A pair ``(lower_bound, upper_bound)``. Each of them can be set
     466        to ``None`` if the variable is not bounded in the
     467        corresponding direction, and is a real value otherwise.
     468
     469        EXAMPLE::
     470
     471            sage: from sage.numerical.backends.generic_backend import getSolver
     472            sage: p = getSolver(solver = "GLPK")
     473            sage: p.add_variable()
     474            1
     475            sage: p.get_col_bounds(0)
     476            (0.0, None)
     477            sage: p.set_variable_max(0, 5)
     478            sage: p.get_col_bounds(0)
     479            (0.0, 5.0)
     480        """
     481
     482        cdef double ub
     483        cdef double lb
     484
     485        ub = glp_get_col_ub(self.lp, index +1)
     486        lb = glp_get_col_lb(self.lp, index +1)
     487
     488        return (
     489            (lb if lb != -DBL_MAX else None),
     490            (ub if ub != +DBL_MAX else None)
     491            )
     492
     493    cpdef double get_objective_coeff(self, int index):
     494        r"""
     495        Returns the coefficient of a variable in the objective
     496        function.
     497
     498        INPUT:
     499
     500        - ``index`` (integer) -- the variable's id.
     501
     502        EXAMPLE::
     503
     504            sage: from sage.numerical.backends.generic_backend import getSolver
     505            sage: p = getSolver(solver = "GLPK")
     506            sage: p.add_variable()
     507            1
     508            sage: p.get_objective_coeff(0)
     509            0.0
     510            sage: p.set_objective_coeff(0,2)
     511            sage: p.get_objective_coeff(0)
     512            2.0
     513        """
     514        return glp_get_obj_coef(self.lp, index + 1)
     515           
     516
     517    cpdef add_col(self, list indices, list coeffs):
     518        r"""
     519        Adds a column.
     520
     521        INPUT:
     522
     523        - ``indices`` (list of integers) -- this list constains the
     524          indices of the constraints in which the variable's
     525          coefficient is nonzero
     526
     527        - ``coeffs`` (list of real values) -- associates a coefficient
     528          to the variable in each of the constraints in which it
     529          appears. Namely, the ith entry of ``coeffs`` corresponds to
     530          the coefficient of the variable in the constraint
     531          represented by the ith entry in ``indices``.
     532
     533        .. NOTE::
     534
     535            ``indices`` and ``coeffs`` are expected to be of the same
     536            length.
     537
     538        EXAMPLE::
     539
     540            sage: from sage.numerical.backends.generic_backend import getSolver
     541            sage: p = getSolver(solver = "GLPK")
     542            sage: p.n_cols()
     543            0
     544            sage: p.n_rows()
     545            0
     546            sage: p.add_constraints(5, -1, 0)
     547            sage: p.add_col(range(5), range(5))
     548            sage: p.n_rows()
     549            5
     550        """
     551
     552        glp_add_cols(self.lp, 1)
     553        cdef int n = glp_get_num_cols(self.lp)
     554
     555        cdef int * col_i
     556        cdef double * col_values
     557
     558        col_i = <int *> sage_malloc((len(indices)+1) * sizeof(int))
     559        col_values = <double *> sage_malloc((len(indices)+1) * sizeof(double))
     560
     561        for i,v in enumerate(indices):
     562            col_i[i+1] = v+1
     563        for i,v in enumerate(coeffs):
     564            col_values[i+1] = v
     565       
     566        glp_set_mat_col(self.lp, n, len(indices), col_i, col_values)
     567        glp_set_col_bnds(self.lp, n, GLP_LO, 0,0)
     568
     569
     570    cpdef int solve(self) except -1:
     571        r"""
     572        Solves the problem.
     573
     574        .. NOTE::
     575
     576            This method raises ``MIPSolverException`` exceptions when
     577            the solution can not be computed for any reason (none
     578            exists, or the LP solver was not able to find it, etc...)
     579
     580        EXAMPLE::
     581
     582            sage: from sage.numerical.backends.generic_backend import getSolver
     583            sage: p = getSolver(solver = "GLPK")
     584            sage: p.add_constraints(5, -1, 0)
     585            sage: p.add_col(range(5), range(5))
     586            sage: p.solve()
     587            0
     588            sage: p.set_objective_coeff(0,1)
     589            sage: p.solve()
     590            Traceback (most recent call last):
     591            ...
     592            MIPSolverException: ...
     593        """
     594
     595        glp_intopt(self.lp, self.iocp)
     596
     597        cdef int status = glp_mip_status(self.lp)
     598        if status == GLP_OPT:
     599            pass
     600        elif status == GLP_UNDEF:
     601            raise MIPSolverException("GLPK : Solution is undefined")
     602        elif status == GLP_FEAS:
     603            raise MIPSolverException("GLPK : Feasible solution found, while optimality has not been proven")
     604        elif status == GLP_NOFEAS:
     605            raise MIPSolverException("GLPK : There is no feasible integer solution to this Linear Program")
     606
     607        return 0
     608
     609    cpdef double get_objective_value(self):
     610        r"""
     611        Returns the value of the objective function.
     612
     613        .. NOTE::
     614
     615           Has no meaning unless ``solve`` has been called before.
     616
     617        EXAMPLE::
     618
     619            sage: from sage.numerical.backends.generic_backend import getSolver
     620            sage: p = getSolver(solver = "GLPK")
     621            sage: p.add_variables(2)
     622            2
     623            sage: p.add_constraint([0, 1], [1, 2], +1, 3)
     624            sage: p.set_objective([2, 5])
     625            sage: p.solve()
     626            0
     627            sage: p.get_objective_value()
     628            7.5
     629            sage: p.get_variable_value(0)
     630            0.0
     631            sage: p.get_variable_value(1)
     632            1.5
     633        """
     634        return glp_mip_obj_val(self.lp)
     635
     636    cpdef double get_variable_value(self, int variable):
     637        r"""
     638        Returns the value of a variable given by the solver.
     639
     640        .. NOTE::
     641
     642           Has no meaning unless ``solve`` has been called before.
     643
     644        EXAMPLE::
     645
     646            sage: from sage.numerical.backends.generic_backend import getSolver
     647            sage: p = getSolver(solver = "GLPK")
     648            sage: p.add_variables(2)
     649            2
     650            sage: p.add_constraint([0, 1], [1, 2], +1, 3)
     651            sage: p.set_objective([2, 5])
     652            sage: p.solve()
     653            0
     654            sage: p.get_objective_value()
     655            7.5
     656            sage: p.get_variable_value(0)
     657            0.0
     658            sage: p.get_variable_value(1)
     659            1.5
     660        """   
     661        return glp_mip_col_val(self.lp, variable+1)
     662
     663    cpdef int n_cols(self):
     664        r"""
     665        Returns the number of columns/variables.
     666
     667        EXAMPLE::
     668
     669            sage: from sage.numerical.backends.generic_backend import getSolver
     670            sage: p = getSolver(solver = "GLPK")
     671            sage: p.n_cols()
     672            0
     673            sage: p.add_variables(2)
     674            2
     675            sage: p.n_cols()
     676            2
     677        """
     678        return glp_get_num_cols(self.lp)
     679
     680    cpdef int n_rows(self):
     681        r"""
     682        Returns the number of rows/constraints.
     683
     684        EXAMPLE::
     685
     686            sage: from sage.numerical.backends.generic_backend import getSolver
     687            sage: p = getSolver(solver = "GLPK")
     688            sage: p.n_rows()
     689            0
     690            sage: p.add_constraints(2, -1, 2)
     691            sage: p.n_rows()
     692            2
     693        """
     694
     695        return glp_get_num_rows(self.lp)
     696
     697    cpdef get_row_name(self, int index):
     698        r"""
     699        Returns the ``index`` th row name
     700
     701        INPUT:
     702
     703        - ``index`` (integer) -- the row's id
     704
     705        EXAMPLE::
     706
     707            sage: from sage.numerical.backends.generic_backend import getSolver
     708            sage: p = getSolver(solver = "GLPK")
     709            sage: p.add_variable()
     710            1
     711            sage: p.set_col_name(0, "I am a variable")
     712            sage: p.get_col_name(0)
     713            'I am a variable'
     714        """
     715        glp_create_index(self.lp)
     716        cdef char *  s = <char*> glp_get_row_name(self.lp, index + 1)
     717
     718        if s != NULL:
     719            return s
     720        else:
     721            return ""
     722
     723
     724    cpdef set_col_name(self, int index, char * name):
     725        r"""
     726        Sets the ``index`` th col name
     727
     728        INPUT:
     729
     730        - ``index`` (integer) -- the col's id
     731
     732        - ``name`` (``char *``) -- its name
     733
     734        EXAMPLE::
     735
     736            sage: from sage.numerical.backends.generic_backend import getSolver
     737            sage: p = getSolver(solver = "GLPK")
     738            sage: p.add_variable()
     739            1
     740            sage: p.set_col_name(0, "I am a variable")
     741            sage: p.get_col_name(0)
     742            'I am a variable'
     743        """
     744
     745        glp_set_col_name(self.lp, index + 1, name)
     746
     747    cpdef get_col_name(self, int index):
     748        r"""
     749        Returns the ``index`` th variable name
     750
     751        INPUT:
     752
     753        - ``index`` (integer) -- the variable's id
     754
     755        EXAMPLE::
     756
     757            sage: from sage.numerical.backends.generic_backend import getSolver
     758            sage: p = getSolver(solver = "GLPK")
     759            sage: p.add_constraints(1, -1, 2)
     760            sage: p.set_row_name(0, "Empty constraint 1")
     761            sage: p.get_row_name(0)
     762            'Empty constraint 1'
     763        """
     764        glp_create_index(self.lp)
     765        cdef char *  s = <char*> glp_get_col_name(self.lp, index + 1)
     766
     767        if s != NULL:
     768            return s
     769        else:
     770            return ""
     771
     772    cpdef set_row_name(self, int index, char * name):
     773        r"""
     774        Sets the ``index`` th row name
     775
     776        INPUT:
     777
     778        - ``index`` (integer) -- the row's id
     779
     780        - ``name`` (``char *``) -- its name
     781
     782        EXAMPLE::
     783
     784            sage: from sage.numerical.backends.generic_backend import getSolver
     785            sage: p = getSolver(solver = "GLPK")
     786            sage: p.add_constraints(1, -1, 2)
     787            sage: p.set_row_name(0, "Empty constraint 1")
     788            sage: p.get_row_name(0)
     789            'Empty constraint 1'
     790
     791        """
     792
     793        glp_set_row_name(self.lp, index + 1, name)
     794
     795    cpdef bint is_variable_binary(self, int index):
     796        r"""
     797        Tests whether the given variable is of binary type.
     798
     799        INPUT:
     800
     801        - ``index`` (integer) -- the variable's id
     802
     803        EXAMPLE::
     804
     805            sage: from sage.numerical.backends.generic_backend import getSolver
     806            sage: p = getSolver(solver = "GLPK")
     807            sage: p.n_cols()
     808            0
     809            sage: p.add_variable()
     810            1
     811            sage: p.set_variable_type(0,0)
     812            sage: p.is_variable_binary(0)
     813            True
     814
     815        """
     816        return glp_get_col_kind(self.lp, index + 1) == GLP_BV
     817
     818    cpdef bint is_variable_integer(self, int index):
     819        r"""
     820        Tests whether the given variable is of integer type.
     821
     822        INPUT:
     823
     824        - ``index`` (integer) -- the variable's id
     825
     826        EXAMPLE::
     827
     828            sage: from sage.numerical.backends.generic_backend import getSolver
     829            sage: p = getSolver(solver = "GLPK")
     830            sage: p.n_cols()
     831            0
     832            sage: p.add_variable()
     833            1
     834            sage: p.set_variable_type(0,1)
     835            sage: p.is_variable_integer(0)
     836            True
     837        """
     838        return glp_get_col_kind(self.lp, index + 1) == GLP_IV
     839
     840    cpdef bint is_variable_continuous(self, int index):
     841        r"""
     842        Tests whether the given variable is of continuous/real type.
     843
     844        INPUT:
     845
     846        - ``index`` (integer) -- the variable's id
     847
     848        EXAMPLE::
     849
     850            sage: from sage.numerical.backends.generic_backend import getSolver
     851            sage: p = getSolver(solver = "GLPK")
     852            sage: p.n_cols()
     853            0
     854            sage: p.add_variable()
     855            1
     856            sage: p.is_variable_continuous(0)
     857            True
     858            sage: p.set_variable_type(0,1)
     859            sage: p.is_variable_continuous(0)
     860            False
     861
     862        """
     863        return glp_get_col_kind(self.lp, index + 1) == GLP_CV
     864
     865    cpdef bint is_maximization(self):
     866        r"""
     867        Tests whether the problem is a maximization
     868
     869        EXAMPLE::
     870
     871            sage: from sage.numerical.backends.generic_backend import getSolver
     872            sage: p = getSolver(solver = "GLPK")
     873            sage: p.is_maximization()
     874            True
     875            sage: p.set_direction(-1)
     876            sage: p.is_maximization()
     877            False
     878        """
     879
     880        return glp_get_obj_dir(self.lp) == GLP_MAX
     881
     882    cpdef get_variable_max(self, int index):
     883        r"""
     884        Returns the upper bound on a variable
     885
     886        INPUT:
     887
     888        - ``index`` (integer) -- the variable's id
     889
     890        OUTPUT:
     891
     892        A real value if the variable has an upper bound, ``None``
     893        otherwise.
     894
     895        EXAMPLE::
     896
     897            sage: from sage.numerical.backends.generic_backend import getSolver
     898            sage: p = getSolver(solver = "GLPK")
     899            sage: p.add_variable()
     900            1
     901            sage: p.get_variable_max(0) is None
     902            True
     903            sage: p.set_variable_max(0, 5)
     904            sage: p.get_variable_max(0)
     905            5.0
     906
     907        """
     908        cdef double x = glp_get_col_ub(self.lp, index +1)
     909        if x == DBL_MAX:
     910            return None
     911        else:
     912            return x
     913
     914    cpdef get_variable_min(self, int index):
     915        r"""
     916        Returns the lower bound on a variable
     917
     918        INPUT:
     919
     920        - ``index`` (integer) -- the variable's id
     921
     922        OUTPUT:
     923
     924        A real value if the variable has an lower bound, ``None``
     925        otherwise.
     926
     927        EXAMPLE::
     928
     929            sage: from sage.numerical.backends.generic_backend import getSolver
     930            sage: p = getSolver(solver = "GLPK")
     931            sage: p.add_variable()
     932            1
     933            sage: p.get_variable_min(0)
     934            0.0
     935            sage: p.set_variable_min(0, 5)
     936            sage: p.get_variable_min(0)
     937            5.0
     938        """
     939        cdef double x = glp_get_col_lb(self.lp, index +1)
     940        if x == -DBL_MAX:
     941            return None
     942        else:
     943            return x
     944
     945    cpdef set_variable_max(self, int index, value):
     946        r"""
     947        Sets the upper bound on a variable
     948
     949        INPUT:
     950
     951        - ``index`` (integer) -- the variable's id
     952
     953        - ``value`` -- real value, or ``None`` to mean that the
     954          variable has not upper bound.
     955
     956        EXAMPLE::
     957
     958            sage: from sage.numerical.backends.generic_backend import getSolver
     959            sage: p = getSolver(solver = "GLPK")
     960            sage: p.add_variable()
     961            1
     962            sage: p.get_col_bounds(0)
     963            (0.0, None)
     964            sage: p.set_variable_max(0, 5)
     965            sage: p.get_col_bounds(0)
     966            (0.0, 5.0)
     967        """
     968
     969        cdef double min = glp_get_col_lb(self.lp, index + 1)
     970
     971        if value is None and min == -DBL_MAX:
     972            glp_set_col_bnds(self.lp, index + 1, GLP_FR, 0, 0)
     973
     974        elif value is None:
     975            glp_set_col_bnds(self.lp, index + 1, GLP_LO, min, 0)
     976
     977        elif min == -DBL_MAX:
     978            glp_set_col_bnds(self.lp, index + 1, GLP_UP, 0, value)
     979           
     980        elif min == value:
     981            glp_set_col_bnds(self.lp, index + 1, GLP_FX,  value, value)
     982
     983        else:
     984            glp_set_col_bnds(self.lp, index + 1, GLP_DB, min, value)
     985
     986    cpdef set_variable_min(self, int index, value):
     987        r"""
     988        Sets the lower bound on a variable
     989
     990        INPUT:
     991
     992        - ``index`` (integer) -- the variable's id
     993
     994        - ``value`` -- real value, or ``None`` to mean that the
     995          variable has not lower bound.
     996
     997        EXAMPLE::
     998
     999            sage: from sage.numerical.backends.generic_backend import getSolver
     1000            sage: p = getSolver(solver = "GLPK")
     1001            sage: p.add_variable()
     1002            1
     1003            sage: p.get_col_bounds(0)
     1004            (0.0, None)
     1005            sage: p.set_variable_min(0, 5)
     1006            sage: p.get_col_bounds(0)
     1007            (5.0, None)
     1008        """
     1009   
     1010        cdef double max = glp_get_col_ub(self.lp, index + 1)
     1011
     1012        if value is None and max == DBL_MAX:
     1013            glp_set_col_bnds(self.lp, index + 1, GLP_FR, 0.0, 0.0)
     1014
     1015        elif value is None:
     1016            glp_set_col_bnds(self.lp, index + 1, GLP_UP, 0.0, max)
     1017
     1018        elif max == DBL_MAX:
     1019            glp_set_col_bnds(self.lp, index + 1, GLP_LO, value, 0.0)
     1020           
     1021        elif max == value:
     1022            glp_set_col_bnds(self.lp, index + 1, GLP_FX,  value, value)
     1023
     1024        else:
     1025            glp_set_col_bnds(self.lp, index + 1, GLP_DB, value, min)
     1026
     1027    cpdef write_lp(self, char * filename):
     1028        r"""
     1029        Writes the problem to a .lp file
     1030
     1031        INPUT:
     1032       
     1033        - ``filename`` (string)
     1034
     1035        EXAMPLE::
     1036
     1037            sage: from sage.numerical.backends.generic_backend import getSolver
     1038            sage: p = getSolver(solver = "GLPK")
     1039            sage: p.add_variables(2)
     1040            2
     1041            sage: p.add_constraint([0, 1], [1, 2], +1, 3)
     1042            sage: p.set_objective([2, 5])
     1043            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")
     1044        """
     1045        glp_write_lp(self.lp, NULL, filename)
     1046
     1047    cpdef write_mps(self, char * filename, int modern):
     1048        r"""
     1049        Writes the problem to a .mps file
     1050
     1051        INPUT:
     1052       
     1053        - ``filename`` (string)
     1054
     1055        EXAMPLE::
     1056
     1057            sage: from sage.numerical.backends.generic_backend import getSolver
     1058            sage: p = getSolver(solver = "GLPK")
     1059            sage: p.add_variables(2)
     1060            2
     1061            sage: p.add_constraint([0, 1], [1, 2], +1, 3)
     1062            sage: p.set_objective([2, 5])
     1063            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")
     1064        """
     1065        glp_write_mps(self.lp, modern, NULL,  filename)
     1066
     1067    def __dealloc__(self):
     1068        r"""
     1069        Destructor
     1070        """
     1071        glp_delete_prob(self.lp)
  • sage/numerical/mip.pxd

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/mip.pxd
    a b  
    11cdef extern from *:
    22    ctypedef double* const_double_ptr "const double*"
     3    cdef int BINARY = 1
     4    cdef int REAL = -1
     5    cdef int INTEGER = 0
    36
     7from sage.numerical.backends.generic_backend cimport GenericBackend
     8cdef class MIPVariable
     9cdef class MixedIntegerLinearProgram
    410
     11
     12
     13cdef class MixedIntegerLinearProgram:
     14    cdef GenericBackend _backend
     15    cdef list _mipvariables
     16    cdef MIPVariable _default_mipvariable
     17    cdef dict _variables
     18    cdef int __BINARY
     19    cdef int __REAL
     20    cdef int __INTEGER
     21
     22cdef class MIPVariable:
     23    cdef MixedIntegerLinearProgram _p
     24    cdef int _dim
     25    cdef dict _dict
     26    cdef int _vtype
     27    cdef char * _name
  • sage/numerical/mip.pyx

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/mip.pyx
    a b  
    6262    sage: _ = [ p.set_min(w[i], None) for i in range(1,4) ]
    6363    sage: p.set_objective(w[3])
    6464    sage: p.show()
    65     Minimization: 
    66       x_3
    67     Constraints: 
    68        0 <= x_0 +x_1 +x_2 -14 x_3 <= 0
    69        0 <= x_1 +2 x_2 -8 x_3 <= 0
    70        0 <= 2 x_2 -3 x_3 <= 0
    71        -1 x_0 +x_1 +x_2 <= 0
    72        -1 x_3 <= -1
    73     Variables: 
    74       x_0 is an integer variable (min=0.0, max=+oo) 
    75       x_1 is an integer variable (min=-oo, max=+oo) 
    76       x_2 is an integer variable (min=-oo, max=+oo) 
     65    Minimization:
     66       x_3
     67    Constraints:
     68      0.0 <= x_0 +x_1 +x_2 -14.0 x_3 <= 0.0
     69      0.0 <= x_1 +2.0 x_2 -8.0 x_3 <= 0.0
     70      0.0 <= 2.0 x_2 -3.0 x_3 <= 0.0
     71      -1.0 x_0 +x_1 +x_2 <= 0.0
     72      -1.0 x_3 <= -1.0
     73    Variables:
     74      x_0 is an integer variable (min=0.0, max=+oo)
     75      x_1 is an integer variable (min=-oo, max=+oo)
     76      x_2 is an integer variable (min=-oo, max=+oo)
    7777      x_3 is an integer variable (min=-oo, max=+oo)
    7878    sage: print 'Objective Value:', p.solve()
    7979    Objective Value: 2.0
     
    8989include "../ext/interrupt.pxi"
    9090from copy import deepcopy
    9191
    92 class MixedIntegerLinearProgram:
     92cdef class MixedIntegerLinearProgram:
    9393    r"""
    9494    The ``MixedIntegerLinearProgram`` class is the link between Sage, linear
    9595    programming (LP) and  mixed integer programming (MIP) solvers. See the
     
    128128         4.0
    129129    """
    130130   
    131     def __init__(self, maximization=True):
     131    def __init__(self, solver = None, maximization=True):
    132132        r"""
    133133        Constructor for the ``MixedIntegerLinearProgram`` class.
    134134
    135135        INPUT:
    136136
     137        - ``solver`` -- 3 solvers should be available through this class:
     138
     139          - GLPK (``solver="GLPK"``). See the
     140            `GLPK <http://www.gnu.org/software/glpk/>`_ web site.
     141
     142          - COIN Branch and Cut  (``solver="Coin"``). See the
     143            `COIN-OR <http://www.coin-or.org>`_ web site.
     144
     145          - CPLEX (``solver="CPLEX"``). See the
     146            `CPLEX <http://www.ilog.com/products/cplex/>`_ web site.
     147            An interface to CPLEX is not yet implemented.
     148
     149            ``solver`` should then be equal to one of ``"GLPK"``,
     150            ``"Coin"``, ``"CPLEX"``, or ``None``. If ``solver=None``
     151            (default), the solvers are tried in this order :
     152       
     153                * CPLEX
     154                * Coin
     155                * GLPK
     156   
     157            A backend corresponding to the first solver available is
     158            then returned
     159
     160
     161
    137162        - ``maximization``
    138163
    139164          - When set to ``True`` (default), the ``MixedIntegerLinearProgram``
     
    145170
    146171            sage: p = MixedIntegerLinearProgram(maximization=True)
    147172        """
    148        
    149         self._default_solver = None
    150        
    151         try:
    152             if self._default_solver == None:
    153                 from sage.numerical.mip_cplex import solve_cplex
    154                 self._default_solver = "CPLEX"
    155         except ImportError:
    156             pass
    157173
    158         try:
    159             if self._default_solver == None:
    160                 from sage.numerical.mip_coin import solve_coin
    161                 self._default_solver = "Coin"
    162         except ImportError:
    163             pass
     174        from sage.numerical.backends.generic_backend import getSolver
     175        self._backend = getSolver(solver = solver)
     176        if not maximization:
     177            self._backend.set_direction(-1)
    164178
    165         if self._default_solver == None:
    166             self._default_solver = "GLPK"
     179        self.__BINARY = 0
     180        self.__REAL = -1
     181        self.__INTEGER = 1
     182
    167183
    168184        # List of all the MIPVariables linked to this instance of
    169185        # MixedIntegerLinearProgram
     
    172188        # Associates an index to the variables
    173189        self._variables = {}
    174190
    175         # contains the variables' values when
    176         # solve(objective_only=False) is called
    177         self._values = {}
    178 
    179         # Several constants
    180         self.__BINARY = 1
    181         self.__REAL = -1
    182         self.__INTEGER = 0
    183 
    184         # ######################################################
    185         # The information data of a Linear Program
    186         #
    187         # - name
    188         # - maximization
    189         # - objective
    190         #    --> name
    191         #    --> i
    192         #    --> values
    193         # - variables
    194         #   --> names
    195         #   --> type
    196         #   --> bounds
    197         #       --> min
    198         #       --> max
    199         # - constraints
    200         #   --> names
    201         #   --> matrix
    202         #       --> i
    203         #       --> j
    204         #       --> values
    205         #   --> bounds
    206         #       --> min
    207         #       --> max
    208         #
    209         # The Constraint matrix being almost always sparse, it is stored
    210         # as a list of positions (i,j) in the matrix with an associated value.
    211         #
    212         # This is how matrices are exchanged in GLPK's or Cbc's libraries
    213         # By storing the data this way, we do no have to convert them
    214         # ( too often ) and this process is a bit faster.
    215         #
    216         # ######################################################
    217        
    218         self._name = None
    219         self._maximization = maximization
    220         self._objective_i = None
    221         self._objective_values = None
    222         self._objective_name = None
    223         self._variables_name = []
    224         self._variables_type = []
    225         self._variables_bounds_min = []
    226         self._variables_bounds_max = []
    227         self._constraints_name = []
    228         self._constraints_matrix_i = []
    229         self._constraints_matrix_j = []
    230         self._constraints_matrix_values = []
    231         self._constraints_bounds_max = []
    232         self._constraints_bounds_min = []
    233 
    234191    def __repr__(self):
    235192         r"""
    236193         Returns a short description of the ``MixedIntegerLinearProgram``.
     
    243200             sage: print p
    244201             Mixed Integer Program ( maximization, 2 variables, 1 constraints )
    245202         """
    246          return "Mixed Integer Program "+("\""+self._name+"\"" if self._name!=None else "")+" ( " + \
    247              ( "maximization" if self._maximization else "minimization" ) + \
    248              ", " + str(len(self._variables)) + " variables, " +  \
    249              str(len(self._constraints_bounds_min)) + " constraints )"
     203         cdef GenericBackend b = self._backend
    250204
    251     def __eq__(self,p):
    252         r"""
    253         Test of equality.
     205         return ("Mixed Integer Program "+
    254206
    255         INPUT:
     207                 ( "\"" +self._backend.get_problem_name()+ "\""
     208                   if (str(self._backend.get_problem_name()) != "") else "")+
    256209
    257         - ``p`` -- an instance of ``MixedIntegerLinearProgram`` to be tested
    258           against ``self``.
     210                 " ( " + ("maximization" if b.is_maximization() else "minimization" ) +
    259211
    260         EXAMPLE::
    261 
    262             sage: p = MixedIntegerLinearProgram()
    263             sage: v = p.new_variable()
    264             sage: p.add_constraint(v[1] + v[2], max=2)
    265             sage: p == loads(dumps(p))
    266             True
    267             sage: p2 = loads(dumps(p))
    268             sage: p2.add_constraint(2*v[1] + 3*v[2], max=1)
    269             sage: p == p2
    270             False
    271         """
    272 
    273         return (
    274             self._name == p._name and
    275             self._maximization == p._maximization and
    276             self._objective_i == p._objective_i and
    277             self._objective_values == p._objective_values and
    278             self._objective_name == p._objective_name and
    279             self._variables_name == p._variables_name and
    280             self._variables_type == p._variables_type and
    281             self._variables_bounds_min == p._variables_bounds_min and
    282             self._variables_bounds_max == p._variables_bounds_max and
    283             self._constraints_name == p._constraints_name and
    284             self._constraints_matrix_i == p._constraints_matrix_i and
    285             self._constraints_matrix_j == p._constraints_matrix_j and
    286             self._constraints_matrix_values == p._constraints_matrix_values and
    287             self._constraints_bounds_max == p._constraints_bounds_max
    288             )
     212                 ", " + str(b.n_cols()) + " variables, " +
     213                 str(b.n_rows()) + " constraints )")
    289214
    290215    def __getitem__(self, v):
    291216        r"""
     
    308233
    309234        try:
    310235            return self._default_mipvariable[v]
    311         except AttributeError:
     236        except TypeError:
    312237            self._default_mipvariable = self.new_variable()
    313238            return self._default_mipvariable[v]
    314239
     
    329254            Mixed Integer Program "Test program" ( maximization, 0 variables, 0 constraints )
    330255        """
    331256
    332         self._name=name       
     257        self._backend.set_problem_name(name)
    333258
    334259    def set_objective_name(self,name):
    335260        r"""
     
    346271            sage: p.set_objective_name("Objective function")
    347272        """
    348273
    349         self._objective_name=name       
     274        self._backend.set_objective_name(name)
    350275
    351276    def _update_variables_name(self):
    352277        r"""
     
    363288            sage: p._update_variables_name()
    364289        """
    365290
    366         self._variables_name=['']*len(self._variables)
    367291        for v in self._mipvariables:
    368292            v._update_variables_name()
    369293
     
    437361        self._mipvariables.append(v)
    438362        return v
    439363
    440     def constraints(self):
    441         r"""
    442         Returns the list of constraints.
    443 
    444         This function returns the constraints as a list
    445         of tuples ``(linear_function,min_bound,max_bound)``, representing
    446         the constraint:
    447 
    448         .. MATH::
    449        
    450             \text{min\_bound}
    451             \leq
    452             \text{linear\_function}
    453             \leq
    454             \text{max\_bound}
    455        
    456         Variables ``min_bound`` (respectively ``max_bound``) is set
    457         to ``None`` when the function has no lower ( respectively upper )
    458         bound.
    459        
    460         EXAMPLE::
    461 
    462             sage: p = MixedIntegerLinearProgram(maximization=True)
    463             sage: x = p.new_variable()
    464             sage: p.set_objective(x[1] + 5*x[2])
    465             sage: p.add_constraint(x[1] + 2/10*x[2], max=4)
    466             sage: p.add_constraint(15/10*x[1]+3*x[2], max=4)
    467             sage: p.constraints()
    468             [(x_0 +1/5 x_1, None, 4), (3/2 x_0 +3 x_1, None, 4)]
    469         """
    470        
    471         d = [0]*len(self._variables)
    472         for (v,id) in self._variables.iteritems():
    473             d[id]=v
    474 
    475         constraints=[0]*len(self._constraints_bounds_min)
    476         for (i,j,value) in zip(self._constraints_matrix_i,self._constraints_matrix_j,self._constraints_matrix_values):
    477             constraints[i]+=value*d[j]
    478         return zip(constraints,self._constraints_bounds_min,self._constraints_bounds_max)
    479 
    480 
    481364    def show(self):
    482365        r"""
    483366        Displays the ``MixedIntegerLinearProgram`` in a human-readable
     
    491374            sage: p.add_constraint(-3*x[1] + 2*x[2], max=2, name="Constraint_1")
    492375            sage: p.show()
    493376            Maximization:
    494               x_0 +x_1
     377               x_0 +x_1
    495378            Constraints:
    496               Constraint_1: -3 x_0 +2 x_1 <= 2
     379              Constraint_1: -3.0 x_0 +2.0 x_1 <= 2.0
    497380            Variables:
    498381              x_0 is a real variable (min=0.0, max=+oo)
    499382              x_1 is a real variable (min=0.0, max=+oo)
    500383        """
    501384
     385        cdef int i, j
     386        cdef double c
     387        cdef GenericBackend b = self._backend
    502388        self._update_variables_name()
    503389
    504390        inv_variables = [0]*len(self._variables)
    505391        for (v,id) in self._variables.iteritems():
    506392            inv_variables[id]=v
    507393
    508 
    509394        value = ( "Maximization:\n"
    510                   if self._maximization
     395                  if b.is_maximization()
    511396                  else "Minimization:\n" )
    512397        value+="  "
    513         if self._objective_i==None:
    514             value+="Undefined"
    515         else:
    516             value+=str(sum([inv_variables[i]*c for (i,c) in zip(self._objective_i, self._objective_values)]))
     398       
     399        first = True
     400        for 0<= i< b.n_cols():
     401            c = b.get_objective_coeff(i)
     402            if c != 0:
     403
     404                value+= ((" +" if (not first and c>0) else " ") +
     405                         str(inv_variables[i]*b.get_objective_coeff(i))
     406                         )
     407                first = False
    517408
    518409        value += "\nConstraints:"
    519         for (c,min,max), name in zip(self.constraints(), self._constraints_name):
    520             value += "\n  "+(name+":" if name is not None else "")+" " + (str(min)+" <= " if min!=None else "")+str(c)+(" <= "+str(max) if max!=None else "")
     410
     411
     412        for 0<= i < b.n_rows():
     413
     414            indices, values = b.get_row(i)
     415
     416            lb, ub = b.get_row_bounds(i)
     417
     418            value += ("\n  "+
     419                      (b.get_row_name(i)+": " if b.get_row_name(i)!="" else "")+
     420                      (str(lb)+" <= " if lb!=None else "")
     421                      )
     422
     423            first = True
     424
     425            for j,v in sorted(zip(indices, values)):
     426
     427                value += (("+" if (not first and v>=0) else "") +
     428                          str(inv_variables[j]*v) +" ")
     429
     430                first = False
     431
     432            value += ("<= "+str(ub) if ub!=None else "")
     433
    521434        value += "\nVariables:"
    522         for _,v in sorted([(str(x),x) for x in self._variables.keys()]):
    523            
    524             value += "\n  " + str(v) + " is"
    525             if self.is_integer(v):
     435
     436        for 0<= i < b.n_cols():
     437            value += "\n  " + str(inv_variables[i]) + " is"
     438
     439            if b.is_variable_integer(i):
    526440                value += " an integer variable"
    527             elif self.is_binary(v):
     441            elif b.is_variable_binary(i):
    528442                value += " an boolean variable"
    529443            else:
    530444                value += " a real variable"
     445
     446            lb, ub = b.get_col_bounds(i)
     447
    531448            value += " (min=" + \
    532                 ( str(self.get_min(v))
    533                   if self.get_min(v) != None
     449                ( str(lb)
     450                  if lb != None
    534451                  else "-oo" ) + \
    535452                ", max=" + \
    536                 ( str(self.get_max(v))
    537                   if self.get_max(v) != None
     453                ( str(ub)
     454                  if ub != None
    538455                  else "+oo" ) + \
    539456                ")"
    540457        print value
     
    567484        http://en.wikipedia.org/wiki/MPS_%28format%29
    568485        """
    569486       
    570         from sage.numerical.mip_glpk import write_mps
    571 
    572         self._update_variables_name()
    573         write_mps(self, filename, modern)
    574        
     487        self._backend.write_mps(filename, modern)       
    575488
    576489    def write_lp(self,filename):
    577490        r"""
     
    595508        For more information about the LP file format :
    596509        http://lpsolve.sourceforge.net/5.5/lp-format.htm
    597510        """
    598         from sage.numerical.mip_glpk import write_lp
    599511
    600         self._update_variables_name()
    601         write_lp(self, filename)
    602 
     512        self._backend.write_lp(filename)
    603513       
    604514    def get_values(self, *lists):
    605515        r"""
     
    658568                if l.depth() == 1:
    659569                    c = {}
    660570                    for (k,v) in l.items():
    661                         c[k] = self._values[v] if self._values.has_key(v) else None
     571                        #c[k] = self._values[v] if self._values.has_key(v) else None
     572                        c[k] = self._backend.get_variable_value(self._variables[v])
    662573                    val.append(c)
    663574                else:
    664575                    c = {}
     
    673584                    [c.append(self.get_values(ll)) for ll in l]
    674585                    val.append(c)
    675586            elif self._variables.has_key(l):
    676                 val.append(self._values[l])
     587                #val.append(self._values[l])
     588                val.append(self._backend.get_variable_value(self._variables[l]))
    677589        if len(lists) == 1:
    678590            return val[0]
    679591        else:
     
    716628            0.0
    717629        """
    718630
    719 
    720         self._objective_i = []
    721         self._objective_values = []
     631        cdef list values = []
    722632
    723633        # If the objective is None, or a constant, we want to remember
    724634        # that the objective function has been defined ( the user did not
    725635        # forget it ). In some LP problems, you just want a feasible solution
    726636        # and do not care about any function being optimal.
    727637
     638        cdef int i
     639
    728640        if obj != None:
    729641            f = obj.dict()
    730642        else:
    731             return None
     643            f = {-1 : 0}
    732644       
    733645        f.pop(-1,0)
    734646
    735         for (v,coeff) in f.iteritems():
    736             self._objective_i.append(v)
    737             self._objective_values.append(coeff)
     647        for i in range(self._backend.n_cols()):
     648            values.append(f.get(i,0))
    738649
     650        self._backend.set_objective(values)
     651           
    739652    def add_constraint(self, linear_function, max=None, min=None, name=None):
    740653        r"""
    741654        Adds a constraint to self.
     
    807720            sage: round(p.solve(), 5)
    808721            6.66667
    809722
    810 
    811723        TESTS::
    812724
    813725            sage: p=MixedIntegerLinearProgram()
     
    840752
    841753            f = linear_function.dict()
    842754
    843             self._constraints_name.append(name)
    844 
    845755            constant_coefficient = f.get(-1,0)
    846756
    847757            # We do not want to ignore the constant coefficient
    848758            max = (max - constant_coefficient) if max != None else None
    849759            min = (min - constant_coefficient) if min != None else None
    850760
    851             c = len(self._constraints_bounds_min)
     761            indices = []
     762            values = []
    852763
    853764            for (v,coeff) in f.iteritems():
    854765                if v != -1:
    855                     self._constraints_matrix_i.append(c)
    856                     self._constraints_matrix_j.append(v)
    857                     self._constraints_matrix_values.append(coeff)
     766                    indices.append(v)
     767                    values.append(coeff)
    858768
    859             self._constraints_bounds_max.append(max)
    860             self._constraints_bounds_min.append(min)
     769            if min == None and max == None:
     770                raise ValueError("Both max and min are set to None ? Weird !")
     771            elif min == max:
     772                self._backend.add_constraint(indices, values, 0, min)
     773            elif min != None:
     774                self._backend.add_constraint(indices, values, -1, min)
     775            elif max != None:
     776                self._backend.add_constraint(indices, values, +1, max)
     777
     778            if name != None:
     779                self._backend.set_row_name(self._backend.n_rows()-1,name)
    861780
    862781        elif isinstance(linear_function,LinearConstraint):
    863782            functions = linear_function.constraints
     
    872791                self.add_constraint(functions[0] - functions[1], max=0, name=name)
    873792                self.add_constraint(functions[1] - functions[2], max=0, name=name)
    874793
    875     def set_binary(self, e):
     794    def set_binary(self, ee):
    876795        r"""
    877796        Sets a variable or a ``MIPVariable`` as binary.
    878797
    879798        INPUT:
    880799
    881         - ``e`` -- An instance of ``MIPVariable`` or one of
     800        - ``ee`` -- An instance of ``MIPVariable`` or one of
    882801          its elements.
    883802
    884803        EXAMPLE::
     
    898817
    899818            sage: p.set_real(x[3])
    900819        """
     820        cdef MIPVariable e
     821        e = <MIPVariable> ee
     822
    901823        if isinstance(e, MIPVariable):
    902824            e._vtype = self.__BINARY
    903825            if e.depth() == 1:
    904826                for v in e.values():
    905                     self._variables_type[self._variables[v]] = self.__BINARY
     827                    self._backend.set_variable_type(self._variables[v],self.__BINARY)
    906828            else:
    907829                for v in e.keys():
    908830                    self.set_binary(e[v])
    909831        elif self._variables.has_key(e):
    910             self._variables_type[self._variables[e]] = self.__BINARY
     832            self._backend.set_variable_type(self._variables[e],self.__BINARY)
    911833        else:
    912834            raise ValueError("e must be an instance of MIPVariable or one of its elements.")
    913835
     
    936858            True
    937859        """
    938860
    939         if self._variables_type[self._variables[e]] == self.__BINARY:
    940             return True
    941         return False
     861        return self._backend.is_variable_binary(self._variables[e])
    942862
    943     def set_integer(self, e):
     863    def set_integer(self, ee):
    944864        r"""
    945865        Sets a variable or a ``MIPVariable`` as integer.
    946866
    947867        INPUT:
    948868
    949         - ``e`` -- An instance of ``MIPVariable`` or one of
     869        - ``ee`` -- An instance of ``MIPVariable`` or one of
    950870          its elements.
    951871
    952872        EXAMPLE::
     
    966886
    967887            sage: p.set_real(x[3])
    968888        """
     889        cdef MIPVariable e
     890        e = <MIPVariable> ee
     891
    969892        if isinstance(e, MIPVariable):
    970893            e._vtype = self.__INTEGER
    971894            if e.depth() == 1:
    972895                for v in e.values():
    973                     self._variables_type[self._variables[v]] = self.__INTEGER
     896                    self._backend.set_variable_type(self._variables[v],self.__INTEGER)
    974897            else:
    975898                for v in e.keys():
    976899                    self.set_integer(e[v])
    977900        elif self._variables.has_key(e):
    978             self._variables_type[self._variables[e]] = self.__INTEGER
     901            self._backend.set_variable_type(self._variables[e],self.__INTEGER)
    979902        else:
    980903            raise ValueError("e must be an instance of MIPVariable or one of its elements.")
    981904
     
    1004927            True
    1005928        """
    1006929
    1007         if self._variables_type[self._variables[e]] == self.__INTEGER:
    1008             return True
    1009         return False
     930        return self._backend.is_variable_integer(self._variables[e])
    1010931
    1011     def set_real(self,e):
     932    def set_real(self,ee):
    1012933        r"""
    1013934        Sets a variable or a ``MIPVariable`` as real.
    1014935
    1015936        INPUT:
    1016937
    1017         - ``e`` -- An instance of ``MIPVariable`` or one of
     938        - ``ee`` -- An instance of ``MIPVariable`` or one of
    1018939          its elements.
    1019940
    1020941        EXAMPLE::
     
    1034955
    1035956            sage: p.set_binary(x[3])
    1036957        """
     958
     959        cdef MIPVariable e
     960        e = <MIPVariable> ee
     961
    1037962        if isinstance(e, MIPVariable):
    1038963            e._vtype = self.__REAL
    1039964            if e.depth() == 1:
    1040965                for v in e.values():
    1041                     self._variables_type[self._variables[v]] = self.__REAL
     966                    self._backend.set_variable_type(self._variables[v],self.__REAL)
    1042967            else:
    1043968                for v in e.keys():
    1044969                    self.set_real(e[v])
    1045970        elif self._variables.has_key(e):
    1046             self._variables_type[self._variables[e]] = self.__REAL
     971            self._backend.set_variable_type(self._variables[e],self.__REAL)
    1047972        else:
    1048973            raise ValueError("e must be an instance of MIPVariable or one of its elements.")
    1049974
     
    1074999            True
    10751000        """
    10761001
    1077         if self._variables_type[self._variables[e]] == self.__REAL:
    1078             return True
    1079         return False
     1002        return self._backend.is_variable_continuous(self._variables[e])
    10801003
    1081     def solve(self, solver=None, log=0, objective_only=False, threads = 0):
     1004    def solve(self, solver=None, log=0, objective_only=False):
    10821005        r"""
    10831006        Solves the ``MixedIntegerLinearProgram``.
    10841007
    10851008        INPUT:
    10861009
    1087         - ``solver`` -- 3 solvers should be available through this class:
    1088 
    1089           - GLPK (``solver="GLPK"``). See the
    1090             `GLPK <http://www.gnu.org/software/glpk/>`_ web site.
    1091 
    1092           - COIN Branch and Cut  (``solver="Coin"``). See the
    1093             `COIN-OR <http://www.coin-or.org>`_ web site.
    1094 
    1095           - CPLEX (``solver="CPLEX"``). See the
    1096             `CPLEX <http://www.ilog.com/products/cplex/>`_ web site.
    1097             An interface to CPLEX is not yet implemented.
    1098 
    1099           ``solver`` should then be equal to one of ``"GLPK"``, ``"Coin"``,
    1100           ``"CPLEX"``, or ``None``. If ``solver=None`` (default), the default
    1101           solver is used (COIN if available, GLPK otherwise).
     1010        - ``solver`` -- DEPRECATED -- the solver now has to be set
     1011          when calling the class' constructor
    11021012
    11031013        - ``log`` -- integer (default: ``0``) The verbosity level. Indicates
    11041014          whether progress should be printed during computation.
    11051015
    1106         - ``threads`` -- Number of threads to use. This option is only useful
    1107           when Coin is used to solve the problem. Set ``threads`` to 0 (its
    1108           default value) to use one thread per core available.
    1109 
    11101016        - ``objective_only`` -- Boolean variable.
    11111017
    11121018          - When set to ``True``, only the objective function is returned.
     
    11581064            4.0
    11591065        """
    11601066
     1067        if solver != None:
     1068            raise ValueError("Solver argument deprecated. This parameter now has to be set when calling the class' constructor")
    11611069
    1162         if self._objective_i == None:
    1163             raise ValueError("No objective function has been defined.")
     1070        self._backend.set_log_level(log)
    11641071
    1165         if solver == None:
    1166             solver = self._default_solver
     1072        self._backend.solve()
    11671073
    1168         try:
    1169             if solver == "Coin":
    1170                 from sage.numerical.mip_coin import solve_coin as solve
    1171             elif solver == "GLPK":
    1172                 from sage.numerical.mip_glpk import solve_glpk as solve
    1173             elif solver == "CPLEX":
    1174                 from sage.numerical.mip_cplex import solve_cplex as solve
    1175             else:
    1176                 raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX' or None (in which case the default one is used).")
     1074        return self._backend.get_objective_value()
    11771075
    1178         except ImportError:
    1179             from sage.misc.exceptions import OptionalPackageNotFoundError
    1180             raise OptionalPackageNotFoundError("The required solver is not installed and cannot be used to solve this (Mixed) Integer Linear Program. To install it, follow the instructions given at http://www.sagemath.org/doc/constructions/linear_programming.html")
    1181            
    1182 
    1183         if solver=="Coin":
    1184             return solve(self, log=log, objective_only=objective_only, threads=threads)
    1185         else:
    1186             return solve(self, log=log, objective_only=objective_only)
    1187        
    11881076
    11891077    def _add_element_to_ring(self, vtype):
    11901078        r"""
     
    12031091
    12041092            sage: p = MixedIntegerLinearProgram()
    12051093            sage: v = p.new_variable()
    1206             sage: len(p._variables_type)
    1207             0
    1208             sage: p._add_element_to_ring(p.__REAL)
     1094            sage: print p
     1095            Mixed Integer Program  ( maximization, 0 variables, 0 constraints )
     1096            sage: p._add_element_to_ring(-1)
    12091097            x_0
    1210             sage: len(p._variables_type)
    1211             1
     1098            sage: print p
     1099            Mixed Integer Program  ( maximization, 1 variables, 0 constraints )
    12121100        """
    12131101
    12141102        v = LinearFunction({len(self._variables) : 1})
    12151103
    12161104        self._variables[v] = len(self._variables)
    1217         self._variables_type.append(vtype)
    1218         self._variables_bounds_min.append(0)
    1219         self._variables_bounds_max.append(None)
     1105        self._backend.add_variable()
     1106        self._backend.set_variable_type(self._backend.n_cols()-1,vtype)
    12201107        return v
    12211108
    12221109    def set_min(self, v, min):
     
    12411128            sage: p.get_min(v[1])
    12421129            6.0
    12431130        """
    1244         self._variables_bounds_min[self._variables[v]] = min
     1131        self._backend.set_variable_min(self._variables[v], min)
    12451132
    12461133    def set_max(self, v, max):
    12471134        r"""
     
    12651152            6.0
    12661153        """
    12671154
    1268         self._variables_bounds_max[self._variables[v]] = max
     1155        self._backend.set_variable_max(self._variables[v], max)
    12691156
    12701157    def get_min(self, v):
    12711158        r"""
     
    12911178            sage: p.get_min(v[1])
    12921179            6.0
    12931180        """
    1294         return float(self._variables_bounds_min[self._variables[v]]) if self._variables_bounds_min[self._variables[v]] != None else None
     1181
     1182        return self._backend.get_variable_min(self._variables[v])
    12951183
    12961184    def get_max(self, v):
    12971185        r"""
     
    13161204            sage: p.get_max(v[1])
    13171205            6.0
    13181206        """
    1319         return float(self._variables_bounds_max[self._variables[v]])  if self._variables_bounds_max[self._variables[v]] != None else None
     1207
     1208        return self._backend.get_variable_max(self._variables[v])
    13201209
    13211210class MIPSolverException(Exception):
    13221211    r"""
     
    13391228
    13401229         No continuous solution::
    13411230
    1342             sage: p=MixedIntegerLinearProgram()
     1231            sage: p=MixedIntegerLinearProgram(solver="GLPK")
    13431232            sage: v=p.new_variable()
    13441233            sage: p.add_constraint(v[0],max=5.5)
    13451234            sage: p.add_constraint(v[0],min=7.6)
     
    13471236
    13481237         Tests of GLPK's Exceptions::
    13491238
    1350             sage: p.solve(solver="GLPK")
     1239            sage: p.solve()
    13511240            Traceback (most recent call last):
    13521241            ...
    13531242            MIPSolverException: 'GLPK : Solution is undefined'
    13541243
    13551244         No integer solution::
    13561245
    1357             sage: p=MixedIntegerLinearProgram()
     1246            sage: p=MixedIntegerLinearProgram(solver="GLPK")
    13581247            sage: v=p.new_variable()
    13591248            sage: p.add_constraint(v[0],max=5.6)
    13601249            sage: p.add_constraint(v[0],min=5.2)
     
    13631252
    13641253         Tests of GLPK's Exceptions::
    13651254
    1366             sage: p.solve(solver="GLPK")
     1255            sage: p.solve()
    13671256            Traceback (most recent call last):
    13681257            ...
    13691258            MIPSolverException: 'GLPK : Solution is undefined'
    1370 
    1371 
    13721259        """
    13731260        self.value = value
    13741261
     
    13851272        """
    13861273        return repr(self.value)
    13871274
    1388 class MIPVariable:
     1275cdef class MIPVariable:
    13891276    r"""
    13901277    ``MIPVariable`` is a variable used by the class
    13911278    ``MixedIntegerLinearProgram``.
    13921279    """
    13931280
    1394     def __init__(self, p, vtype, dim=1, name=None):
     1281    def __init__(self, p, vtype, dim=1, name=""):
    13951282        r"""
    13961283        Constructor for ``MIPVariable``.
    13971284
     
    14161303        self._dict = {}
    14171304        self._p = p
    14181305        self._vtype = vtype
    1419         self._name=name
     1306
     1307        #####################################################
     1308        self._name="x"
    14201309
    14211310
    14221311    def __getitem__(self, i):
     
    14551344            sage: v=p.new_variable(name="Test")
    14561345            sage: v[5]+v[99]
    14571346            x_0 +x_1
    1458             sage: p._variables_name=['']*2
    14591347            sage: v._update_variables_name()
    14601348        """
    14611349
     
    14641352
    14651353        if self._dim == 1:
    14661354            for (k,v) in self._dict.iteritems():
    1467                 self._p._variables_name[self._p._variables[v]]=prefix + "[" + str(k) + "]"
     1355                name = prefix + "[" + str(k) + "]"
     1356                self._p._backend.set_col_name(self._p._variables[v], name)
     1357                #self._p._variables_name[self._p._variables[v]]=prefix + "[" + str(k) + "]"
    14681358        else:
    14691359            for v in self._dict.itervalues():
    1470                 v._update_variables_name(prefix=prefix + "[" + str(k) + "]")
     1360                v._update_variables_name(prefix=prefix + "(" + str(k) + ")")
    14711361               
    14721362               
    14731363
  • deleted file sage/numerical/mip_coin.pxd

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/mip_coin.pxd
    + -  
    1 cdef extern from *:
    2     ctypedef double* const_double_ptr "const double*"
    3 
    4 cdef 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 *)
    9 cdef 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 
    16 cdef 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 
    23 cdef 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 
    32 cdef 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 *)
    60 
    61 from sage.numerical.osi_interface cimport Osi_interface
    62 from sage.numerical.osi_interface cimport c_OsiSolverInterface
  • deleted file sage/numerical/mip_coin.pyx

    diff -r 7ae7b5175304 -r 0b5f2ba89540 sage/numerical/mip_coin.pyx
    + -  
    1 include '../../../../devel/sage/sage/ext/stdsage.pxi'
    2 
    3 cdef int BINARY = 1
    4 cdef int REAL = -1
    5 cdef int INTEGER = 0
    6 
    7 
    8 def solve_coin(self,log=0,objective_only=False, threads = 0):
    9     r"""
    10     Solves the ``MixedIntegerLinearProgram`` using COIN-OR CBC/CLP
    11     *Use ``solve()`` instead*
    12 
    13     INPUT:
    14    
    15     - ``log`` (integer) -- level of verbosity during the
    16       solving process. Set ``log=3`` for maximal verbosity and
    17       ``log=0`` for no verbosity at all.
    18 
    19     - ``objective_only`` (boolean) -- Indicates whether the
    20       values corresponding to an optimal assignment of the
    21       variables should be computed. Setting ``objective_only``
    22       to ``True`` saves some time on the computation when
    23       this information is not needed.
    24 
    25     - ``threads`` -- Number of threads to use. Set ``threads``
    26       to 0 (its default value) to use one thread per core available.
    27 
    28 
    29     OUTPUT:
    30 
    31     This function returns the optimal value of the objective
    32     function given by Coin.
    33 
    34     EXAMPLE:
    35 
    36     Solving a simple Linear Program using Coin as a solver
    37     (Computation of a maximum stable set in Petersen's graph)::
    38 
    39         sage: from sage.numerical.mip_coin import solve_coin     # optional - CBC
    40         sage: g = graphs.PetersenGraph()
    41         sage: p = MixedIntegerLinearProgram(maximization=True)
    42         sage: b = p.new_variable()
    43         sage: p.set_objective(sum([b[v] for v in g]))
    44         sage: for (u,v) in g.edges(labels=None):
    45         ...       p.add_constraint(b[u] + b[v], max=1)
    46         sage: p.set_binary(b)
    47         sage: solve_coin(p,objective_only=True)     # optional - CBC
    48         4.0
    49     """
    50     # Creates the solver interfaces
    51     cdef c_OsiCbcSolverInterface* si
    52     si = new_c_OsiCbcSolverInterface();
    53 
    54     # stuff related to the loglevel
    55     cdef c_CoinMessageHandler * msg
    56     cdef c_CbcModel * model
    57     model = si.getModelPtr()
    58     if threads == 0:
    59         import multiprocessing
    60         model.setNumberThreads(multiprocessing.cpu_count())
    61     else:
    62         model.setNumberThreads(threads)
    63        
    64 
    65     msg = model.messageHandler()
    66     msg.setLogLevel(log)
    67 
    68     from sage.numerical.mip import MIPSolverException
    69    
    70     cdef Osi_interface OSI
    71     OSI = Osi_interface()
    72 
    73 
    74     return_value = OSI.osi_solve(self, <c_OsiSolverInterface *> si, objective_only, False)
    75     del_OsiCbcSolverInterface(si)
    76 
    77     return return_value