--- src/sage/libs/ppl.pyx.orig 2014-12-06 17:14:55.273653335 -0200 +++ src/sage/libs/ppl.pyx 2014-12-01 12:54:53.538369211 -0200 @@ -150,7 +150,7 @@ from sage.structure.sage_object cimport SageObject from sage.libs.gmp.mpz cimport mpz_t, mpz_set from sage.rings.integer cimport Integer -from sage.rings.rational import Rational +from sage.rings.rational cimport Rational include 'sage/ext/interrupt.pxi' include "sage/ext/stdsage.pxi" @@ -171,7 +171,7 @@ mpz_class(int i) mpz_class(mpz_t z) mpz_class(mpz_class) - mpz_t* get_mpz_t() + mpz_t get_mpz_t() #################################################### @@ -187,11 +187,11 @@ #################################################### # Cython does not support ctypedef within cppclass; Hack around this restriction: cdef extern from "ppl.hh" namespace "Parma_Polyhedra_Library::Generator": - ctypedef enum PPL_GeneratorType: + ctypedef enum PPL_GeneratorType "Parma_Polyhedra_Library::Generator::Type": LINE, RAY, POINT, CLOSURE_POINT cdef extern from "ppl.hh" namespace "Parma_Polyhedra_Library::Constraint": - ctypedef enum PPL_ConstraintType: + ctypedef enum PPL_ConstraintType "Parma_Polyhedra_Library::Constraint::Type": EQUALITY, NONSTRICT_INEQUALITY, STRICT_INEQUALITY cdef extern from "ppl.hh" namespace "Parma_Polyhedra_Library::MIP_Problem": @@ -328,7 +328,7 @@ cdef enum PPL_Optimization_Mode: MINIMIZATION, MAXIMIZATION - cdef enum PPL_MIP_Problem_Status: + cdef enum MIP_Problem_Status: UNFEASIBLE_MIP_PROBLEM, UNBOUNDED_MIP_PROBLEM, OPTIMIZED_MIP_PROBLEM cdef cppclass PPL_Polyhedron: @@ -426,7 +426,7 @@ void set_optimization_mode(PPL_Optimization_Mode mode) PPL_Optimization_Mode optimization_mode() bint is_satisfiable() - PPL_MIP_Problem_Status solve() + MIP_Problem_Status solve() void evaluate_objective_function(PPL_Generator evaluating_point, PPL_Coefficient &num, PPL_Coefficient &den) except +ValueError PPL_Generator& feasible_point() PPL_Generator optimizing_point() except +ValueError @@ -861,6 +861,51 @@ self.thisptr.add_space_dimensions_and_embed(m) sig_off() + def _add_rational_constraint(self, e, denom, lower, upper): + """ + Helper function for adding constraints: add the constraint + ``lower <= e/denom <= upper``. + + INPUT: + + - ``e`` -- a linear expression (type ``Linear_Expression``) + + - ``denom`` -- a positive integer + + - ``lower``, ``upper`` -- a rational number or ``None``, where + ``None`` means that there is no constraint + + TESTS: + + Create a linear system with only equalities as constraints:: + + sage: p = MixedIntegerLinearProgram(solver="PPL") + sage: x = p.new_variable(nonnegative=False) + sage: n = 40 + sage: v = random_vector(QQ, n) + sage: M = random_matrix(QQ, 2*n, n) + sage: for j in range(2*n): # indirect doctest + ....: lhs = p.sum(M[j,i]*x[i] for i in range(n)) + ....: rhs = M.row(j).inner_product(v) + ....: p.add_constraint(lhs == rhs) + sage: p.solve() # long time + 0 + + """ + cdef Rational rhs + + if lower == upper: + if lower is not None: + rhs = Rational(lower * denom) + self.add_constraint(e * rhs.denominator() == rhs.numerator()) + else: + if lower is not None: + rhs = Rational(lower * denom) + self.add_constraint(e * rhs.denominator() >= rhs.numerator()) + if upper is not None: + rhs = Rational(upper * denom) + self.add_constraint(e * rhs.denominator() <= rhs.numerator()) + def add_constraint(self, Constraint c): """ Adds a copy of constraint c to the MIP problem. @@ -1894,7 +1939,11 @@ sage: cs.insert( 3*x+5*y<=10 ) sage: p = C_Polyhedron(cs) sage: p.maximize( x+y ) - {'sup_d': 3, 'sup_n': 10, 'bounded': True, 'maximum': True, 'generator': point(10/3, 0/3)} + {'bounded': True, + 'generator': point(10/3, 0/3), + 'maximum': True, + 'sup_d': 3, + 'sup_n': 10} Unbounded case:: @@ -1904,7 +1953,11 @@ sage: p.maximize( +x ) {'bounded': False} sage: p.maximize( -x ) - {'sup_d': 1, 'sup_n': 0, 'bounded': True, 'maximum': False, 'generator': closure_point(0/1)} + {'bounded': True, + 'generator': closure_point(0/1), + 'maximum': False, + 'sup_d': 1, + 'sup_n': 0} """ cdef PPL_Coefficient sup_n cdef PPL_Coefficient sup_d @@ -1965,7 +2018,11 @@ sage: cs.insert( 3*x+5*y<=10 ) sage: p = C_Polyhedron(cs) sage: p.minimize( x+y ) - {'minimum': True, 'bounded': True, 'inf_d': 1, 'generator': point(0/1, 0/1), 'inf_n': 0} + {'bounded': True, + 'generator': point(0/1, 0/1), + 'inf_d': 1, + 'inf_n': 0, + 'minimum': True} Unbounded case:: @@ -1973,7 +2030,11 @@ sage: cs.insert( x>0 ) sage: p = NNC_Polyhedron(cs) sage: p.minimize( +x ) - {'minimum': False, 'bounded': True, 'inf_d': 1, 'generator': closure_point(0/1), 'inf_n': 0} + {'bounded': True, + 'generator': closure_point(0/1), + 'inf_d': 1, + 'inf_n': 0, + 'minimum': False} sage: p.minimize( -x ) {'bounded': False} """ @@ -2863,7 +2924,7 @@ sage: sage_cmd += 'p.minimized_generators()\n' sage: sage_cmd += 'p.ascii_dump()\n' sage: from sage.tests.cmdline import test_executable - sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100); # long time, indirect doctest + sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100) # long time, indirect doctest sage: print err # long time space_dim 2 -ZE -EM +CM +GM +CS +GS -CP -GP -SC +SG @@ -3919,7 +3980,7 @@ sage: sage_cmd += 'e = 3*x+2*y+1\n' sage: sage_cmd += 'e.ascii_dump()\n' sage: from sage.tests.cmdline import test_executable - sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100); # long time, indirect doctest + sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100) # long time, indirect doctest sage: print err # long time size 3 1 3 2 """ @@ -4813,7 +4874,7 @@ sage: sage_cmd += 'p = point(3*x+2*y)\n' sage: sage_cmd += 'p.ascii_dump()\n' sage: from sage.tests.cmdline import test_executable - sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100); # long time, indirect doctest + sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100) # long time, indirect doctest sage: print err # long time size 3 1 3 2 P (C) """ @@ -5114,7 +5175,7 @@ sage: sage_cmd += 'gs = Generator_System( point(3*x+2*y+1) )\n' sage: sage_cmd += 'gs.ascii_dump()\n' sage: from sage.tests.cmdline import test_executable - sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100); # long time, indirect doctest + sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100) # long time, indirect doctest sage: print err # long time topology NECESSARILY_CLOSED 1 x 2 SPARSE (sorted) @@ -5802,7 +5863,7 @@ sage: sage_cmd += 'e = (3*x+2*y+1 > 0)\n' sage: sage_cmd += 'e.ascii_dump()\n' sage: from sage.tests.cmdline import test_executable - sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100); # long time, indirect doctest + sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100) # long time, indirect doctest sage: print err # long time size 4 1 3 2 -1 > (NNC) """ @@ -6148,7 +6209,7 @@ sage: sage_cmd += 'cs = Constraint_System( 3*x > 2*y+1 )\n' sage: sage_cmd += 'cs.ascii_dump()\n' sage: from sage.tests.cmdline import test_executable - sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100); # long time, indirect doctest + sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100) # long time, indirect doctest sage: print err # long time topology NOT_NECESSARILY_CLOSED 1 x 2 SPARSE (sorted) @@ -6499,7 +6560,7 @@ sage: sage_cmd = 'from sage.libs.ppl import Poly_Gen_Relation\n' sage: sage_cmd += 'Poly_Gen_Relation.nothing().ascii_dump()\n' sage: from sage.tests.cmdline import test_executable - sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100); # long time, indirect doctest + sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100) # long time, indirect doctest sage: print err # long time NOTHING """ @@ -6749,7 +6810,7 @@ sage: sage_cmd = 'from sage.libs.ppl import Poly_Con_Relation\n' sage: sage_cmd += 'Poly_Con_Relation.nothing().ascii_dump()\n' sage: from sage.tests.cmdline import test_executable - sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100); # long time, indirect doctest + sage: (out, err, ret) = test_executable(['sage', '-c', sage_cmd], timeout=100) # long time, indirect doctest sage: print err # long time NOTHING """