Ticket #10341: trac_10431-part2.patch

File trac_10431-part2.patch, 57.7 KB (added by ncohen, 11 years ago)
  • sage/numerical/backends/coin_backend.pyx

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1290872901 -3600
    # Node ID 4825b49a4b2a955775c29046950b6f02444cc97b
    # Parent  cfaca337639bd3628804c0633d8074e04038dfa0
    trac 10341 -- make MIP backend interface more Python-ic -- Coin and CPLEX
    
    diff -r cfaca337639b -r 4825b49a4b2a sage/numerical/backends/coin_backend.pyx
    a b  
    3535        else:
    3636            self.set_sense(-1)
    3737
    38     cpdef int add_variable(self):
    39         r"""
    40         Adds a variable.
     38    cpdef int add_variable(self, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False) except -1:
     39        """
     40        Add a variable.
    4141
    4242        This amounts to adding a new column to the matrix. By default,
    4343        the variable is both positive and real.
    4444
     45        INPUT:
     46
     47        - ``lower_bound`` - the lower bound of the variable (default: 0)
     48
     49        - ``upper_bound`` - the upper bound of the variable (default: ``None``)
     50
     51        - ``binary`` - ``True`` if the variable is binary (default: ``False``).
     52
     53        - ``continuous`` - ``True`` if the variable is binary (default: ``True``).
     54
     55        - ``integer`` - ``True`` if the variable is binary (default: ``False``).
     56
     57        OUTPUT: The index of the newly created variable           
     58
    4559        EXAMPLE::
    4660
    4761            sage: from sage.numerical.backends.generic_backend import get_solver
    48             sage: p = get_solver(solver = "Coin")    # optional - Coin
     62            sage: p = get_solver(solver = "Coin")                  # optional - Coin
    4963            sage: p.ncols()                                         # optional - Coin
    5064            0
    51             sage: p.add_variable()                                   # optional - Coin
    52             1
     65            sage: p.add_variable()                                  # optional - Coin
     66            0
    5367            sage: p.ncols()                                         # optional - Coin
    5468            1
     69            sage: p.add_variable(binary=True)                       # optional - Coin
     70            1
     71            sage: p.add_variable(lower_bound=-2.0, integer=True)    # optional - Coin
     72            2
     73            sage: p.add_variable(continuous=True, integer=True)     # optional - Coin
     74            Traceback (most recent call last):
     75            ...
     76            ValueError: ...           
    5577        """
    5678
     79        cdef int vtype = int(bool(binary)) + int(bool(continuous)) + int(bool(integer))
     80        if  vtype == 0:
     81            continuous = True           
     82        elif vtype != 1:
     83            raise ValueError("Exactly one parameter of 'binary', 'integer' and 'continuous' must be 'True'.")
     84
    5785        self.si.addCol(0, NULL, NULL, 0, self.si.getInfinity(), 0)
    58         return self.si.getNumCols()
    5986
    60     cpdef int add_variables(self, int number):
    61         r"""
    62         Adds ``number`` variables.
     87        cdef int n
     88        n = self.si.getNumCols() - 1
     89
     90        if lower_bound != 0.0:
     91            self.variable_lower_bound(n, lower_bound)
     92        if upper_bound is not None:
     93            self.variable_upper_bound(n, upper_bound)
     94
     95        if binary:
     96            self.set_variable_type(n,0)
     97        elif integer:
     98            self.set_variable_type(n,1)
     99
     100        return n
     101
     102    cpdef int add_variables(self, int number, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False) except -1:
     103        """
     104        Add ``number`` new variables.
    63105
    64106        This amounts to adding new columns to the matrix. By default,
    65107        the variables are both positive and real.
    66108
     109        INPUT:
     110
     111        - ``n`` - the number of new variables (must be > 0)
     112
     113        - ``lower_bound`` - the lower bound of the variable (default: 0)
     114
     115        - ``upper_bound`` - the upper bound of the variable (default: ``None``)
     116
     117        - ``binary`` - ``True`` if the variable is binary (default: ``False``).
     118
     119        - ``continuous`` - ``True`` if the variable is binary (default: ``True``).
     120
     121        - ``integer`` - ``True`` if the variable is binary (default: ``False``).
     122
     123        OUTPUT: The index of the variable created last.
     124
    67125        EXAMPLE::
    68126
    69127            sage: from sage.numerical.backends.generic_backend import get_solver
    70             sage: p = get_solver(solver = "Coin")    # optional - Coin
    71             sage: p.ncols()                                         # optional - Coin
     128            sage: p = get_solver(solver = "Coin")                         # optional - Coin
     129            sage: p.ncols()                                                # optional - Coin
    72130            0
    73             sage: p.add_variables(5)                                 # optional - Coin
     131            sage: p.add_variables(5)                                       # optional - Coin
     132            4
     133            sage: p.ncols()                                                # optional - Coin
    74134            5
    75             sage: p.ncols()                                         # optional - Coin
    76             5
     135            sage: p.add_variables(2, lower_bound=-2.0, integer=True)       # optional - Coin
     136            6
    77137        """
     138        cdef int vtype = int(bool(binary)) + int(bool(continuous)) + int(bool(integer))
     139        if  vtype == 0:
     140            continuous = True           
     141        elif vtype != 1:
     142            raise ValueError("Exactly one parameter of 'binary', 'integer' and 'continuous' must be 'True'.")
     143
     144        cdef int n
     145        n = self.si.getNumCols()
    78146
    79147        cdef int i
    80         for 0<= i< number:
     148       
     149        for 0<= i < number:
     150
    81151            self.si.addCol(0, NULL, NULL, 0, self.si.getInfinity(), 0)
    82         return self.si.getNumCols()
     152
     153            if lower_bound != 0.0:
     154                self.variable_lower_bound(n + i, lower_bound)
     155            if upper_bound is not None:
     156                self.variable_upper_bound(n + i, upper_bound)
     157
     158            if binary:
     159                self.set_variable_type(n + i,0)
     160            elif integer:
     161                self.set_variable_type(n + i,1)
     162
     163        return n + number -1
    83164
    84165    cpdef set_variable_type(self, int variable, int vtype):
    85166        r"""
     
    102183            sage: p.ncols()                                        # optional - Coin
    103184            0
    104185            sage: p.add_variable()                                  # optional - Coin
    105             1
     186            0
    106187            sage: p.set_variable_type(0,1)                          # optional - Coin
    107188            sage: p.is_variable_integer(0)                          # optional - Coin
    108189            True
     
    155236            sage: from sage.numerical.backends.generic_backend import get_solver
    156237            sage: p = get_solver(solver = "Coin")  # optional - Coin
    157238            sage: p.add_variable()                                 # optional - Coin
    158             1
     239            0
    159240            sage: p.get_objective_coefficient(0)                         # optional - Coin
    160241            0.0
    161242            sage: p.set_objective_coefficient(0,2)                       # optional - Coin
     
    179260            sage: from sage.numerical.backends.generic_backend import get_solver
    180261            sage: p = get_solver(solver = "Coin")    # optional - Coin
    181262            sage: p.add_variables(5)                                 # optional - Coin
    182             5
     263            4
    183264            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - Coin
    184265            sage: map(lambda x :p.get_objective_coefficient(x), range(5))  # optional - Coin
    185266            [1.0, 1.0, 2.0, 1.0, 3.0]
     
    211292        msg = model.messageHandler()
    212293        msg.setLogLevel(level)
    213294
    214     cpdef add_linear_constraints(self, int number, int direction, double bound):
    215         r"""
    216         Adds constraints.
     295    cpdef add_linear_constraints(self, int number, lower_bound, upper_bound):
     296        """
     297        Add ``'number`` linear constraints.
    217298
    218299        INPUT:
    219300
    220301        - ``number`` (integer) -- the number of constraints to add.
    221302
    222         - ``direction`` (integer) -- the direction of the constraint,
    223           where :
     303        - ``lower_bound`` - a lower bound, either a real value or ``None``
    224304
    225               * +1 indicates : function `\leq` ``bound``
    226               *  0 indicates : function `=` ``bound``
    227               * -1 indicates : function `\geq` ``bound``
    228 
    229         - ``bound`` (double) -- value of the right-hand side (as
    230           illustrated immediately above).
     305        - ``upper_bound`` - an upper bound, either a real value or ``None``
    231306
    232307        EXAMPLE::
    233308
    234309            sage: from sage.numerical.backends.generic_backend import get_solver
    235             sage: p = get_solver(solver = "Coin")   # optional - Coin
    236             sage: p.add_variables(5)                                # optional - Coin
    237             5
    238             sage: p.add_linear_constraints(5, +1, 2)                       # optional - Coin
    239             sage: p.row(4)                                      # optional - Coin
     310            sage: p = get_solver(solver = "Coin")        # optional - Coin
     311            sage: p.add_variables(5)                     # optional - Coin
     312            4
     313            sage: p.add_linear_constraints(5, None, 2)   # optional - Coin
     314            sage: p.row(4)                               # optional - Coin
    240315            ([], [])
    241             sage: p.row_bounds(4)                               # optional - Coin
     316            sage: p.row_bounds(4)                        # optional - Coin
    242317            (None, 2.0)
    243318        """
    244319
    245320        cdef int i
    246321        for 0<= i<number:
    247             self.add_linear_constraint([],[],direction, bound)
     322            self.add_linear_constraint([],lower_bound, upper_bound)
    248323
    249     cpdef add_linear_constraint(self, list indices, list coeffs, int direction, double bound):
    250         r"""
    251         Adds a linear constraint.
     324    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound):
     325        """
     326        Add a linear constraint.
    252327
    253328        INPUT:
    254329
    255         - ``indices`` (list of integers) -- this list constains the
    256           indices of the variables whose coefficient is nonzero in the
    257           constraint.
     330        - ``coefficients`` an iterable with ``(c,v)`` pairs where ``c``
     331          is a variable index (integer) and ``v`` is a value (real
     332          value).
    258333
    259         - ``coeffs`` (list of real values) -- associates a coefficient
    260           to the variables listed by ``indices``. Namely, the ith
    261           entry of ``coeffs`` corresponds to the coefficient of the
    262           variable represented by the ith entry in ``indices``.
     334        - ``lower_bound`` - a lower bound, either a real value or ``None``
    263335
    264         - ``direction`` (integer) -- the direction of the constraint,
    265           where :
    266 
    267               * +1 indicates : function `\leq` ``bound``
    268               *  0 indicates : function `=` ``bound``
    269               * -1 indicates : function `\geq` ``bound``
    270 
    271         - ``bound`` (double) -- value of the right-hand side (as
    272           illustrated immediately above).
    273 
    274         .. NOTE::
    275 
    276             ``indices`` and ``coeffs`` are expected to be of the same
    277             length.
    278 
     336        - ``upper_bound`` - an upper bound, either a real value or ``None``
     337 
    279338        EXAMPLE::
    280339
    281340            sage: from sage.numerical.backends.generic_backend import get_solver
    282             sage: p = get_solver(solver = "Coin") # optional - Coin
    283             sage: p.add_variables(5)                              # optional - Coin
    284             5
    285             sage: p.add_linear_constraint(range(5), range(5), 0, 2)      # optional - Coin
    286             sage: p.row(0)                                    # optional - Coin
     341            sage: p = get_solver(solver = "Coin")                              # optional - Coin
     342            sage: p.add_variables(5)                                           # optional - Coin
     343            4
     344            sage: p.add_linear_constraint( zip(range(5), range(5)), 2.0, 2.0)  # optional - Coin
     345            sage: p.row(0)                                                     # optional - Coin
    287346            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
    288             sage: p.row_bounds(0)                             # optional - Coin
     347            sage: p.row_bounds(0)                                              # optional - Coin
    289348            (2.0, 2.0)
    290349        """
     350        if lower_bound is None and upper_bound is None:
     351            raise ValueError("At least one of 'upper_bound' or 'lower_bound' must be set.")
    291352
    292353        cdef int i
    293         cdef int n = len(indices)
     354        cdef double c
    294355        cdef c_CoinPackedVector* row
    295356        row = new_c_CoinPackedVector();
    296357
    297         for 0<= i<n:
    298             row.insert(indices[i], coeffs[i])
     358        for i,c in coefficients:
     359            row.insert(i, c)
    299360
    300361        self.si.addRow (row[0],
    301                         bound if direction != +1 else -self.si.getInfinity(),
    302                         bound if direction != -1 else +self.si.getInfinity())
     362                        lower_bound if lower_bound != None else -self.si.getInfinity(),
     363                        upper_bound if upper_bound != None else +self.si.getInfinity())
    303364
    304365
    305366    cpdef row(self, int index):
     
    322383            sage: from sage.numerical.backends.generic_backend import get_solver
    323384            sage: p = get_solver(solver = "Coin")  # optional - Coin
    324385            sage: p.add_variables(5)                               # optional - Coin
    325             5
    326             sage: p.add_linear_constraint(range(5), range(5), 0, 2)       # optional - Coin
     386            4
     387            sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)       # optional - Coin
    327388            sage: p.row(0)                                     # optional - Coin
    328389            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
    329390            sage: p.row_bounds(0)                              # optional - Coin
     
    367428            sage: from sage.numerical.backends.generic_backend import get_solver
    368429            sage: p = get_solver(solver = "Coin")  # optional - Coin
    369430            sage: p.add_variables(5)                               # optional - Coin
    370             5
    371             sage: p.add_linear_constraint(range(5), range(5), 0, 2)       # optional - Coin
     431            4
     432            sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)       # optional - Coin
    372433            sage: p.row(0)                                     # optional - Coin
    373434            ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0])
    374435            sage: p.row_bounds(0)                              # optional - Coin
     
    403464            sage: from sage.numerical.backends.generic_backend import get_solver
    404465            sage: p = get_solver(solver = "Coin")  # optional - Coin
    405466            sage: p.add_variable()                                 # optional - Coin
    406             1
     467            0
    407468            sage: p.col_bounds(0)                              # optional - Coin
    408469            (0.0, None)
    409             sage: p.variable_max(0, 5)                         # optional - Coin
     470            sage: p.variable_upper_bound(0, 5)                         # optional - Coin
    410471            sage: p.col_bounds(0)                              # optional - Coin
    411472            (0.0, 5.0)
    412473        """
     
    433494            sage: from sage.numerical.backends.generic_backend import get_solver
    434495            sage: p = get_solver(solver = "Coin")  # optional - Coin
    435496            sage: p.add_variables(2)                               # optional - Coin
    436             2
    437             sage: p.add_linear_constraint([0, 1], [1, 2], +1, 3)          # optional - Coin
     497            1
     498            sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3)          # optional - Coin
    438499            sage: p.set_objective([2, 5])                          # optional - Coin
    439500            sage: p.solve()                                        # optional - Coin
    440501            0
     
    476537            0
    477538            sage: p.nrows()                                       # optional - Coin
    478539            0
    479             sage: p.add_linear_constraints(5, -1, 0)                      # optional - Coin
     540            sage: p.add_linear_constraints(5, 0, None)                      # optional - Coin
    480541            sage: p.add_col(range(5), range(5))                    # optional - Coin
    481542            sage: p.nrows()                                       # optional - Coin
    482543            5
     
    508569
    509570            sage: from sage.numerical.backends.generic_backend import get_solver
    510571            sage: p = get_solver(solver = "Coin")    # optional - Coin
    511             sage: p.add_linear_constraints(5, -1, 0)       # optional - Coin
     572            sage: p.add_linear_constraints(5, 0, None)       # optional - Coin
    512573            sage: p.add_col(range(5), [1,2,3,4,5])  # optional - Coin
    513574            sage: p.solve()                         # optional - Coin
    514575            0
     
    518579            sage: from sage.numerical.backends.generic_backend import get_solver
    519580            sage: p = get_solver(solver = "Coin")    # optional - Coin
    520581            sage: p.add_variable()                  # optional - Coin
    521             1
    522             sage: p.add_linear_constraint([0], [1], +1, 4) # optional - Coin
    523             sage: p.add_linear_constraint([0], [1], -1, 6) # optional - Coin
     582            0
     583            sage: p.add_linear_constraint([(0, 1)], None, 4) # optional - Coin
     584            sage: p.add_linear_constraint([(0, 1)], 6, None) # optional - Coin
    524585            sage: p.set_objective_coefficient(0,1)        # optional - Coin
    525586            sage: p.solve()                         # optional - Coin
    526587            Traceback (most recent call last):
     
    560621            sage: from sage.numerical.backends.generic_backend import get_solver
    561622            sage: p = get_solver(solver = "Coin")  # optional - Coin
    562623            sage: p.add_variables(2)                               # optional - Coin
    563             2
    564             sage: p.add_linear_constraint([0, 1], [1, 2], +1, 3)          # optional - Coin
     624            1
     625            sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3)          # optional - Coin
    565626            sage: p.set_objective([2, 5])                          # optional - Coin
    566627            sage: p.solve()                                        # optional - Coin
    567628            0
     
    588649            sage: from sage.numerical.backends.generic_backend import get_solver
    589650            sage: p = get_solver(solver = "Coin") # optional - Coin
    590651            sage: p.add_variables(2)                              # optional - Coin
    591             2
    592             sage: p.add_linear_constraint([0, 1], [1, 2], +1, 3)         # optional - Coin
     652            1
     653            sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3)          # optional - Coin
    593654            sage: p.set_objective([2, 5])                         # optional - Coin
    594655            sage: p.solve()                                       # optional - Coin
    595656            0
     
    616677            sage: p.ncols()                                       # optional - Coin
    617678            0
    618679            sage: p.add_variables(2)                               # optional - Coin
    619             2
     680            1
    620681            sage: p.ncols()                                       # optional - Coin
    621682            2
    622683        """
     
    633694            sage: p = get_solver(solver = "Coin") # optional - Coin
    634695            sage: p.nrows()                                      # optional - Coin
    635696            0
    636             sage: p.add_linear_constraints(2, -1, 2)                     # optional - Coin
     697            sage: p.add_linear_constraints(2, 2, None)                     # optional - Coin
    637698            sage: p.nrows()                                      # optional - Coin
    638699            2
    639700        """
     
    655716            sage: p.ncols()                                       # optional - Coin
    656717            0
    657718            sage: p.add_variable()                                 # optional - Coin
    658             1
     719            0
    659720            sage: p.set_variable_type(0,0)                         # optional - Coin
    660721            sage: p.is_variable_binary(0)                          # optional - Coin
    661722            True
     
    663724        """
    664725
    665726        return (0 == self.si.isContinuous(index) and
    666                 self.variable_min(index) == 0 and
    667                 self.variable_max(index) == 1)     
     727                self.variable_lower_bound(index) == 0 and
     728                self.variable_upper_bound(index) == 1)     
    668729
    669730    cpdef bint is_variable_integer(self, int index):
    670731        r"""
     
    681742            sage: p.ncols()                                       # optional - Coin
    682743            0
    683744            sage: p.add_variable()                                 # optional - Coin
    684             1
     745            0
    685746            sage: p.set_variable_type(0,1)                         # optional - Coin
    686747            sage: p.is_variable_integer(0)                         # optional - Coin
    687748            True
    688749        """
    689750        return (0 == self.si.isContinuous(index) and
    690                 (self.variable_min(index) != 0 or
    691                 self.variable_max(index) != 1))
     751                (self.variable_lower_bound(index) != 0 or
     752                self.variable_upper_bound(index) != 1))
    692753
    693754    cpdef bint is_variable_continuous(self, int index):
    694755        r"""
     
    705766            sage: p.ncols()                                       # optional - Coin
    706767            0
    707768            sage: p.add_variable()                                 # optional - Coin
    708             1
     769            0
    709770            sage: p.is_variable_continuous(0)                      # optional - Coin
    710771            True
    711772            sage: p.set_variable_type(0,1)                         # optional - Coin
     
    733794
    734795        return self.si.getObjSense() == -1
    735796
    736     cpdef variable_max(self, int index, value = False):
     797    cpdef variable_upper_bound(self, int index, value = False):
    737798        r"""
    738799        Returns or defines the upper bound on a variable
    739800
     
    750811            sage: from sage.numerical.backends.generic_backend import get_solver
    751812            sage: p = get_solver(solver = "Coin")  # optional - Coin
    752813            sage: p.add_variable()                                 # optional - Coin
    753             1
     814            0
    754815            sage: p.col_bounds(0)                              # optional - Coin
    755816            (0.0, None)
    756             sage: p.variable_max(0, 5)                         # optional - Coin
     817            sage: p.variable_upper_bound(0, 5)                         # optional - Coin
    757818            sage: p.col_bounds(0)                              # optional - Coin
    758819            (0.0, 5.0)
    759820        """
     
    765826        else:
    766827            self.si.setColUpper(index, value if value is not None else +self.si.getInfinity())
    767828
    768     cpdef variable_min(self, int index, value = False):
     829    cpdef variable_lower_bound(self, int index, value = False):
    769830        r"""
    770831        Returns or defines the lower bound on a variable
    771832
     
    782843            sage: from sage.numerical.backends.generic_backend import get_solver
    783844            sage: p = get_solver(solver = "Coin")  # optional - Coin
    784845            sage: p.add_variable()                                 # optional - Coin
    785             1
     846            0
    786847            sage: p.col_bounds(0)                              # optional - Coin
    787848            (0.0, None)
    788             sage: p.variable_min(0, 5)                         # optional - Coin
     849            sage: p.variable_lower_bound(0, 5)                         # optional - Coin
    789850            sage: p.col_bounds(0)                              # optional - Coin
    790851            (5.0, None)
    791852        """
     
    810871            sage: from sage.numerical.backends.generic_backend import get_solver
    811872            sage: p = get_solver(solver = "Coin")  # optional - Coin
    812873            sage: p.add_variables(2)                               # optional - Coin
    813             2
    814             sage: p.add_linear_constraint([0, 1], [1, 2], +1, 3)          # optional - Coin
     874            1
     875            sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3)          # optional - Coin
    815876            sage: p.set_objective([2, 5])                          # optional - Coin
    816877            sage: p.write_mps(SAGE_TMP+"/lp_problem.mps", 0)       # optional - Coin
    817878        """
     
    856917
    857918            sage: from sage.numerical.backends.generic_backend import get_solver
    858919            sage: p = get_solver(solver = "Coin")  # optional - Coin
    859             sage: p.add_linear_constraints(1, -1, 2)                      # optional - Coin
     920            sage: p.add_linear_constraints(1, 2, None)                      # optional - Coin
    860921            sage: p.row_name(0, "Empty constraint 1")          # optional - Coin
    861922            sage: print p.row_name(0)                          # optional - Coin
    862923            <BLANKLINE>
     
    880941            sage: from sage.numerical.backends.generic_backend import get_solver
    881942            sage: p = get_solver(solver = "Coin")  # optional - Coin
    882943            sage: p.add_variable()                                 # optional - Coin
    883             1
     944            0
    884945            sage: p.col_name(0, "I am a variable")             # optional - Coin
    885946            sage: print p.col_name(0)                          # optional - Coin
    886947            <BLANKLINE>
  • sage/numerical/backends/cplex_backend.pxd

    diff -r cfaca337639b -r 4825b49a4b2a sage/numerical/backends/cplex_backend.pxd
    a b  
    157157     # Get the problem's type
    158158     int CPXgetprobtype(c_cpxlp * env, c_cpxlp * lp)
    159159
     160     # Change a row's range
     161     int CPXchgrngval(c_cpxlp * env, c_cpxlp * lp, int cnt, int * indices, double * values)
     162
     163     # Get a row's range
     164     int CPXgetrngval(c_cpxlp * env, c_cpxlp * lp, double * rngval, int begin, int end)
     165
    160166     # CONSTANTS
    161167     int CPX_ON = 1
    162168     int CPX_PARAM_SCRIND = 1035
  • sage/numerical/backends/cplex_backend.pyx

    diff -r cfaca337639b -r 4825b49a4b2a sage/numerical/backends/cplex_backend.pyx
    a b  
    3434        else:
    3535            self.set_sense(-1)
    3636
    37     cpdef int add_variable(self):
    38         r"""
    39         Adds a variable.
     37    cpdef int add_variable(self, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False) except -1:
     38        """
     39        Add a variable.
    4040
    4141        This amounts to adding a new column to the matrix. By default,
    4242        the variable is both positive and real.
    4343
     44        INPUT:
     45
     46        - ``lower_bound`` - the lower bound of the variable (default: 0)
     47
     48        - ``upper_bound`` - the upper bound of the variable (default: ``None``)
     49
     50        - ``binary`` - ``True`` if the variable is binary (default: ``False``).
     51
     52        - ``continuous`` - ``True`` if the variable is binary (default: ``True``).
     53
     54        - ``integer`` - ``True`` if the variable is binary (default: ``False``).
     55
     56        OUTPUT: The index of the newly created variable           
     57
    4458        EXAMPLE::
    4559
    4660            sage: from sage.numerical.backends.generic_backend import get_solver
    47             sage: p = get_solver(solver = "CPLEX")                    # optional - CPLEX
     61            sage: p = get_solver(solver = "CPLEX")                  # optional - CPLEX
    4862            sage: p.ncols()                                         # optional - CPLEX
    4963            0
    50             sage: p.add_variable()                                   # optional - CPLEX
    51             1
     64            sage: p.add_variable()                                  # optional - CPLEX
     65            0
    5266            sage: p.ncols()                                         # optional - CPLEX
    5367            1
     68            sage: p.add_variable(binary=True)                       # optional - CPLEX
     69            1
     70            sage: p.add_variable(lower_bound=-2.0, integer=True)    # optional - CPLEX
     71            2
     72            sage: p.add_variable(continuous=True, integer=True)     # optional - CPLEX
     73            Traceback (most recent call last):
     74            ...
     75            ValueError: ...           
    5476        """
    5577
     78        cdef int vtype = int(bool(binary)) + int(bool(continuous)) + int(bool(integer))
     79        if  vtype == 0:
     80            continuous = True           
     81        elif vtype != 1:
     82            raise ValueError("Exactly one parameter of 'binary', 'integer' and 'continuous' must be 'True'.")
     83
    5684        cdef int status
    5785        status = CPXnewcols(self.env, self.lp, 1, NULL, NULL, NULL, NULL, NULL)
    5886        check(status)
    59         return CPXgetnumcols(self.env, self.lp)
    6087
    61     cpdef int add_variables(self, int number):
    62         r"""
    63         Adds ``number`` variables.
     88        cdef int n
     89        n = CPXgetnumcols(self.env, self.lp) - 1
     90
     91        if lower_bound != 0.0:
     92            self.variable_lower_bound(n, lower_bound)
     93        if upper_bound is not None:
     94            self.variable_upper_bound(n, upper_bound)
     95
     96        if binary:
     97            self.set_variable_type(n,0)
     98        elif integer:
     99            self.set_variable_type(n,1)
     100
     101        return n
     102
     103    cpdef int add_variables(self, int number, lower_bound=0.0, upper_bound=None, binary=False, continuous=False, integer=False) except -1:
     104        """
     105        Add ``number`` new variables.
    64106
    65107        This amounts to adding new columns to the matrix. By default,
    66108        the variables are both positive and real.
    67109
     110        INPUT:
     111
     112        - ``n`` - the number of new variables (must be > 0)
     113
     114        - ``lower_bound`` - the lower bound of the variable (default: 0)
     115
     116        - ``upper_bound`` - the upper bound of the variable (default: ``None``)
     117
     118        - ``binary`` - ``True`` if the variable is binary (default: ``False``).
     119
     120        - ``continuous`` - ``True`` if the variable is binary (default: ``True``).
     121
     122        - ``integer`` - ``True`` if the variable is binary (default: ``False``).
     123
     124        OUTPUT: The index of the variable created last.
     125
    68126        EXAMPLE::
    69127
    70128            sage: from sage.numerical.backends.generic_backend import get_solver
    71             sage: p = get_solver(solver = "CPLEX")                    # optional - CPLEX
    72             sage: p.ncols()                                         # optional - CPLEX
     129            sage: p = get_solver(solver = "CPLEX")                         # optional - CPLEX
     130            sage: p.ncols()                                                # optional - CPLEX
    73131            0
    74             sage: p.add_variables(5)                                 # optional - CPLEX
     132            sage: p.add_variables(5)                                       # optional - CPLEX
     133            4
     134            sage: p.ncols()                                                # optional - CPLEX
    75135            5
    76             sage: p.ncols()                                         # optional - CPLEX
    77             5
     136            sage: p.add_variables(2, lower_bound=-2.0, integer=True)       # optional - CPLEX
     137            6
    78138        """
     139        cdef int vtype = int(bool(binary)) + int(bool(continuous)) + int(bool(integer))
     140        if  vtype == 0:
     141            continuous = True           
     142        elif vtype != 1:
     143            raise ValueError("Exactly one parameter of 'binary', 'integer' and 'continuous' must be 'True'.")
    79144
    80145        cdef int status
    81146        status = CPXnewcols(self.env, self.lp, number, NULL, NULL, NULL, NULL, NULL)
    82147        check(status)
    83         return CPXgetnumcols(self.env, self.lp)
     148
     149        cdef int n
     150        n = CPXgetnumcols(self.env, self.lp) - 1
     151
     152        cdef int i
     153       
     154        for 0<= i < number:
     155            if lower_bound != 0.0:
     156                self.variable_lower_bound(n - i, lower_bound)
     157            if upper_bound is not None:
     158                self.variable_upper_bound(n - i, upper_bound)
     159
     160            if binary:
     161                self.set_variable_type(n - i,0)
     162            elif integer:
     163                self.set_variable_type(n - i,1)
     164
     165        return n
    84166
    85167    cpdef set_variable_type(self, int variable, int vtype):
    86168        r"""
     
    103185            sage: p.ncols()                                        # optional - CPLEX
    104186            0
    105187            sage: p.add_variable()                                  # optional - CPLEX
    106             1
     188            0
    107189            sage: p.set_variable_type(0,1)                          # optional - CPLEX
    108190            sage: p.is_variable_integer(0)                          # optional - CPLEX
    109191            True
     
    161243            sage: from sage.numerical.backends.generic_backend import get_solver
    162244            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    163245            sage: p.add_variable()                                 # optional - CPLEX
    164             1
     246            0
    165247            sage: p.get_objective_coefficient(0)                         # optional - CPLEX
    166248            0.0
    167249            sage: p.set_objective_coefficient(0,2)                       # optional - CPLEX
     
    223305            sage: from sage.numerical.backends.generic_backend import get_solver
    224306            sage: p = get_solver(solver = "CPLEX")    # optional - CPLEX
    225307            sage: p.add_variables(5)                                 # optional - CPLEX
    226             5
     308            4
    227309            sage: p.set_objective([1, 1, 2, 1, 3])                   # optional - CPLEX
    228310            sage: map(lambda x :p.get_objective_coefficient(x), range(5))  # optional - CPLEX
    229311            [1.0, 1.0, 2.0, 1.0, 3.0]
     
    266348            status = CPXsetintparam (self.env, CPX_PARAM_SCRIND, CPX_ON)
    267349            check(status)
    268350
    269     cpdef add_linear_constraints(self, int number, int direction, double bound):
    270         r"""
    271         Adds constraints.
     351    cpdef add_linear_constraints(self, int number, lower_bound, upper_bound):
     352        """
     353        Add ``'number`` linear constraints.
    272354
    273355        INPUT:
    274356
    275357        - ``number`` (integer) -- the number of constraints to add.
    276358
    277         - ``direction`` (integer) -- the direction of the constraint,
    278           where :
     359        - ``lower_bound`` - a lower bound, either a real value or ``None``
    279360
    280               * +1 indicates : function `\leq` ``bound``
    281               *  0 indicates : function `=` ``bound``
    282               * -1 indicates : function `\geq` ``bound``
    283 
    284         - ``bound`` (double) -- value of the right-hand side (as
    285           illustrated immediately above).
     361        - ``upper_bound`` - an upper bound, either a real value or ``None``
    286362
    287363        EXAMPLE::
    288364
    289365            sage: from sage.numerical.backends.generic_backend import get_solver
    290             sage: p = get_solver(solver = "CPLEX")   # optional - CPLEX
    291             sage: p.add_variables(5)                                # optional - CPLEX
    292             5
    293             sage: p.add_linear_constraints(5, +1, 2)                       # optional - CPLEX
    294             sage: p.row(4)                                      # optional - CPLEX
     366            sage: p = get_solver(solver = "CPLEX")       # optional - CPLEX
     367            sage: p.add_variables(5)                     # optional - CPLEX
     368            4
     369            sage: p.add_linear_constraints(5, None, 2)   # optional - CPLEX
     370            sage: p.row(4)                               # optional - CPLEX
    295371            ([], [])
    296             sage: p.row_bounds(4)                               # optional - CPLEX
     372            sage: p.row_bounds(4)                        # optional - CPLEX
    297373            (None, 2.0)
    298374        """
     375        if lower_bound is None and upper_bound is None:
     376            raise ValueError("At least one of 'upper_bound' or 'lower_bound' must be set.")
    299377
    300         cdef char * c_types = <char *> sage_malloc(number * sizeof(char))
    301         cdef double * c_bounds = <double *> sage_malloc(number * sizeof(double))
     378        cdef int status
     379        cdef char * sense = <char *> sage_malloc(number * sizeof(char))
     380        cdef double * bound = <double *> sage_malloc(number * sizeof(double))
     381        cdef double * rng = NULL
    302382        cdef int i
    303         cdef int status
    304383
    305         c_bounds[0] = bound
    306        
    307         if direction == +1:
    308             c_types[0] = 'L'
    309         elif direction == -1:
    310             c_types[0] = 'G'
    311         else:
    312             c_types[0] = 'E'
     384        if upper_bound == lower_bound:
     385            sense[0] = 'E'
     386            bound[0] = lower_bound
    313387
    314         for 1<= i < number:
    315             c_types[i] = c_types[0]
    316             c_bounds[i] = c_bounds[0]
    317        
     388        elif upper_bound is not None and lower_bound is not None:
     389            if  upper_bound < lower_bound:
     390                raise ValueError("The upper bound must be at least equal to the lower bound !")
     391           
     392            rng = <double *> sage_malloc(number * sizeof(double))
    318393
    319         status = CPXnewrows(self.env, self.lp, number, c_bounds, c_types, NULL, NULL)
    320         check(status)
     394            sense[0] = 'R'
     395            bound[0] = lower_bound
     396            rng[0] = upper_bound - lower_bound
    321397
    322     cpdef add_linear_constraint(self, list indices, list coeffs, int direction, double bound):
    323         r"""
    324         Adds a linear constraint.
     398
     399        elif upper_bound is not None:
     400            sense[0] = 'L'
     401            bound[0] = upper_bound
     402
     403        elif lower_bound is not None:
     404            sense[0] = 'G'
     405            bound[0] = lower_bound
     406           
     407        for 1<= i <number:
     408            sense[i] = sense[0]
     409            bound[i] = bound[0]
     410            if rng != NULL:
     411                rng[i] = rng[0]
     412
     413        status = CPXnewrows(self.env, self.lp, number, bound, sense, rng, NULL)
     414        check(status)       
     415
     416    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound):
     417        """
     418        Add a linear constraint.
    325419
    326420        INPUT:
    327421
    328         - ``indices`` (list of integers) -- this list constains the
    329           indices of the variables whose coefficient is nonzero in the
    330           constraint.
     422        - ``coefficients`` an iterable with ``(c,v)`` pairs where ``c``
     423          is a variable index (integer) and ``v`` is a value (real
     424          value).
    331425
    332         - ``coeffs`` (list of real values) -- associates a coefficient
    333           to the variables listed by ``indices``. Namely, the ith
    334           entry of ``coeffs`` corresponds to the coefficient of the
    335           variable represented by the ith entry in ``indices``.
     426        - ``lower_bound`` - a lower bound, either a real value or ``None``
    336427
    337         - ``direction`` (integer) -- the direction of the constraint,
    338           where :
    339 
    340               * +1 indicates : function `\leq` ``bound``
    341               *  0 indicates : function `=` ``bound``
    342               * -1 indicates : function `\geq` ``bound``
    343 
    344         - ``bound`` (double) -- value of the right-hand side (as
    345           illustrated immediately above).
    346 
    347         .. NOTE::
    348 
    349             ``indices`` and ``coeffs`` are expected to be of the same
    350             length.
    351 
     428        - ``upper_bound`` - an upper bound, either a real value or ``None``
     429 
    352430        EXAMPLE::
    353431
    354432            sage: from sage.numerical.backends.generic_backend import get_solver
    355             sage: p = get_solver(solver = "CPLEX") # optional - CPLEX
    356             sage: p.add_variables(5)                              # optional - CPLEX
    357             5
    358             sage: p.add_linear_constraint(range(5), range(5), 0, 2)      # optional - CPLEX
    359             sage: p.row(0)                                    # optional - CPLEX
     433            sage: p = get_solver(solver = "CPLEX")                             # optional - CPLEX
     434            sage: p.add_variables(5)                                           # optional - CPLEX
     435            4
     436            sage: p.add_linear_constraint( zip(range(5), range(5)), 2.0, 2.0)  # optional - CPLEX
     437            sage: p.row(0)                                                     # optional - CPLEX
    360438            ([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])
    361             sage: p.row_bounds(0)                             # optional - CPLEX
     439            sage: p.row_bounds(0)                                              # optional - CPLEX
    362440            (2.0, 2.0)
    363441        """
     442        if lower_bound is None and upper_bound is None:
     443            raise ValueError("At least one of 'upper_bound' or 'lower_bound' must be set.")
    364444
    365445        cdef int status
    366         cdef int i
    367         cdef int n = len(indices)
     446        cdef int i, j
     447        cdef int n = len(coefficients)
    368448        cdef int nrows = self.nrows()
    369449        cdef char sense
    370450
    371         if direction == 1:
    372             sense = 'L'
    373         elif direction == -1:
    374             sense = 'G'
    375         else:
    376             sense = 'E'
    377        
    378         status = CPXnewrows(self.env, self.lp, 1, &bound, &sense, NULL, NULL)
    379         check(status)
     451        cdef double * c_coeff
     452        cdef int * c_indices
     453        cdef int * c_row
     454        cdef double bound
     455        cdef double rng
     456        cdef double c
    380457
    381         cdef double * c_coeff = <double *> sage_malloc(n * sizeof(double))
    382         cdef int * c_indices = <int *> sage_malloc(n * sizeof(int))
    383         cdef int * c_row = <int *> sage_malloc(n * sizeof(int))
    384        
    385         for 0<= i < n:
    386             c_coeff[i] = coeffs[i]
    387             c_indices[i] = indices[i]
     458        c_coeff = <double *> sage_malloc(n * sizeof(double))
     459        c_indices = <int *> sage_malloc(n * sizeof(int))
     460        c_row = <int *> sage_malloc(n * sizeof(int))
     461
     462        for i, (j, c) in enumerate(coefficients):
     463            c_coeff[i] = c
     464            c_indices[i] = j
    388465            c_row[i] = nrows
    389466
     467        if upper_bound is None and lower_bound is None:
     468            pass
    390469
     470        elif upper_bound == lower_bound:
     471            sense = 'E'
     472            bound = lower_bound
     473
     474        elif upper_bound is not None and lower_bound is not None:
     475            if  upper_bound < lower_bound:
     476                raise ValueError("The upper bound must be at least equal to the lower bound !")
     477
     478            sense = 'R'
     479            bound = lower_bound
     480
     481        elif upper_bound is not None:
     482            sense = 'L'
     483            bound = upper_bound
     484
     485        elif lower_bound is not None:
     486            sense = 'G'
     487            bound = lower_bound
     488
     489        status = CPXnewrows(self.env, self.lp, 1, &bound, &sense, &rng, NULL)
     490        check(status)
    391491        status = CPXchgcoeflist(self.env, self.lp, n, c_row, c_indices, c_coeff)
    392492        check(status)
    393493
     
    411511            sage: from sage.numerical.backends.generic_backend import get_solver
    412512            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    413513            sage: p.add_variables(5)                               # optional - CPLEX
    414             5
    415             sage: p.add_linear_constraint(range(5), range(5), 0, 2)       # optional - CPLEX
     514            4
     515            sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)       # optional - CPLEX
    416516            sage: p.row(0)                                     # optional - CPLEX
    417517            ([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])
    418518            sage: p.row_bounds(0)                              # optional - CPLEX
     
    460560            sage: from sage.numerical.backends.generic_backend import get_solver
    461561            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    462562            sage: p.add_variables(5)                               # optional - CPLEX
    463             5
    464             sage: p.add_linear_constraint(range(5), range(5), 0, 2)       # optional - CPLEX
     563            4
     564            sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2)       # optional - CPLEX
    465565            sage: p.row(0)                                     # optional - CPLEX
    466566            ([1, 2, 3, 4], [1.0, 2.0, 3.0, 4.0])
    467567            sage: p.row_bounds(0)                              # optional - CPLEX
     
    469569        """
    470570
    471571        cdef int status
     572        cdef double rng
    472573        cdef double value
    473574        status = CPXgetrhs(self.env, self.lp, &value, index, index)
    474575        check(status)
     
    481582            return (None, value)
    482583        elif direction == 'G':
    483584            return (value, None)
    484         else:
     585        elif direction == 'E':
    485586            return (value, value)
     587        elif direction == 'R':
     588            status = CPXgetrngval(self.env, self.lp, &rng, index, index)
     589            check(status)
     590            return (value, value + rng)
    486591
    487592    cpdef col_bounds(self, int index):
    488593        r"""
     
    503608            sage: from sage.numerical.backends.generic_backend import get_solver
    504609            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    505610            sage: p.add_variable()                                 # optional - CPLEX
    506             1
     611            0
    507612            sage: p.col_bounds(0)                              # optional - CPLEX
    508613            (0.0, None)
    509             sage: p.variable_max(0, 5)                         # optional - CPLEX
     614            sage: p.variable_upper_bound(0, 5)                         # optional - CPLEX
    510615            sage: p.col_bounds(0)                              # optional - CPLEX
    511616            (0.0, 5.0)
    512617        """
     
    539644            sage: from sage.numerical.backends.generic_backend import get_solver
    540645            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    541646            sage: p.add_variable()                                 # optional - CPLEX
    542             1
     647            0
    543648            sage: p.get_objective_coefficient(0)                         # optional - CPLEX
    544649            0.0
    545650            sage: p.set_objective_coefficient(0,2)                       # optional - CPLEX
     
    583688            0
    584689            sage: p.nrows()                                       # optional - CPLEX
    585690            0
    586             sage: p.add_linear_constraints(5, -1, 0)                      # optional - CPLEX
     691            sage: p.add_linear_constraints(5, 0, None)                      # optional - CPLEX
    587692            sage: p.add_col(range(5), range(5))                    # optional - CPLEX
    588693            sage: p.nrows()                                       # optional - CPLEX
    589694            5
     
    626731
    627732            sage: from sage.numerical.backends.generic_backend import get_solver
    628733            sage: p = get_solver(solver = "CPLEX") # optional - CPLEX
    629             sage: p.add_linear_constraints(5, -1, 0)                     # optional - CPLEX
     734            sage: p.add_linear_constraints(5, 0, None)                     # optional - CPLEX
    630735            sage: p.add_col(range(5), range(5))                   # optional - CPLEX
    631736            sage: p.solve()                                       # optional - CPLEX
    632737            0
     
    677782            sage: from sage.numerical.backends.generic_backend import get_solver
    678783            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    679784            sage: p.add_variables(2)                               # optional - CPLEX
    680             2
    681             sage: p.add_linear_constraint([0, 1], [1, 2], +1, 3)          # optional - CPLEX
     785            1
     786            sage: p.add_linear_constraint([(0,1), (1,2)], None, 3)          # optional - CPLEX
    682787            sage: p.set_objective([2, 5])                          # optional - CPLEX
    683788            sage: p.solve()                                        # optional - CPLEX
    684789            0
     
    711816            sage: from sage.numerical.backends.generic_backend import get_solver
    712817            sage: p = get_solver(solver = "CPLEX") # optional - CPLEX
    713818            sage: p.add_variables(2)                              # optional - CPLEX
    714             2
    715             sage: p.add_linear_constraint([0, 1], [1, 2], +1, 3)         # optional - CPLEX
     819            1
     820            sage: p.add_linear_constraint([(0,1), (1,2)], None, 3)         # optional - CPLEX
    716821            sage: p.set_objective([2, 5])                         # optional - CPLEX
    717822            sage: p.solve()                                       # optional - CPLEX
    718823            0
     
    744849            sage: p.ncols()                                       # optional - CPLEX
    745850            0
    746851            sage: p.add_variables(2)                               # optional - CPLEX
    747             2
     852            1
    748853            sage: p.ncols()                                       # optional - CPLEX
    749854            2
    750855        """
     
    761866            sage: p = get_solver(solver = "CPLEX") # optional - CPLEX
    762867            sage: p.nrows()                                      # optional - CPLEX
    763868            0
    764             sage: p.add_linear_constraints(2, -1, 2)                     # optional - CPLEX
     869            sage: p.add_linear_constraints(2, 2, None)                     # optional - CPLEX
    765870            sage: p.nrows()                                      # optional - CPLEX
    766871            2
    767872        """
     
    783888
    784889            sage: from sage.numerical.backends.generic_backend import get_solver
    785890            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    786             sage: p.add_linear_constraints(1, -1, 2)                      # optional - CPLEX
     891            sage: p.add_linear_constraints(1, 2, None)                      # optional - CPLEX
    787892            sage: p.row_name(0, "Empty constraint 1")          # optional - CPLEX
    788893            sage: p.row_name(0)                                # optional - CPLEX
    789894            'Empty constraint 1'
     
    828933            sage: from sage.numerical.backends.generic_backend import get_solver
    829934            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    830935            sage: p.add_variable()                                 # optional - CPLEX
    831             1
     936            0
    832937            sage: p.col_name(0, "I am a variable")             # optional - CPLEX
    833938            sage: p.col_name(0)                                # optional - CPLEX
    834939            'I am a variable'
     
    872977            sage: p.ncols()                                       # optional - CPLEX
    873978            0
    874979            sage: p.add_variable()                                 # optional - CPLEX
    875             1
     980            0
    876981            sage: p.set_variable_type(0,0)                         # optional - CPLEX
    877982            sage: p.is_variable_binary(0)                          # optional - CPLEX
    878983            True
     
    9081013            sage: p.ncols()                                       # optional - CPLEX
    9091014            0
    9101015            sage: p.add_variable()                                 # optional - CPLEX
    911             1
     1016            0
    9121017            sage: p.set_variable_type(0,1)                         # optional - CPLEX
    9131018            sage: p.is_variable_integer(0)                         # optional - CPLEX
    9141019            True
     
    9431048            sage: p.ncols()                                       # optional - CPLEX
    9441049            0
    9451050            sage: p.add_variable()                                 # optional - CPLEX
    946             1
     1051            0
    9471052            sage: p.is_variable_continuous(0)                      # optional - CPLEX
    9481053            True
    9491054            sage: p.set_variable_type(0,1)                         # optional - CPLEX
     
    9831088
    9841089        return -1 == CPXgetobjsen(self.env, self.lp)
    9851090
    986     cpdef variable_max(self, int index, value = False):
     1091    cpdef variable_upper_bound(self, int index, value = False):
    9871092        r"""
    9881093        Returns or defines the upper bound on a variable
    9891094
     
    10001105            sage: from sage.numerical.backends.generic_backend import get_solver
    10011106            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    10021107            sage: p.add_variable()                                 # optional - CPLEX
    1003             1
     1108            0
    10041109            sage: p.col_bounds(0)                              # optional - CPLEX
    10051110            (0.0, None)
    1006             sage: p.variable_max(0, 5)                         # optional - CPLEX
     1111            sage: p.variable_upper_bound(0, 5)                         # optional - CPLEX
    10071112            sage: p.col_bounds(0)                              # optional - CPLEX
    10081113            (0.0, 5.0)
    10091114        """
     
    10261131            status = CPXchgbds(self.env, self.lp, 1, &index, &x, &c_value)
    10271132            check(status)
    10281133
    1029     cpdef variable_min(self, int index, value = False):
     1134    cpdef variable_lower_bound(self, int index, value = False):
    10301135        r"""
    10311136        Returns or defines the lower bound on a variable
    10321137
     
    10431148            sage: from sage.numerical.backends.generic_backend import get_solver
    10441149            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    10451150            sage: p.add_variable()                                 # optional - CPLEX
    1046             1
     1151            0
    10471152            sage: p.col_bounds(0)                              # optional - CPLEX
    10481153            (0.0, None)
    1049             sage: p.variable_min(0, 5)                         # optional - CPLEX
     1154            sage: p.variable_lower_bound(0, 5)                         # optional - CPLEX
    10501155            sage: p.col_bounds(0)                              # optional - CPLEX
    10511156            (5.0, None)
    10521157        """
     
    10791184            sage: from sage.numerical.backends.generic_backend import get_solver
    10801185            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    10811186            sage: p.add_variables(2)                               # optional - CPLEX
    1082             2
    1083             sage: p.add_linear_constraint([0, 1], [1, 2], +1, 3)          # optional - CPLEX
     1187            1
     1188            sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3)          # optional - CPLEX
    10841189            sage: p.set_objective([2, 5])                          # optional - CPLEX
    10851190            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")            # optional - CPLEX
    10861191        """
     
    11031208            sage: from sage.numerical.backends.generic_backend import get_solver
    11041209            sage: p = get_solver(solver = "CPLEX")  # optional - CPLEX
    11051210            sage: p.add_variables(2)                               # optional - CPLEX
    1106             2
    1107             sage: p.add_linear_constraint([0, 1], [1, 2], +1, 3)          # optional - CPLEX
     1211            1
     1212            sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3)          # optional - CPLEX
    11081213            sage: p.set_objective([2, 5])                          # optional - CPLEX
    11091214            sage: p.write_lp(SAGE_TMP+"/lp_problem.lp")            # optional - CPLEX
    11101215        """
  • sage/numerical/backends/generic_backend.pxd

    diff -r cfaca337639b -r 4825b49a4b2a sage/numerical/backends/generic_backend.pxd
    a b  
    1919    cpdef int solve(self) except -1
    2020    cpdef double get_objective_value(self)
    2121    cpdef double get_variable_value(self, int variable)
    22     cpdef name(self)
    2322    cpdef bint is_maximization(self)
    2423    cpdef write_lp(self, char * name)
    2524    cpdef write_mps(self, char * name, int modern)
  • sage/numerical/backends/generic_backend.pyx

    diff -r cfaca337639b -r 4825b49a4b2a sage/numerical/backends/generic_backend.pyx
    a b  
    218218        """
    219219        raise NotImplementedError()
    220220
    221     cpdef add_linear_constraint(self, constraints, lower_bound, upper_bound):
     221    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound):
    222222        """
    223223        Add a linear constraint.
    224224
    225225        INPUT:
    226226
    227         - ``contraints`` an iterable with ``(c,v)`` pairs where ``c``
     227        - ``coefficients`` an iterable with ``(c,v)`` pairs where ``c``
    228228          is a variable index (integer) and ``v`` is a value (real
    229229          value).
    230230
  • sage/numerical/backends/glpk_backend.pyx

    diff -r cfaca337639b -r 4825b49a4b2a sage/numerical/backends/glpk_backend.pyx
    a b  
    319319        else:
    320320            self.iocp.msg_lev = GLP_MSG_ALL
    321321
    322     cpdef add_linear_constraint(self, constraints, lower_bound, upper_bound):
     322    cpdef add_linear_constraint(self, coefficients, lower_bound, upper_bound):
    323323        """
    324324        Add a linear constraint.
    325325
    326326        INPUT:
    327327
    328         - ``contraints`` an iterable with ``(c,v)`` pairs where ``c``
     328        - ``coefficients`` an iterable with ``(c,v)`` pairs where ``c``
    329329          is a variable index (integer) and ``v`` is a value (real
    330330          value).
    331331
     
    354354        cdef int * row_i
    355355        cdef double * row_values
    356356
    357         row_i = <int *> sage_malloc((len(constraints)+1) * sizeof(int))
    358         row_values = <double *> sage_malloc((len(constraints)+1) * sizeof(double))
     357        row_i = <int *> sage_malloc((len(coefficients)+1) * sizeof(int))
     358        row_values = <double *> sage_malloc((len(coefficients)+1) * sizeof(double))
    359359
    360         for i,(c,v) in enumerate(constraints):
     360        for i,(c,v) in enumerate(coefficients):
    361361            row_i[i+1] = c+1
    362362            row_values[i+1] = v
    363363       
    364         glp_set_mat_row(self.lp, n, len(constraints), row_i, row_values)
     364        glp_set_mat_row(self.lp, n, len(coefficients), row_i, row_values)
    365365
    366366        if upper_bound is not None and lower_bound is None:
    367367            glp_set_row_bnds(self.lp, n, GLP_UP, upper_bound, upper_bound)
  • sage/numerical/mip.pyx

    diff -r cfaca337639b -r 4825b49a4b2a sage/numerical/mip.pyx
    a b  
    723723
    724724        TESTS::
    725725
     726        Complex constraints::
     727
     728            sage: p = MixedIntegerLinearProgram()
     729            sage: b = p.new_variable()
     730            sage: p.add_constraint( b[8] - b[15] <= 3*b[8] + 9)
     731            sage: p.show()
     732           
     733        Empty constraint::
     734
    726735            sage: p=MixedIntegerLinearProgram()
    727736            sage: p.add_constraint(sum([]),min=2)
    728737
     
    773782                self._backend.row_name(self._backend.nrows()-1,name)
    774783
    775784        elif isinstance(linear_function,LinearConstraint):
    776             #######
    777             ####### IS THIS DEAD CODE???
    778             #######
    779785            functions = linear_function.constraints
    780786           
    781787            if linear_function.equality: