diff --git a/src/sage/numerical/all.py b/src/sage/numerical/all.py index 06ca1dd1a60..8b69da18652 100644 --- a/src/sage/numerical/all.py +++ b/src/sage/numerical/all.py @@ -1,7 +1,7 @@ from sage.misc.lazy_import import lazy_import lazy_import("sage.numerical.optimize", ["find_fit", "find_local_maximum", "find_local_minimum", - "find_root", "linear_program", "minimize", "minimize_constrained"]) + "find_root", "minimize", "minimize_constrained"]) lazy_import("sage.numerical.mip", ["MixedIntegerLinearProgram"]) lazy_import("sage.numerical.sdp", ["SemidefiniteProgram"]) lazy_import("sage.numerical.backends.generic_backend", ["default_mip_solver"]) diff --git a/src/sage/numerical/backends/cvxopt_backend.pyx b/src/sage/numerical/backends/cvxopt_backend.pyx index 4100fb71b76..fe4809d1232 100644 --- a/src/sage/numerical/backends/cvxopt_backend.pyx +++ b/src/sage/numerical/backends/cvxopt_backend.pyx @@ -1,10 +1,11 @@ +# sage.doctest: needs cvxopt r""" CVXOPT Backend AUTHORS: -- Ingolfur Edvardsson (2014-05) : initial implementation +- Ingolfur Edvardsson (2014-05): initial implementation """ #***************************************************************************** @@ -30,13 +31,13 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="CVXOPT") # optional - cvxopt + sage: p = MixedIntegerLinearProgram(solver="CVXOPT") TESTS: :trac:`20332`:: - sage: p # optional - cvxopt + sage: p Mixed Integer Program (no objective, 0 variables, 0 constraints) """ @@ -62,7 +63,7 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") """ @@ -101,15 +102,15 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = MixedIntegerLinearProgram(solver = "CVXOPT") # optional - cvxopt - sage: b = p.new_variable() # optional - cvxopt - sage: p.add_constraint(b[1] + b[2] <= 6) # optional - cvxopt - sage: p.add_constraint(b[2] <= 5) # optional - cvxopt - sage: p.set_objective(b[1] + b[2]) # optional - cvxopt - sage: cp = copy(p.get_backend()) # optional - cvxopt - sage: cp.solve() # optional - cvxopt + sage: p = MixedIntegerLinearProgram(solver="CVXOPT") + sage: b = p.new_variable() + sage: p.add_constraint(b[1] + b[2] <= 6) + sage: p.add_constraint(b[2] <= 5) + sage: p.set_objective(b[1] + b[2]) + sage: cp = copy(p.get_backend()) + sage: cp.solve() 0 - sage: cp.get_objective_value() # optional - cvxopt + sage: cp.get_objective_value() 6.0 """ cdef CVXOPTBackend cp = type(self)() @@ -160,35 +161,35 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.ncols() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.ncols() 0 - sage: p.add_variable() # optional - cvxopt + sage: p.add_variable() 0 - sage: p.ncols() # optional - cvxopt + sage: p.ncols() 1 - sage: p.add_variable() # optional - cvxopt + sage: p.add_variable() 1 - sage: p.add_variable(lower_bound=-2.0) # optional - cvxopt + sage: p.add_variable(lower_bound=-2.0) 2 - sage: p.add_variable(continuous=True) # optional - cvxopt + sage: p.add_variable(continuous=True) 3 - sage: p.add_variable(name='x',obj=1.0) # optional - cvxopt + sage: p.add_variable(name='x',obj=1.0) 4 - sage: p.col_name(3) # optional - cvxopt + sage: p.col_name(3) 'x_3' - sage: p.col_name(4) # optional - cvxopt + sage: p.col_name(4) 'x' - sage: p.objective_coefficient(4) # optional - cvxopt + sage: p.objective_coefficient(4) 1.00000000000000 TESTS:: - sage: p.add_variable(integer=True) # optional - cvxopt + sage: p.add_variable(integer=True) Traceback (most recent call last): ... RuntimeError: CVXOPT only supports continuous variables - sage: p.add_variable(binary=True) # optional - cvxopt + sage: p.add_variable(binary=True) Traceback (most recent call last): ... RuntimeError: CVXOPT only supports continuous variables @@ -211,11 +212,11 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "cvxopt") # optional - cvxopt - sage: p.add_variables(5) # optional - cvxopt + sage: p = get_solver(solver="cvxopt") + sage: p.add_variables(5) 4 - sage: p.set_variable_type(3, -1) # optional - cvxopt - sage: p.set_variable_type(3, -2) # optional - cvxopt + sage: p.set_variable_type(3, -1) + sage: p.set_variable_type(3, -2) Traceback (most recent call last): ... ValueError: ... @@ -229,19 +230,19 @@ cdef class CVXOPTBackend(GenericBackend): INPUT: - - ``sense`` (integer) : + - ``sense`` (integer): - * +1 => Maximization - * -1 => Minimization + * `+1` => Maximization + * `-1` => Minimization EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.is_maximization() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.is_maximization() True - sage: p.set_sense(-1) # optional - cvxopt - sage: p.is_maximization() # optional - cvxopt + sage: p.set_sense(-1) + sage: p.is_maximization() False """ if sense == 1: @@ -263,13 +264,13 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variable() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variable() 0 - sage: p.objective_coefficient(0) # optional - cvxopt + sage: p.objective_coefficient(0) 0.0 - sage: p.objective_coefficient(0,2) # optional - cvxopt - sage: p.objective_coefficient(0) # optional - cvxopt + sage: p.objective_coefficient(0,2) + sage: p.objective_coefficient(0) 2.0 """ if coeff is not None: @@ -290,12 +291,12 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: - sage: from sage.numerical.backends.generic_backend import get_solver # optional - cvxopt - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variables(5) # optional - cvxopt + sage: from sage.numerical.backends.generic_backend import get_solver + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variables(5) 4 - sage: p.set_objective([1, 1, 2, 1, 3]) # optional - cvxopt - sage: [p.objective_coefficient(x) for x in range(5)] # optional - cvxopt + sage: p.set_objective([1, 1, 2, 1, 3]) + sage: [p.objective_coefficient(x) for x in range(5)] [1, 1, 2, 1, 3] """ for i in range(len(coeff)): @@ -332,14 +333,14 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.ncols() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.ncols() 0 - sage: p.nrows() # optional - cvxopt + sage: p.nrows() 0 - sage: p.add_linear_constraints(5, 0, None) # optional - cvxopt - sage: p.add_col(range(5), range(5)) # optional - cvxopt - sage: p.nrows() # optional - cvxopt + sage: p.add_linear_constraints(5, 0, None) + sage: p.add_col(range(5), range(5)) + sage: p.nrows() 5 """ column = [] @@ -375,16 +376,16 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variables(5) # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variables(5) 4 - sage: p.add_linear_constraint(zip(range(5), range(5)), 2.0, 2.0) # optional - cvxopt - sage: p.row(0) # optional - cvxopt + sage: p.add_linear_constraint(zip(range(5), range(5)), 2.0, 2.0) + sage: p.row(0) ([1, 2, 3, 4], [1, 2, 3, 4]) - sage: p.row_bounds(0) # optional - cvxopt + sage: p.row_bounds(0) (2.00000000000000, 2.00000000000000) - sage: p.add_linear_constraint(zip(range(5), range(5)), 1.0, 1.0, name='foo') # optional - cvxopt - sage: p.row_name(-1) # optional - cvxopt + sage: p.add_linear_constraint(zip(range(5), range(5)), 1.0, 1.0, name='foo') + sage: p.row_name(-1) 'foo' """ coefficients = list(coefficients) @@ -412,76 +413,85 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver = "cvxopt", maximization=False) # optional - cvxopt - sage: x=p.new_variable(nonnegative=True) # optional - cvxopt - sage: p.set_objective(-4*x[0] - 5*x[1]) # optional - cvxopt - sage: p.add_constraint(2*x[0] + x[1] <= 3) # optional - cvxopt - sage: p.add_constraint(2*x[1] + x[0] <= 3) # optional - cvxopt - sage: N(p.solve(), digits=2) # optional - cvxopt + sage: p = MixedIntegerLinearProgram(solver="cvxopt", maximization=False) + sage: x = p.new_variable(nonnegative=True) + sage: p.set_objective(-4*x[0] - 5*x[1]) + sage: p.add_constraint(2*x[0] + x[1] <= 3) + sage: p.add_constraint(2*x[1] + x[0] <= 3) + sage: N(p.solve(), digits=2) -9.0 - sage: p = MixedIntegerLinearProgram(solver = "cvxopt", maximization=False) # optional - cvxopt - sage: x=p.new_variable(nonnegative=True) # optional - cvxopt - sage: p.set_objective(x[0] + 2*x[1]) # optional - cvxopt - sage: p.add_constraint(-5*x[0] + x[1] <= 7) # optional - cvxopt - sage: p.add_constraint(-5*x[0] + x[1] >= 7) # optional - cvxopt - sage: p.add_constraint(x[0] + x[1] >= 26 ) # optional - cvxopt - sage: p.add_constraint( x[0] >= 3) # optional - cvxopt - sage: p.add_constraint( x[1] >= 4) # optional - cvxopt - sage: N(p.solve(),digits=4) # optional - cvxopt + + sage: p = MixedIntegerLinearProgram(solver="cvxopt", maximization=False) + sage: x = p.new_variable(nonnegative=True) + sage: p.set_objective(x[0] + 2*x[1]) + sage: p.add_constraint(-5*x[0] + x[1] <= 7) + sage: p.add_constraint(-5*x[0] + x[1] >= 7) + sage: p.add_constraint(x[0] + x[1] >= 26) + sage: p.add_constraint(x[0] >= 3) + sage: p.add_constraint(x[1] >= 4) + sage: N(p.solve(), digits=4) 48.83 - sage: p = MixedIntegerLinearProgram(solver = "cvxopt") # optional - cvxopt - sage: x=p.new_variable(nonnegative=True) # optional - cvxopt - sage: p.set_objective(x[0] + x[1] + 3*x[2]) # optional - cvxopt - sage: p.solver_parameter("show_progress",True) # optional - cvxopt - sage: p.add_constraint(x[0] + 2*x[1] <= 4) # optional - cvxopt - sage: p.add_constraint(5*x[2] - x[1] <= 8) # optional - cvxopt - sage: N(p.solve(), digits=2) # optional - cvxopt + + sage: p = MixedIntegerLinearProgram(solver="cvxopt") + sage: x = p.new_variable(nonnegative=True) + sage: p.set_objective(x[0] + x[1] + 3*x[2]) + sage: p.solver_parameter("show_progress",True) + sage: p.add_constraint(x[0] + 2*x[1] <= 4) + sage: p.add_constraint(5*x[2] - x[1] <= 8) + sage: N(p.solve(), digits=2) pcost dcost gap pres dres k/t ... 8.8 - sage: #CVXOPT gives different values for variables compared to the other solvers. - sage: c = MixedIntegerLinearProgram(solver = "cvxopt") # optional - cvxopt - sage: p = MixedIntegerLinearProgram(solver = "ppl") # optional - cvxopt - sage: g = MixedIntegerLinearProgram() # optional - cvxopt - sage: xc=c.new_variable(nonnegative=True) # optional - cvxopt - sage: xp=p.new_variable(nonnegative=True) # optional - cvxopt - sage: xg=g.new_variable(nonnegative=True) # optional - cvxopt - sage: c.set_objective(xc[2]) # optional - cvxopt - sage: p.set_objective(xp[2]) # optional - cvxopt - sage: g.set_objective(xg[2]) # optional - cvxopt - sage: #we create a cube for all three solvers - sage: c.add_constraint(xc[0] <= 100) # optional - cvxopt - sage: c.add_constraint(xc[1] <= 100) # optional - cvxopt - sage: c.add_constraint(xc[2] <= 100) # optional - cvxopt - sage: p.add_constraint(xp[0] <= 100) # optional - cvxopt - sage: p.add_constraint(xp[1] <= 100) # optional - cvxopt - sage: p.add_constraint(xp[2] <= 100) # optional - cvxopt - sage: g.add_constraint(xg[0] <= 100) # optional - cvxopt - sage: g.add_constraint(xg[1] <= 100) # optional - cvxopt - sage: g.add_constraint(xg[2] <= 100) # optional - cvxopt - sage: N(c.solve(),digits=4) # optional - cvxopt + + When the optimal solution is not unique, CVXOPT as an interior point solver + gives a different type of solution compared to the solvers that use the + simplex method. + + In the following example, the top face of the cube is optimal, and CVXOPT + gives the center point of the top face, whereas the other tested solvers + return a vertex:: + + sage: c = MixedIntegerLinearProgram(solver="cvxopt") + sage: p = MixedIntegerLinearProgram(solver="ppl") + sage: g = MixedIntegerLinearProgram() + sage: xc = c.new_variable(nonnegative=True) + sage: xp = p.new_variable(nonnegative=True) + sage: xg = g.new_variable(nonnegative=True) + sage: c.set_objective(xc[2]) + sage: p.set_objective(xp[2]) + sage: g.set_objective(xg[2]) + sage: c.add_constraint(xc[0] <= 100) + sage: c.add_constraint(xc[1] <= 100) + sage: c.add_constraint(xc[2] <= 100) + sage: p.add_constraint(xp[0] <= 100) + sage: p.add_constraint(xp[1] <= 100) + sage: p.add_constraint(xp[2] <= 100) + sage: g.add_constraint(xg[0] <= 100) + sage: g.add_constraint(xg[1] <= 100) + sage: g.add_constraint(xg[2] <= 100) + sage: N(c.solve(), digits=4) 100.0 - sage: N(c.get_values(xc[0]),digits=3) # optional - cvxopt + sage: N(c.get_values(xc[0]), digits=3) 50.0 - sage: N(c.get_values(xc[1]),digits=3) # optional - cvxopt + sage: N(c.get_values(xc[1]), digits=3) 50.0 - sage: N(c.get_values(xc[2]),digits=4) # optional - cvxopt + sage: N(c.get_values(xc[2]), digits=4) 100.0 - sage: N(p.solve(),digits=4) # optional - cvxopt + sage: N(p.solve(), digits=4) 100.0 - sage: N(p.get_values(xp[0]),2) # optional - cvxopt + sage: N(p.get_values(xp[0]), 2) 0.00 - sage: N(p.get_values(xp[1]),2) # optional - cvxopt + sage: N(p.get_values(xp[1]), 2) 0.00 - sage: N(p.get_values(xp[2]),digits=4) # optional - cvxopt + sage: N(p.get_values(xp[2]), digits=4) 100.0 - sage: N(g.solve(),digits=4) # optional - cvxopt + sage: N(g.solve(), digits=4) 100.0 - sage: N(g.get_values(xg[0]),2) # optional - cvxopt + sage: N(g.get_values(xg[0]), 2) 0.00 - sage: N(g.get_values(xg[1]),2) # optional - cvxopt + sage: N(g.get_values(xg[1]), 2) 0.00 - sage: N(g.get_values(xg[2]),digits=4) # optional - cvxopt + sage: N(g.get_values(xg[2]), digits=4) 100.0 """ from cvxopt import matrix, solvers @@ -565,18 +575,18 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "cvxopt") # optional - cvxopt - sage: p.add_variables(2) # optional - cvxopt + sage: p = get_solver(solver="cvxopt") + sage: p.add_variables(2) 1 - sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - cvxopt - sage: p.set_objective([2, 5]) # optional - cvxopt - sage: p.solve() # optional - cvxopt + sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) + sage: p.set_objective([2, 5]) + sage: p.solve() 0 - sage: N(p.get_objective_value(),4) # optional - cvxopt + sage: N(p.get_objective_value(),4) 7.5 - sage: N(p.get_variable_value(0),4) # optional - cvxopt + sage: N(p.get_variable_value(0),4) 3.6e-7 - sage: N(p.get_variable_value(1),4) # optional - cvxopt + sage: N(p.get_variable_value(1),4) 1.5 """ sum = self.obj_constant_term @@ -597,18 +607,18 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variables(2) # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variables(2) 1 - sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) # optional - cvxopt - sage: p.set_objective([2, 5]) # optional - cvxopt - sage: p.solve() # optional - cvxopt + sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) + sage: p.set_objective([2, 5]) + sage: p.solve() 0 - sage: N(p.get_objective_value(),4) # optional - cvxopt + sage: N(p.get_objective_value(),4) 7.5 - sage: N(p.get_variable_value(0),4) # optional - cvxopt + sage: N(p.get_variable_value(0),4) 3.6e-7 - sage: N(p.get_variable_value(1),4) # optional - cvxopt + sage: N(p.get_variable_value(1),4) 1.5 """ return self.answer['x'][variable] @@ -620,12 +630,12 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.ncols() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.ncols() 0 - sage: p.add_variables(2) # optional - cvxopt + sage: p.add_variables(2) 1 - sage: p.ncols() # optional - cvxopt + sage: p.ncols() 2 """ @@ -638,13 +648,13 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.nrows() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.nrows() 0 - sage: p.add_variables(5) # optional - cvxopt + sage: p.add_variables(5) 4 - sage: p.add_linear_constraints(2, 2.0, None) # optional - cvxopt - sage: p.nrows() # optional - cvxopt + sage: p.add_linear_constraints(2, 2.0, None) + sage: p.nrows() 2 """ return len(self.row_upper_bound) @@ -657,11 +667,11 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.is_maximization() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.is_maximization() True - sage: p.set_sense(-1) # optional - cvxopt - sage: p.is_maximization() # optional - cvxopt + sage: p.set_sense(-1) + sage: p.is_maximization() False """ if self.is_maximize == 1: @@ -681,11 +691,11 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.problem_name() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.problem_name() '' - sage: p.problem_name("There once was a french fry") # optional - cvxopt - sage: print(p.problem_name()) # optional - cvxopt + sage: p.problem_name("There once was a french fry") + sage: print(p.problem_name()) There once was a french fry """ if name is None: @@ -711,13 +721,13 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variables(5) # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variables(5) 4 - sage: p.add_linear_constraint(list(zip(range(5), range(5))), 2, 2) # optional - cvxopt - sage: p.row(0) # optional - cvxopt + sage: p.add_linear_constraint(list(zip(range(5), range(5))), 2, 2) + sage: p.row(0) ([1, 2, 3, 4], [1, 2, 3, 4]) - sage: p.row_bounds(0) # optional - cvxopt + sage: p.row_bounds(0) (2, 2) """ coeff = [] @@ -748,13 +758,13 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variables(5) # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variables(5) 4 - sage: p.add_linear_constraint(list(zip(range(5), range(5))), 2, 2) # optional - cvxopt - sage: p.row(0) # optional - cvxopt + sage: p.add_linear_constraint(list(zip(range(5), range(5))), 2, 2) + sage: p.row(0) ([1, 2, 3, 4], [1, 2, 3, 4]) - sage: p.row_bounds(0) # optional - cvxopt + sage: p.row_bounds(0) (2, 2) """ return (self.row_lower_bound[index], self.row_upper_bound[index]) @@ -776,13 +786,13 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variable() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variable() 0 - sage: p.col_bounds(0) # optional - cvxopt + sage: p.col_bounds(0) (0.0, None) - sage: p.variable_upper_bound(0, 5) # optional - cvxopt - sage: p.col_bounds(0) # optional - cvxopt + sage: p.variable_upper_bound(0, 5) + sage: p.col_bounds(0) (0.0, 5) """ return (self.col_lower_bound[index], self.col_upper_bound[index]) @@ -799,16 +809,16 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.ncols() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.ncols() 0 - sage: p.add_variable() # optional - cvxopt + sage: p.add_variable() 0 - sage: p.set_variable_type(0,0) # optional - cvxopt + sage: p.set_variable_type(0,0) Traceback (most recent call last): ... ValueError: ... - sage: p.is_variable_binary(0) # optional - cvxopt + sage: p.is_variable_binary(0) False """ @@ -826,17 +836,17 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.ncols() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.ncols() 0 - sage: p.add_variable() # optional - cvxopt + sage: p.add_variable() 0 - sage: p.set_variable_type(0,-1) # optional - cvxopt - sage: p.set_variable_type(0,1) # optional - cvxopt + sage: p.set_variable_type(0,-1) + sage: p.set_variable_type(0,1) Traceback (most recent call last): ... ValueError: ... - sage: p.is_variable_integer(0) # optional - cvxopt + sage: p.is_variable_integer(0) False """ return False @@ -853,18 +863,18 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.ncols() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.ncols() 0 - sage: p.add_variable() # optional - cvxopt + sage: p.add_variable() 0 - sage: p.is_variable_continuous(0) # optional - cvxopt + sage: p.is_variable_continuous(0) True - sage: p.set_variable_type(0,1) # optional - cvxopt + sage: p.set_variable_type(0,1) Traceback (most recent call last): ... ValueError: ... - sage: p.is_variable_continuous(0) # optional - cvxopt + sage: p.is_variable_continuous(0) True """ @@ -881,9 +891,9 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_linear_constraints(1, 2, None, names=["Empty constraint 1"]) # optional - cvxopt - sage: p.row_name(0) # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_linear_constraints(1, 2, None, names=["Empty constraint 1"]) + sage: p.row_name(0) 'Empty constraint 1' """ if self.row_name_var[index] is not None: @@ -904,10 +914,10 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variable(name="I am a variable") # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variable(name="I am a variable") 0 - sage: p.col_name(0) # optional - cvxopt + sage: p.col_name(0) 'I am a variable' """ if self.col_name_var[index] is not None: @@ -929,13 +939,13 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variable() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variable() 0 - sage: p.col_bounds(0) # optional - cvxopt + sage: p.col_bounds(0) (0.0, None) - sage: p.variable_upper_bound(0, 5) # optional - cvxopt - sage: p.col_bounds(0) # optional - cvxopt + sage: p.variable_upper_bound(0, 5) + sage: p.col_bounds(0) (0.0, 5) """ if value is not False: @@ -958,13 +968,13 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.add_variable() # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.add_variable() 0 - sage: p.col_bounds(0) # optional - cvxopt + sage: p.col_bounds(0) (0.0, None) - sage: p.variable_lower_bound(0, 5) # optional - cvxopt - sage: p.col_bounds(0) # optional - cvxopt + sage: p.variable_lower_bound(0, 5) + sage: p.col_bounds(0) (5, None) """ if value is not False: @@ -991,11 +1001,11 @@ cdef class CVXOPTBackend(GenericBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver="CVXOPT") # optional - cvxopt - sage: p.solver_parameter("show_progress") # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.solver_parameter("show_progress") False - sage: p.solver_parameter("show_progress", True) # optional - cvxopt - sage: p.solver_parameter("show_progress") # optional - cvxopt + sage: p.solver_parameter("show_progress", True) + sage: p.solver_parameter("show_progress") True """ if value is None: diff --git a/src/sage/numerical/backends/cvxopt_sdp_backend.pyx b/src/sage/numerical/backends/cvxopt_sdp_backend.pyx index aefa91439bf..115e3f504bb 100644 --- a/src/sage/numerical/backends/cvxopt_sdp_backend.pyx +++ b/src/sage/numerical/backends/cvxopt_sdp_backend.pyx @@ -1,12 +1,13 @@ +# sage.doctest: needs cvxopt r""" CVXOPT SDP Backend AUTHORS: -- Ingolfur Edvardsson (2014-05) : initial implementation +- Ingolfur Edvardsson (2014-05): initial implementation -- Dima Pasechnik (2015-12) : minor fixes +- Dima Pasechnik (2015-12): minor fixes """ #***************************************************************************** @@ -36,7 +37,7 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") """ @@ -62,15 +63,15 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): .. NOTE:: - This method raises ``SDPSolverException`` exceptions when + This method raises :class:`SDPSolverException` exceptions when the solution cannot be computed for any reason (none exists, or the LP solver was not able to find it, etc...) EXAMPLES:: - sage: p = SemidefiniteProgram(solver = "cvxopt", maximization=False) # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0] - x[1] + x[2]) # optional - cvxopt + sage: p = SemidefiniteProgram(solver="cvxopt", maximization=False) + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1] + x[2]) sage: a1 = matrix([[-7., -11.], [-11., 3.]]) sage: a2 = matrix([[7., -18.], [-18., 8.]]) sage: a3 = matrix([[-2., -8.], [-8., 1.]]) @@ -79,13 +80,13 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): sage: b2 = matrix([[0., 10., 16.], [10., -10., -10.], [16., -10., 3.]]) sage: b3 = matrix([[-5., 2., -17.], [2., -6., 8.], [-17., 8., 6.]]) sage: b4 = matrix([[14., 9., 40.], [9., 91., 10.], [40., 10., 15.]]) - sage: p.add_constraint(a1*x[0] + a3*x[2] <= a4) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) # optional - cvxopt - sage: N(p.solve(), digits=4) # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a3*x[2] <= a4) + sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) + sage: N(p.solve(), digits=4) -3.225 - sage: p = SemidefiniteProgram(solver = "cvxopt", maximization=False) # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0] - x[1] + x[2]) # optional - cvxopt + sage: p = SemidefiniteProgram(solver="cvxopt", maximization=False) + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1] + x[2]) sage: a1 = matrix([[-7., -11.], [-11., 3.]]) sage: a2 = matrix([[7., -18.], [-18., 8.]]) sage: a3 = matrix([[-2., -8.], [-8., 1.]]) @@ -94,9 +95,9 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): sage: b2 = matrix([[0., 10., 16.], [10., -10., -10.], [16., -10., 3.]]) sage: b3 = matrix([[-5., 2., -17.], [2., -6., 8.], [-17., 8., 6.]]) sage: b4 = matrix([[14., 9., 40.], [9., 91., 10.], [40., 10., 15.]]) - sage: p.add_constraint(a1*x[0] + a2*x[1] + a3*x[2] <= a4) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) # optional - cvxopt - sage: N(p.solve(), digits=4) # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a2*x[1] + a3*x[2] <= a4) + sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) + sage: N(p.solve(), digits=4) -3.154 """ @@ -171,9 +172,9 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: - sage: p = SemidefiniteProgram(solver = "cvxopt", maximization=False) # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0] - x[1] + x[2]) # optional - cvxopt + sage: p = SemidefiniteProgram(solver="cvxopt", maximization=False) + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1] + x[2]) sage: a1 = matrix([[-7., -11.], [-11., 3.]]) sage: a2 = matrix([[7., -18.], [-18., 8.]]) sage: a3 = matrix([[-2., -8.], [-8., 1.]]) @@ -182,11 +183,11 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): sage: b2 = matrix([[0., 10., 16.], [10., -10., -10.], [16., -10., 3.]]) sage: b3 = matrix([[-5., 2., -17.], [2., -6., 8.], [-17., 8., 6.]]) sage: b4 = matrix([[14., 9., 40.], [9., 91., 10.], [40., 10., 15.]]) - sage: p.add_constraint(a1*x[0] + a2*x[1] + a3*x[2] <= a4) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) # optional - cvxopt - sage: N(p.solve(), digits=4) # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a2*x[1] + a3*x[2] <= a4) + sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) + sage: N(p.solve(), digits=4) -3.154 - sage: N(p.get_backend().get_objective_value(), digits=4) # optional - cvxopt + sage: N(p.get_backend().get_objective_value(), digits=4) -3.154 """ sum = self.obj_constant_term @@ -204,20 +205,20 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): TESTS:: - sage: p = SemidefiniteProgram(maximization = False, solver='cvxopt') # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0] - x[1]) # optional - cvxopt + sage: p = SemidefiniteProgram(maximization=False, solver='cvxopt') + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1]) sage: a1 = matrix([[1, 2.], [2., 3.]]) sage: a2 = matrix([[3, 4.], [4., 5.]]) sage: a3 = matrix([[5, 6.], [6., 7.]]) sage: b1 = matrix([[1, 1.], [1., 1.]]) sage: b2 = matrix([[2, 2.], [2., 2.]]) sage: b3 = matrix([[3, 3.], [3., 3.]]) - sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) # optional - cvxopt - sage: p.solve(); # tol 1e-08 # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) + sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) + sage: p.solve(); # tol 1e-08 -3.0 - sage: p.get_backend()._get_answer() # optional - cvxopt + sage: p.get_backend()._get_answer() {...} """ return self.answer @@ -232,9 +233,9 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: - sage: p = SemidefiniteProgram(solver = "cvxopt", maximization=False) # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0] - x[1] + x[2]) # optional - cvxopt + sage: p = SemidefiniteProgram(solver="cvxopt", maximization=False) + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1] + x[2]) sage: a1 = matrix([[-7., -11.], [-11., 3.]]) sage: a2 = matrix([[7., -18.], [-18., 8.]]) sage: a3 = matrix([[-2., -8.], [-8., 1.]]) @@ -243,15 +244,15 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): sage: b2 = matrix([[0., 10., 16.], [10., -10., -10.], [16., -10., 3.]]) sage: b3 = matrix([[-5., 2., -17.], [2., -6., 8.], [-17., 8., 6.]]) sage: b4 = matrix([[14., 9., 40.], [9., 91., 10.], [40., 10., 15.]]) - sage: p.add_constraint(a1*x[0] + a2*x[1] + a3*x[2] <= a4) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) # optional - cvxopt - sage: N(p.solve(), digits=4) # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a2*x[1] + a3*x[2] <= a4) + sage: p.add_constraint(b1*x[0] + b2*x[1] + b3*x[2] <= b4) + sage: N(p.solve(), digits=4) -3.154 - sage: N(p.get_backend().get_variable_value(0), digits=3) # optional - cvxopt + sage: N(p.get_backend().get_variable_value(0), digits=3) -0.368 - sage: N(p.get_backend().get_variable_value(1), digits=4) # optional - cvxopt + sage: N(p.get_backend().get_variable_value(1), digits=4) 1.898 - sage: N(p.get_backend().get_variable_value(2), digits=3) # optional - cvxopt + sage: N(p.get_backend().get_variable_value(2), digits=3) -0.888 """ return self.answer['x'][variable] @@ -270,34 +271,34 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: - sage: p = SemidefiniteProgram(maximization = False, solver='cvxopt') # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0] - x[1]) # optional - cvxopt + sage: p = SemidefiniteProgram(maximization=False, solver='cvxopt') + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1]) sage: a1 = matrix([[1, 2.], [2., 3.]]) sage: a2 = matrix([[3, 4.], [4., 5.]]) sage: a3 = matrix([[5, 6.], [6., 7.]]) sage: b1 = matrix([[1, 1.], [1., 1.]]) sage: b2 = matrix([[2, 2.], [2., 2.]]) sage: b3 = matrix([[3, 3.], [3., 3.]]) - sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) # optional - cvxopt - sage: p.solve() # tol 1e-08 # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) + sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) + sage: p.solve() # tol 1e-08 -3.0 - sage: B=p.get_backend() # optional - cvxopt - sage: x=p.get_values(x).values() # optional - cvxopt - sage: -(a3*B.dual_variable(0)).trace()-(b3*B.dual_variable(1)).trace() # tol 1e-07 # optional - cvxopt + sage: B = p.get_backend() + sage: x = p.get_values(x).values() + sage: -(a3*B.dual_variable(0)).trace() - (b3*B.dual_variable(1)).trace() # tol 1e-07 -3.0 - sage: g = sum((B.slack(j)*B.dual_variable(j)).trace() for j in range(2)); g # tol 1.5e-08 # optional - cvxopt + sage: g = sum((B.slack(j)*B.dual_variable(j)).trace() for j in range(2)); g # tol 1.5e-08 0.0 TESTS:: - sage: B.dual_variable(7) # optional - cvxopt + sage: B.dual_variable(7) Traceback (most recent call last): ... IndexError: list index out of range - sage: abs(g - B._get_answer()['gap']) # tol 1e-22 # optional - cvxopt + sage: abs(g - B._get_answer()['gap']) # tol 1e-22 0.0 """ @@ -320,33 +321,33 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: - sage: p = SemidefiniteProgram(maximization = False, solver='cvxopt') # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0] - x[1]) # optional - cvxopt + sage: p = SemidefiniteProgram(maximization = False, solver='cvxopt') + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1]) sage: a1 = matrix([[1, 2.], [2., 3.]]) sage: a2 = matrix([[3, 4.], [4., 5.]]) sage: a3 = matrix([[5, 6.], [6., 7.]]) sage: b1 = matrix([[1, 1.], [1., 1.]]) sage: b2 = matrix([[2, 2.], [2., 2.]]) sage: b3 = matrix([[3, 3.], [3., 3.]]) - sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) # optional - cvxopt - sage: p.solve() # tol 1e-08 # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) + sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) + sage: p.solve() # tol 1e-08 -3.0 - sage: B = p.get_backend() # optional - cvxopt - sage: B1 = B.slack(1); B1 # tol 1e-08 # optional - cvxopt + sage: B = p.get_backend() + sage: B1 = B.slack(1); B1 # tol 1e-08 [0.0 0.0] [0.0 0.0] - sage: B1.is_positive_definite() # optional - cvxopt + sage: B1.is_positive_definite() True - sage: x = sorted(p.get_values(x).values()) # optional - cvxopt - sage: x[0]*b1 + x[1]*b2 - b3 + B1 # tol 1e-09 # optional - cvxopt + sage: x = sorted(p.get_values(x).values()) + sage: x[0]*b1 + x[1]*b2 - b3 + B1 # tol 1e-09 [0.0 0.0] [0.0 0.0] TESTS:: - sage: B.slack(7) # optional - cvxopt + sage: B.slack(7) Traceback (most recent call last): ... IndexError: list index out of range @@ -358,7 +359,7 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): return Matrix(n, n, list(self.answer['ss'][i]), sparse=sparse) - cpdef solver_parameter(self, name, value = None) noexcept: + cpdef solver_parameter(self, name, value=None) noexcept: """ Return or define a solver parameter @@ -377,11 +378,11 @@ cdef class CVXOPTSDPBackend(MatrixSDPBackend): EXAMPLES:: sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "CVXOPT") # optional - cvxopt - sage: p.solver_parameter("show_progress") # optional - cvxopt + sage: p = get_solver(solver="CVXOPT") + sage: p.solver_parameter("show_progress") False - sage: p.solver_parameter("show_progress", True) # optional - cvxopt - sage: p.solver_parameter("show_progress") # optional - cvxopt + sage: p.solver_parameter("show_progress", True) + sage: p.solver_parameter("show_progress") True """ if value is None: diff --git a/src/sage/numerical/backends/cvxpy_backend.pyx b/src/sage/numerical/backends/cvxpy_backend.pyx index 7cf5ccc8fb6..1cbba9f6375 100644 --- a/src/sage/numerical/backends/cvxpy_backend.pyx +++ b/src/sage/numerical/backends/cvxpy_backend.pyx @@ -58,11 +58,11 @@ cdef class CVXPYBackend: Open-source solvers provided by optional packages:: - sage: p = MixedIntegerLinearProgram(solver="CVXPY/GLPK"); p.solve() # optional - cvxopt + sage: p = MixedIntegerLinearProgram(solver="CVXPY/GLPK"); p.solve() # needs cvxopt 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/GLPK_MI"); p.solve() # optional - cvxopt + sage: p = MixedIntegerLinearProgram(solver="CVXPY/GLPK_MI"); p.solve() # needs cvxopt 0.0 - sage: p = MixedIntegerLinearProgram(solver="CVXPY/CVXOPT"); p.solve() # optional - cvxopt + sage: p = MixedIntegerLinearProgram(solver="CVXPY/CVXOPT"); p.solve() # needs cvxopt 0.0 sage: p = MixedIntegerLinearProgram(solver="CVXPY/GLOP"); p.solve() # optional - ortools 0.0 diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 6d43a6ba958..c5c7dadc4c1 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -3,7 +3,7 @@ Generic Backend for LP solvers This class only lists the methods that should be defined by any interface with a LP Solver. All these methods immediately raise -``NotImplementedError`` exceptions when called, and are obviously +:class:`NotImplementedError` exceptions when called, and are obviously meant to be replaced by the solver-specific method. This file can also be used as a template to create a new interface : one would only need to replace the occurrences of ``"Nonexistent_LP_solver"`` by the @@ -69,27 +69,28 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p.add_variable() 0 - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p.ncols() 1 - sage: p.add_variable(binary=True) # optional - Nonexistent_LP_solver + sage: p.add_variable(binary=True) 1 - sage: p.add_variable(lower_bound=-2.0, integer=True) # optional - Nonexistent_LP_solver + sage: p.add_variable(lower_bound=-2.0, integer=True) 2 - sage: p.add_variable(continuous=True, integer=True) # optional - Nonexistent_LP_solver + sage: p.add_variable(continuous=True, integer=True) Traceback (most recent call last): ... ValueError: ... - sage: p.add_variable(name='x',obj=1.0) # optional - Nonexistent_LP_solver + sage: p.add_variable(name='x', obj=1.0) 3 - sage: p.col_name(3) # optional - Nonexistent_LP_solver + sage: p.col_name(3) 'x' - sage: p.objective_coefficient(3) # optional - Nonexistent_LP_solver + sage: p.objective_coefficient(3) 1.0 """ raise NotImplementedError() @@ -123,28 +124,30 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p.add_variables(5) 4 - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p.ncols() 5 - sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b']) # optional - Nonexistent_LP_solver + sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b']) 6 TESTS: Check that arguments are used:: - sage: p.col_bounds(5) # tol 1e-8, optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p.col_bounds(5) # tol 1e-8 (-2.0, None) - sage: p.is_variable_integer(5) # optional - Nonexistent_LP_solver + sage: p.is_variable_integer(5) True - sage: p.col_name(5) # optional - Nonexistent_LP_solver + sage: p.col_name(5) 'a' - sage: p.objective_coefficient(5) # tol 1e-8, optional - Nonexistent_LP_solver + sage: p.objective_coefficient(5) # tol 1e-8 42.0 """ cdef int i @@ -215,22 +218,23 @@ cdef class GenericBackend: - ``variable`` (integer) -- the variable's id - - ``vtype`` (integer) : + - ``vtype`` (integer): - * 1 Integer - * 0 Binary - * -1 Continuous + * `1` Integer + * `0` Binary + * `-1` Continuous EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p.add_variable() 0 - sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver - sage: p.is_variable_integer(0) # optional - Nonexistent_LP_solver + sage: p.set_variable_type(0,1) + sage: p.is_variable_integer(0) True """ raise NotImplementedError() @@ -248,12 +252,13 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.is_maximization() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.is_maximization() True - sage: p.set_sense(-1) # optional - Nonexistent_LP_solver - sage: p.is_maximization() # optional - Nonexistent_LP_solver + sage: p.set_sense(-1) + sage: p.is_maximization() False """ raise NotImplementedError() @@ -293,14 +298,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variable() 0 - sage: p.objective_coefficient(0) # optional - Nonexistent_LP_solver + sage: p.objective_coefficient(0) 0.0 - sage: p.objective_coefficient(0,2) # optional - Nonexistent_LP_solver - sage: p.objective_coefficient(0) # optional - Nonexistent_LP_solver + sage: p.objective_coefficient(0,2) + sage: p.objective_coefficient(0) 2.0 """ raise NotImplementedError() @@ -315,12 +321,13 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.objective_constant_term() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.objective_constant_term() 0.0 - sage: p.objective_constant_term(42) # optional - Nonexistent_LP_solver - sage: p.objective_constant_term() # optional - Nonexistent_LP_solver + sage: p.objective_constant_term(42) + sage: p.objective_constant_term() 42.0 """ if d is None: @@ -341,23 +348,25 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 4 - sage: p.set_objective([1, 1, 2, 1, 3]) # optional - Nonexistent_LP_solver - sage: [p.objective_coefficient(x) for x in range(5)] # optional - Nonexistent_LP_solver + sage: p.set_objective([1, 1, 2, 1, 3]) + sage: [p.objective_coefficient(x) for x in range(5)] [1.0, 1.0, 2.0, 1.0, 3.0] Constants in the objective function are respected:: - sage: p = MixedIntegerLinearProgram(solver='Nonexistent_LP_solver') # optional - Nonexistent_LP_solver - sage: x,y = p[0], p[1] # optional - Nonexistent_LP_solver - sage: p.add_constraint(2*x + 3*y, max = 6) # optional - Nonexistent_LP_solver - sage: p.add_constraint(3*x + 2*y, max = 6) # optional - Nonexistent_LP_solver - sage: p.set_objective(x + y + 7) # optional - Nonexistent_LP_solver - sage: p.set_integer(x); p.set_integer(y) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p = MixedIntegerLinearProgram(solver='Nonexistent_LP_solver') + sage: x,y = p[0], p[1] + sage: p.add_constraint(2*x + 3*y, max=6) + sage: p.add_constraint(3*x + 2*y, max=6) + sage: p.set_objective(x + y + 7) + sage: p.set_integer(x); p.set_integer(y) + sage: p.solve() 9.0 """ raise NotImplementedError() @@ -373,7 +382,7 @@ cdef class GenericBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver sage: p.set_verbosity(2) # optional - Nonexistent_LP_solver """ raise NotImplementedError() @@ -388,19 +397,20 @@ cdef class GenericBackend: EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: v = p.new_variable(nonnegative=True) # optional - Nonexistent_LP_solver - sage: x,y = v[0], v[1] # optional - Nonexistent_LP_solver - sage: p.add_constraint(2*x + 3*y, max = 6) # optional - Nonexistent_LP_solver - sage: p.add_constraint(3*x + 2*y, max = 6) # optional - Nonexistent_LP_solver - sage: p.set_objective(x + y + 7) # optional - Nonexistent_LP_solver - sage: p.set_integer(x); p.set_integer(y) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") + sage: v = p.new_variable(nonnegative=True) + sage: x,y = v[0], v[1] + sage: p.add_constraint(2*x + 3*y, max=6) + sage: p.add_constraint(3*x + 2*y, max=6) + sage: p.set_objective(x + y + 7) + sage: p.set_integer(x); p.set_integer(y) + sage: p.solve() 9.0 - sage: p.remove_constraint(0) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.remove_constraint(0) + sage: p.solve() 10.0 - sage: p.get_values([x,y]) # optional - Nonexistent_LP_solver + sage: p.get_values([x,y]) [0.0, 3.0] """ raise NotImplementedError() @@ -415,13 +425,14 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(2) 1 - sage: p.add_linear_constraint([(0, 2), (1, 3)], None, 6) # optional - Nonexistent_LP_solver - sage: p.add_linear_constraint([(0, 3), (1, 2)], None, 6) # optional - Nonexistent_LP_solver - sage: p.remove_constraints([0, 1]) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint([(0, 2), (1, 3)], None, 6) + sage: p.add_linear_constraint([(0, 3), (1, 2)], None, 6) + sage: p.remove_constraints([0, 1]) """ if isinstance(constraints, int): self.remove_constraint(constraints) @@ -452,17 +463,18 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 4 - sage: p.add_linear_constraint( zip(range(5), range(5)), 2.0, 2.0) # optional - Nonexistent_LP_solver - sage: p.row(0) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint( zip(range(5), range(5)), 2.0, 2.0) + sage: p.row(0) ([0, 1, 2, 3, 4], [0.0, 1.0, 2.0, 3.0, 4.0]) - sage: p.row_bounds(0) # optional - Nonexistent_LP_solver + sage: p.row_bounds(0) (2.0, 2.0) - sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo') # optional - Nonexistent_LP_solver - sage: p.row_name(1) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo') + sage: p.row_name(1) 'foo' """ raise NotImplementedError('add_linear_constraint') @@ -498,14 +510,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") sage: coeffs = ([0, vector([1, 2])], [1, vector([2, 3])]) sage: upper = vector([5, 5]) sage: lower = vector([0, 0]) - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p.add_variables(2) 1 - sage: p.add_linear_constraint_vector(2, coeffs, lower, upper, 'foo') # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint_vector(2, coeffs, lower, upper, 'foo') """ for d in range(degree): coefficients_d = [] @@ -569,15 +582,16 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.nrows() # optional - Nonexistent_LP_solver + sage: p.nrows() 0 - sage: p.add_linear_constraints(5, 0, None) # optional - Nonexistent_LP_solver - sage: p.add_col(list(range(5)), list(range(5))) # optional - Nonexistent_LP_solver - sage: p.nrows() # optional - Nonexistent_LP_solver + sage: p.add_linear_constraints(5, 0, None) + sage: p.add_col(list(range(5)), list(range(5))) + sage: p.nrows() 5 """ raise NotImplementedError() @@ -622,14 +636,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 5 - sage: p.add_linear_constraints(5, None, 2) # optional - Nonexistent_LP_solver - sage: p.row(4) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraints(5, None, 2) + sage: p.row(4) ([], []) - sage: p.row_bounds(4) # optional - Nonexistent_LP_solver + sage: p.row_bounds(4) (None, 2.0) """ cdef int i @@ -686,14 +701,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_linear_constraints(5, 0, None) # optional - Nonexistent_LP_solver - sage: p.add_col(list(range(5)), list(range(5))) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_linear_constraints(5, 0, None) + sage: p.add_col(list(range(5)), list(range(5))) + sage: p.solve() 0 - sage: p.objective_coefficient(0,1) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.objective_coefficient(0,1) + sage: p.solve() Traceback (most recent call last): ... MIPSolverException: ... @@ -739,19 +755,20 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(2) 1 - sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - Nonexistent_LP_solver - sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) + sage: p.set_objective([2, 5]) + sage: p.solve() 0 - sage: p.get_objective_value() # optional - Nonexistent_LP_solver + sage: p.get_objective_value() 7.5 - sage: p.get_variable_value(0) # optional - Nonexistent_LP_solver + sage: p.get_variable_value(0) 0.0 - sage: p.get_variable_value(1) # optional - Nonexistent_LP_solver + sage: p.get_variable_value(1) 1.5 """ @@ -774,17 +791,18 @@ cdef class GenericBackend: EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: b = p.new_variable(binary=True) # optional - Nonexistent_LP_solver - sage: for u,v in graphs.CycleGraph(5).edges(labels=False): # optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") + sage: b = p.new_variable(binary=True) + sage: for u,v in graphs.CycleGraph(5).edges(labels=False): ....: p.add_constraint(b[u]+b[v]<=1) - sage: p.set_objective(p.sum(b[x] for x in range(5))) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.set_objective(p.sum(b[x] for x in range(5))) + sage: p.solve() 2.0 - sage: pb = p.get_backend() # optional - Nonexistent_LP_solver - sage: pb.get_objective_value() # optional - Nonexistent_LP_solver + sage: pb = p.get_backend() + sage: pb.get_objective_value() 2.0 - sage: pb.best_known_objective_bound() # optional - Nonexistent_LP_solver + sage: pb.best_known_objective_bound() 2.0 """ raise NotImplementedError() @@ -809,17 +827,18 @@ cdef class GenericBackend: EXAMPLES:: - sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: b = p.new_variable(binary=True) # optional - Nonexistent_LP_solver - sage: for u,v in graphs.CycleGraph(5).edges(labels=False): # optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") + sage: b = p.new_variable(binary=True) + sage: for u,v in graphs.CycleGraph(5).edges(labels=False): ....: p.add_constraint(b[u]+b[v]<=1) - sage: p.set_objective(p.sum(b[x] for x in range(5))) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.set_objective(p.sum(b[x] for x in range(5))) + sage: p.solve() 2.0 - sage: pb = p.get_backend() # optional - Nonexistent_LP_solver - sage: pb.get_objective_value() # optional - Nonexistent_LP_solver + sage: pb = p.get_backend() + sage: pb.get_objective_value() 2.0 - sage: pb.get_relative_objective_gap() # optional - Nonexistent_LP_solver + sage: pb.get_relative_objective_gap() 0.0 """ raise NotImplementedError() @@ -835,19 +854,20 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(2) 1 - sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) # optional - Nonexistent_LP_solver - sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) + sage: p.set_objective([2, 5]) + sage: p.solve() 0 - sage: p.get_objective_value() # optional - Nonexistent_LP_solver + sage: p.get_objective_value() 7.5 - sage: p.get_variable_value(0) # optional - Nonexistent_LP_solver + sage: p.get_variable_value(0) 0.0 - sage: p.get_variable_value(1) # optional - Nonexistent_LP_solver + sage: p.get_variable_value(1) 1.5 """ @@ -859,13 +879,14 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p.add_variables(2) 1 - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p.ncols() 2 """ @@ -885,12 +906,13 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.nrows() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.nrows() 0 - sage: p.add_linear_constraints(2, 2.0, None) # optional - Nonexistent_LP_solver - sage: p.nrows() # optional - Nonexistent_LP_solver + sage: p.add_linear_constraints(2, 2.0, None) + sage: p.nrows() 2 """ @@ -902,12 +924,13 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.is_maximization() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.is_maximization() True - sage: p.set_sense(-1) # optional - Nonexistent_LP_solver - sage: p.is_maximization() # optional - Nonexistent_LP_solver + sage: p.set_sense(-1) + sage: p.is_maximization() False """ raise NotImplementedError() @@ -924,7 +947,7 @@ cdef class GenericBackend: EXAMPLES:: sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver sage: p.problem_name("There once was a french fry") # optional - Nonexistent_LP_solver sage: print(p.problem_name()) # optional - Nonexistent_LP_solver There once was a french fry @@ -942,14 +965,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(2) 2 - sage: p.add_linear_constraint([(0, 1], (1, 2)], None, 3) # optional - Nonexistent_LP_solver - sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver - sage: from tempfile import NamedTemporaryFile # optional - Nonexistent_LP_solver - sage: with NamedTemporaryFile(suffix=".lp") as f: # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint([(0, 1], (1, 2)], None, 3) + sage: p.set_objective([2, 5]) + sage: from tempfile import NamedTemporaryFile + sage: with NamedTemporaryFile(suffix=".lp") as f: ....: p.write_lp(f.name) """ raise NotImplementedError() @@ -964,14 +988,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(2) 2 - sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) # optional - Nonexistent_LP_solver - sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver - sage: from tempfile import NamedTemporaryFile # optional - Nonexistent_LP_solver - sage: with NamedTemporaryFile(suffix=".lp") as f: # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) + sage: p.set_objective([2, 5]) + sage: from tempfile import NamedTemporaryFile + sage: with NamedTemporaryFile(suffix=".lp") as f: ....: p.write_lp(f.name) """ @@ -983,12 +1008,13 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = MixedIntegerLinearProgram(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: b = p.new_variable() # optional - Nonexistent_LP_solver - sage: p.add_constraint(b[1] + b[2] <= 6) # optional - Nonexistent_LP_solver - sage: p.set_objective(b[1] + b[2]) # optional - Nonexistent_LP_solver - sage: copy(p).solve() # optional - Nonexistent_LP_solver + sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") + sage: b = p.new_variable() + sage: p.add_constraint(b[1] + b[2] <= 6) + sage: p.set_objective(b[1] + b[2]) + sage: copy(p).solve() 6.0 """ return self.__copy__() @@ -1000,15 +1026,16 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = MixedIntegerLinearProgram(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: b = p.new_variable() # optional - Nonexistent_LP_solver - sage: p.add_constraint(b[1] + b[2] <= 6) # optional - Nonexistent_LP_solver - sage: p.set_objective(b[1] + b[2]) # optional - Nonexistent_LP_solver - sage: cp = copy(p.get_backend()) # optional - Nonexistent_LP_solver - sage: cp.solve() # optional - Nonexistent_LP_solver + sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") + sage: b = p.new_variable() + sage: p.add_constraint(b[1] + b[2] <= 6) + sage: p.set_objective(b[1] + b[2]) + sage: cp = copy(p.get_backend()) + sage: cp.solve() 0 - sage: cp.get_objective_value() # optional - Nonexistent_LP_solver + sage: cp.get_objective_value() 6.0 """ raise NotImplementedError() @@ -1019,15 +1046,16 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = MixedIntegerLinearProgram(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: b = p.new_variable() # optional - Nonexistent_LP_solver - sage: p.add_constraint(b[1] + b[2] <= 6) # optional - Nonexistent_LP_solver - sage: p.set_objective(b[1] + b[2]) # optional - Nonexistent_LP_solver - sage: cp = deepcopy(p.get_backend()) # optional - Nonexistent_LP_solver - sage: cp.solve() # optional - Nonexistent_LP_solver + sage: p = MixedIntegerLinearProgram(solver="Nonexistent_LP_solver") + sage: b = p.new_variable() + sage: p.add_constraint(b[1] + b[2] <= 6) + sage: p.set_objective(b[1] + b[2]) + sage: cp = deepcopy(p.get_backend()) + sage: cp.solve() 0 - sage: cp.get_objective_value() # optional - Nonexistent_LP_solver + sage: cp.get_objective_value() 6.0 """ return self.__copy__() @@ -1049,14 +1077,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 4 - sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) # optional - Nonexistent_LP_solver - sage: p.row(0) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) + sage: p.row(0) ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0]) ## FIXME: Why backwards? - sage: p.row_bounds(0) # optional - Nonexistent_LP_solver + sage: p.row_bounds(0) (2.0, 2.0) """ raise NotImplementedError() @@ -1077,14 +1106,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 4 - sage: p.add_linear_constraint(list(range(5)), list(range(5)), 2, 2) # optional - Nonexistent_LP_solver - sage: p.row(0) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint(list(range(5)), list(range(5)), 2, 2) + sage: p.row(0) ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0]) ## FIXME: Why backwards? - sage: p.row_bounds(0) # optional - Nonexistent_LP_solver + sage: p.row_bounds(0) (2.0, 2.0) """ raise NotImplementedError() @@ -1105,14 +1135,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variable() 0 - sage: p.col_bounds(0) # optional - Nonexistent_LP_solver + sage: p.col_bounds(0) (0.0, None) - sage: p.variable_upper_bound(0, 5) # optional - Nonexistent_LP_solver - sage: p.col_bounds(0) # optional - Nonexistent_LP_solver + sage: p.variable_upper_bound(0, 5) + sage: p.col_bounds(0) (0.0, 5.0) """ raise NotImplementedError() @@ -1127,14 +1158,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p.add_variable() 0 - sage: p.set_variable_type(0,0) # optional - Nonexistent_LP_solver - sage: p.is_variable_binary(0) # optional - Nonexistent_LP_solver + sage: p.set_variable_type(0,0) + sage: p.is_variable_binary(0) True """ @@ -1150,14 +1182,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p.add_variable() 0 - sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver - sage: p.is_variable_integer(0) # optional - Nonexistent_LP_solver + sage: p.set_variable_type(0,1) + sage: p.is_variable_integer(0) True """ raise NotImplementedError() @@ -1172,16 +1205,17 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p.add_variable() 0 - sage: p.is_variable_continuous(0) # optional - Nonexistent_LP_solver + sage: p.is_variable_continuous(0) True - sage: p.set_variable_type(0,1) # optional - Nonexistent_LP_solver - sage: p.is_variable_continuous(0) # optional - Nonexistent_LP_solver + sage: p.set_variable_type(0,1) + sage: p.is_variable_continuous(0) False """ @@ -1197,10 +1231,11 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1']) # optional - Nonexistent_LP_solver - sage: p.row_name(0) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_linear_constraints(1, 2, None, names=['Empty constraint 1']) + sage: p.row_name(0) 'Empty constraint 1' """ @@ -1219,11 +1254,12 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variable(name="I am a variable") # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variable(name="I am a variable") 1 - sage: p.col_name(0) # optional - Nonexistent_LP_solver + sage: p.col_name(0) 'I am a variable' """ raise NotImplementedError() @@ -1323,14 +1359,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variable() 0 - sage: p.col_bounds(0) # optional - Nonexistent_LP_solver + sage: p.col_bounds(0) (0.0, None) - sage: p.variable_upper_bound(0, 5) # optional - Nonexistent_LP_solver - sage: p.col_bounds(0) # optional - Nonexistent_LP_solver + sage: p.variable_upper_bound(0, 5) + sage: p.col_bounds(0) (0.0, 5.0) """ raise NotImplementedError() @@ -1349,14 +1386,15 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variable() 0 - sage: p.col_bounds(0) # optional - Nonexistent_LP_solver + sage: p.col_bounds(0) (0.0, None) - sage: p.variable_lower_bound(0, 5) # optional - Nonexistent_LP_solver - sage: p.col_bounds(0) # optional - Nonexistent_LP_solver + sage: p.variable_lower_bound(0, 5) + sage: p.col_bounds(0) (5.0, None) """ raise NotImplementedError() @@ -1379,11 +1417,12 @@ cdef class GenericBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.solver_parameter("timelimit") # optional - Nonexistent_LP_solver - sage: p.solver_parameter("timelimit", 60) # optional - Nonexistent_LP_solver - sage: p.solver_parameter("timelimit") # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.solver_parameter("timelimit") + sage: p.solver_parameter("timelimit", 60) + sage: p.solver_parameter("timelimit") """ raise NotImplementedError() @@ -1400,19 +1439,20 @@ cdef class GenericBackend: EXAMPLES:: - sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: x = p.new_variable(nonnegative=True) # optional - Nonexistent_LP_solver - sage: p.add_constraint(-x[0] + x[1] <= 2) # optional - Nonexistent_LP_solver - sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) # optional - Nonexistent_LP_solver - sage: p.set_objective(5.5 * x[0] - 3 * x[1]) # optional - Nonexistent_LP_solver - sage: b = p.get_backend() # optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p = MixedIntegerLinearProgram(maximization=True, + ....: solver="Nonexistent_LP_solver") + sage: x = p.new_variable(nonnegative=True) + sage: p.add_constraint(-x[0] + x[1] <= 2) + sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) + sage: p.set_objective(5.5 * x[0] - 3 * x[1]) + sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here - sage: b.solve() # optional - Nonexistent_LP_solver + sage: b.solve() 0 - sage: b.is_variable_basic(0) # optional - Nonexistent_LP_solver + sage: b.is_variable_basic(0) True - sage: b.is_variable_basic(1) # optional - Nonexistent_LP_solver + sage: b.is_variable_basic(1) False """ raise NotImplementedError() @@ -1430,19 +1470,20 @@ cdef class GenericBackend: EXAMPLES:: - sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: x = p.new_variable(nonnegative=True) # optional - Nonexistent_LP_solver - sage: p.add_constraint(-x[0] + x[1] <= 2) # optional - Nonexistent_LP_solver - sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) # optional - Nonexistent_LP_solver - sage: p.set_objective(5.5 * x[0] - 3 * x[1]) # optional - Nonexistent_LP_solver - sage: b = p.get_backend() # optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p = MixedIntegerLinearProgram(maximization=True, + ....: solver="Nonexistent_LP_solver") + sage: x = p.new_variable(nonnegative=True) + sage: p.add_constraint(-x[0] + x[1] <= 2) + sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) + sage: p.set_objective(5.5 * x[0] - 3 * x[1]) + sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here - sage: b.solve() # optional - Nonexistent_LP_solver + sage: b.solve() 0 - sage: b.is_variable_nonbasic_at_lower_bound(0) # optional - Nonexistent_LP_solver + sage: b.is_variable_nonbasic_at_lower_bound(0) False - sage: b.is_variable_nonbasic_at_lower_bound(1) # optional - Nonexistent_LP_solver + sage: b.is_variable_nonbasic_at_lower_bound(1) True """ raise NotImplementedError() @@ -1460,19 +1501,20 @@ cdef class GenericBackend: EXAMPLES:: - sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: x = p.new_variable(nonnegative=True) # optional - Nonexistent_LP_solver - sage: p.add_constraint(-x[0] + x[1] <= 2) # optional - Nonexistent_LP_solver - sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) # optional - Nonexistent_LP_solver - sage: p.set_objective(5.5 * x[0] - 3 * x[1]) # optional - Nonexistent_LP_solver - sage: b = p.get_backend() # optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p = MixedIntegerLinearProgram(maximization=True, + ....: solver="Nonexistent_LP_solver") + sage: x = p.new_variable(nonnegative=True) + sage: p.add_constraint(-x[0] + x[1] <= 2) + sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) + sage: p.set_objective(5.5 * x[0] - 3 * x[1]) + sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here - sage: b.solve() # optional - Nonexistent_LP_solver + sage: b.solve() 0 - sage: b.is_slack_variable_basic(0) # optional - Nonexistent_LP_solver + sage: b.is_slack_variable_basic(0) True - sage: b.is_slack_variable_basic(1) # optional - Nonexistent_LP_solver + sage: b.is_slack_variable_basic(1) False """ raise NotImplementedError() @@ -1490,19 +1532,20 @@ cdef class GenericBackend: EXAMPLES:: - sage: p = MixedIntegerLinearProgram(maximization=True,\ - solver="Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: x = p.new_variable(nonnegative=True) # optional - Nonexistent_LP_solver - sage: p.add_constraint(-x[0] + x[1] <= 2) # optional - Nonexistent_LP_solver - sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) # optional - Nonexistent_LP_solver - sage: p.set_objective(5.5 * x[0] - 3 * x[1]) # optional - Nonexistent_LP_solver - sage: b = p.get_backend() # optional - Nonexistent_LP_solver + sage: # optional - nonexistent_lp_solver + sage: p = MixedIntegerLinearProgram(maximization=True, + ....: solver="Nonexistent_LP_solver") + sage: x = p.new_variable(nonnegative=True) + sage: p.add_constraint(-x[0] + x[1] <= 2) + sage: p.add_constraint(8 * x[0] + 2 * x[1] <= 17) + sage: p.set_objective(5.5 * x[0] - 3 * x[1]) + sage: b = p.get_backend() sage: # Backend-specific commands to instruct solver to use simplex method here - sage: b.solve() # optional - Nonexistent_LP_solver + sage: b.solve() 0 - sage: b.is_slack_variable_nonbasic_at_lower_bound(0) # optional - Nonexistent_LP_solver + sage: b.is_slack_variable_nonbasic_at_lower_bound(0) False - sage: b.is_slack_variable_nonbasic_at_lower_bound(1) # optional - Nonexistent_LP_solver + sage: b.is_slack_variable_nonbasic_at_lower_bound(1) True """ raise NotImplementedError() @@ -1552,20 +1595,20 @@ def default_mip_solver(solver=None): - ``solver`` -- one of the following: - - a string indicating one of the available solvers - (see :class:`MixedIntegerLinearProgram`); + - a string indicating one of the available solvers + (see :class:`MixedIntegerLinearProgram`); - - a callable (typically a subclass of - :class:`sage.numerical.backends.generic_backend.GenericBackend`); + - a callable (typically a subclass of + :class:`sage.numerical.backends.generic_backend.GenericBackend`); - - ``None`` (default), in which case the current default solver - is returned; this is either a string or a callable. + - ``None`` (default), in which case the current default solver + is returned; this is either a string or a callable. OUTPUT: This function returns the current default solver's name if ``solver = None`` (default). Otherwise, it sets the default solver to the one given. If this - solver does not exist, or is not available, a ``ValueError`` exception is + solver does not exist, or is not available, a :class:`ValueError` exception is raised. EXAMPLES:: @@ -1677,7 +1720,8 @@ def default_mip_solver(solver=None): else: raise ValueError("'solver' should be set to 'GLPK', 'Coin', 'CPLEX', 'CVXOPT', 'CVXPY', 'Gurobi', 'PPL', 'SCIP', 'InteractiveLP', a callable, or None.") -cpdef GenericBackend get_solver(constraint_generation = False, solver = None, base_ring = None) noexcept: + +cpdef GenericBackend get_solver(constraint_generation=False, solver=None, base_ring=None) noexcept: """ Return a solver according to the given preferences @@ -1685,22 +1729,22 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None, ba - ``solver`` -- one of the following: - - a string indicating one of the available solvers - (see :class:`MixedIntegerLinearProgram`); + - a string indicating one of the available solvers + (see :class:`MixedIntegerLinearProgram`); - - ``None`` (default), in which case the default solver is used - (see :func:`default_mip_solver`); + - ``None`` (default), in which case the default solver is used + (see :func:`default_mip_solver`); - - or a callable (such as a class), in which case it is called, - and its result is returned. + - or a callable (such as a class), in which case it is called, + and its result is returned. - ``base_ring`` -- If not ``None``, request a solver that works over this - (ordered) field. If ``base_ring`` is not a field, its fraction field - is used. + (ordered) field. If ``base_ring`` is not a field, its fraction field + is used. - For example, is ``base_ring=ZZ`` is provided, the solver will work over - the rational numbers. This is unrelated to whether variables are - constrained to be integers or not. + For example, is ``base_ring=ZZ`` is provided, the solver will work over + the rational numbers. This is unrelated to whether variables are + constrained to be integers or not. - ``constraint_generation`` -- Only used when ``solver=None``. @@ -1728,21 +1772,23 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None, ba <...sage.numerical.backends.ppl_backend.PPLBackend...> sage: p.base_ring() Rational Field - sage: p = get_solver(base_ring=AA); p # optional - sage.rings.number_field + sage: p = get_solver(base_ring=AA); p # needs sage.rings.number_field <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...> - sage: p.base_ring() # optional - sage.rings.number_field + sage: p.base_ring() # needs sage.rings.number_field Algebraic Real Field - sage: d = polytopes.dodecahedron() # optional - sage.rings.number_field - sage: p = get_solver(base_ring=d.base_ring()); p # optional - sage.rings.number_field + + sage: # needs sage.groups sage.rings.number_field + sage: d = polytopes.dodecahedron() + sage: p = get_solver(base_ring=d.base_ring()); p <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...> - sage: p.base_ring() # optional - sage.rings.number_field + sage: p.base_ring() Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - sage: p = get_solver(solver='InteractiveLP', base_ring=QQ); p # optional - sage.rings.number_field + sage: p = get_solver(solver='InteractiveLP', base_ring=QQ); p <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...> - sage: p.base_ring() # optional - sage.rings.number_field + sage: p.base_ring() Rational Field - Passing a callable as the 'solver':: + Passing a callable as the ``solver``:: sage: from sage.numerical.backends.glpk_backend import GLPKBackend sage: p = get_solver(solver=GLPKBackend); p diff --git a/src/sage/numerical/backends/generic_sdp_backend.pyx b/src/sage/numerical/backends/generic_sdp_backend.pyx index bad0e3511e2..45bfde5f89b 100644 --- a/src/sage/numerical/backends/generic_sdp_backend.pyx +++ b/src/sage/numerical/backends/generic_sdp_backend.pyx @@ -71,19 +71,20 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p.add_variable() 0 - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p.ncols() 1 - sage: p.add_variable(name='x',obj=1.0) # optional - Nonexistent_LP_solver + sage: p.add_variable(name='x', obj=1.0) 3 - sage: p.col_name(3) # optional - Nonexistent_LP_solver + sage: p.col_name(3) 'x' - sage: p.objective_coefficient(3) # optional - Nonexistent_LP_solver + sage: p.objective_coefficient(3) 1.0 """ raise NotImplementedError() @@ -107,15 +108,16 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p.add_variables(5) 4 - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p.ncols() 5 - sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b']) # optional - Nonexistent_LP_solver + sage: p.add_variables(2, lower_bound=-2.0, integer=True, names=['a','b']) 6 """ raise NotImplementedError() @@ -126,19 +128,20 @@ cdef class GenericSDPBackend: INPUT: - - ``sense`` (integer) : + - ``sense`` (integer): - * +1 => Maximization - * -1 => Minimization + * `+1` => Maximization + * `-1` => Minimization EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.is_maximization() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.is_maximization() True - sage: p.set_sense(-1) # optional - Nonexistent_LP_solver - sage: p.is_maximization() # optional - Nonexistent_LP_solver + sage: p.set_sense(-1) + sage: p.is_maximization() False """ raise NotImplementedError() @@ -156,14 +159,15 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variable() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variable() 1 - sage: p.objective_coefficient(0) # optional - Nonexistent_LP_solver + sage: p.objective_coefficient(0) 0.0 - sage: p.objective_coefficient(0,2) # optional - Nonexistent_LP_solver - sage: p.objective_coefficient(0) # optional - Nonexistent_LP_solver + sage: p.objective_coefficient(0,2) + sage: p.objective_coefficient(0) 2.0 """ raise NotImplementedError() @@ -181,12 +185,13 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 5 - sage: p.set_objective([1, 1, 2, 1, 3]) # optional - Nonexistent_LP_solver - sage: [p.objective_coefficient(x) for x in range(5)] # optional - Nonexistent_LP_solver + sage: p.set_objective([1, 1, 2, 1, 3]) + sage: [p.objective_coefficient(x) for x in range(5)] [1.0, 1.0, 2.0, 1.0, 3.0] Constants in the objective function are respected. @@ -212,17 +217,18 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 4 - sage: p.add_linear_constraint(zip(range(5), range(5)), 2.0, 2.0) # optional - Nonexistent_LP_solver - sage: p.row(0) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint(zip(range(5), range(5)), 2.0, 2.0) + sage: p.row(0) ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0]) # optional - Nonexistent_LP_solver - sage: p.row_bounds(0) # optional - Nonexistent_LP_solver + sage: p.row_bounds(0) (2.0, 2.0) - sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo') # optional - Nonexistent_LP_solver - sage: p.row_name(-1) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint( zip(range(5), range(5)), 1.0, 1.0, name='foo') + sage: p.row_name(-1) "foo" """ raise NotImplementedError() @@ -244,14 +250,15 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 5 - sage: p.add_linear_constraints(5, None, 2) # optional - Nonexistent_LP_solver - sage: p.row(4) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraints(5, None, 2) + sage: p.row(4) ([], []) - sage: p.row_bounds(4) # optional - Nonexistent_LP_solver + sage: p.row_bounds(4) (None, 2.0) """ raise NotImplementedError() @@ -262,20 +269,21 @@ cdef class GenericSDPBackend: .. NOTE:: - This method raises ``SDPSolverException`` exceptions when + This method raises :class:`SDPSolverException` exceptions when the solution cannot be computed for any reason (none exists, or the LP solver was not able to find it, etc...) EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_linear_constraints(5, 0, None) # optional - Nonexistent_LP_solver - sage: p.add_col(range(5), range(5)) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_linear_constraints(5, 0, None) + sage: p.add_col(range(5), range(5)) + sage: p.solve() 0 - sage: p.objective_coefficient(0,1) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.objective_coefficient(0,1) + sage: p.solve() Traceback (most recent call last): ... SDPSolverException: ... @@ -292,22 +300,22 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(2) 2 - sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) # optional - Nonexistent_LP_solver - sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint([(0,1), (1,2)], None, 3) + sage: p.set_objective([2, 5]) + sage: p.solve() 0 - sage: p.get_objective_value() # optional - Nonexistent_LP_solver + sage: p.get_objective_value() 7.5 - sage: p.get_variable_value(0) # optional - Nonexistent_LP_solver + sage: p.get_variable_value(0) 0.0 - sage: p.get_variable_value(1) # optional - Nonexistent_LP_solver + sage: p.get_variable_value(1) 1.5 """ - raise NotImplementedError() cpdef get_variable_value(self, int variable) noexcept: @@ -320,19 +328,20 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(2) 2 - sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) # optional - Nonexistent_LP_solver - sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint([(0,1), (1, 2)], None, 3) + sage: p.set_objective([2, 5]) + sage: p.solve() 0 - sage: p.get_objective_value() # optional - Nonexistent_LP_solver + sage: p.get_objective_value() 7.5 - sage: p.get_variable_value(0) # optional - Nonexistent_LP_solver + sage: p.get_variable_value(0) 0.0 - sage: p.get_variable_value(1) # optional - Nonexistent_LP_solver + sage: p.get_variable_value(1) 1.5 """ @@ -344,13 +353,14 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.ncols() 0 - sage: p.add_variables(2) # optional - Nonexistent_LP_solver + sage: p.add_variables(2) 2 - sage: p.ncols() # optional - Nonexistent_LP_solver + sage: p.ncols() 2 """ @@ -362,15 +372,15 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.nrows() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.nrows() 0 - sage: p.add_linear_constraints(2, 2.0, None) # optional - Nonexistent_LP_solver - sage: p.nrows() # optional - Nonexistent_LP_solver + sage: p.add_linear_constraints(2, 2.0, None) + sage: p.nrows() 2 """ - raise NotImplementedError() cpdef bint is_maximization(self) noexcept: @@ -379,12 +389,13 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.is_maximization() # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.is_maximization() True - sage: p.set_sense(-1) # optional - Nonexistent_LP_solver - sage: p.is_maximization() # optional - Nonexistent_LP_solver + sage: p.set_sense(-1) + sage: p.is_maximization() False """ raise NotImplementedError() @@ -400,10 +411,11 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.problem_name("There once was a french fry") # optional - Nonexistent_LP_solver - sage: print(p.problem_name()) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.problem_name("There once was a french fry") + sage: print(p.problem_name()) There once was a french fry """ @@ -426,20 +438,19 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variables(5) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variables(5) 5 - sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) # optional - Nonexistent_LP_solver - sage: p.row(0) # optional - Nonexistent_LP_solver + sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) + sage: p.row(0) ([4, 3, 2, 1], [4.0, 3.0, 2.0, 1.0]) - sage: p.row_bounds(0) # optional - Nonexistent_LP_solver + sage: p.row_bounds(0) (2.0, 2.0) """ raise NotImplementedError() - - cpdef row_name(self, int index) noexcept: """ Return the ``index`` th row name @@ -450,10 +461,11 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_linear_constraints(1, 2, None, name="Empty constraint 1") # optional - Nonexistent_LP_solver - sage: p.row_name(0) # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_linear_constraints(1, 2, None, name="Empty constraint 1") + sage: p.row_name(0) 'Empty constraint 1' """ @@ -472,11 +484,12 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.add_variable(name="I am a variable") # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.add_variable(name="I am a variable") 1 - sage: p.col_name(0) # optional - Nonexistent_LP_solver + sage: p.col_name(0) 'I am a variable' """ raise NotImplementedError() @@ -495,24 +508,25 @@ cdef class GenericSDPBackend: EXAMPLES:: - sage: p = SemidefiniteProgram(maximization = False,solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: x = p.new_variable() # optional - Nonexistent_LP_solver - sage: p.set_objective(x[0] - x[1]) # optional - Nonexistent_LP_solver - sage: a1 = matrix([[1, 2.], [2., 3.]]) # optional - Nonexistent_LP_solver - sage: a2 = matrix([[3, 4.], [4., 5.]]) # optional - Nonexistent_LP_solver - sage: a3 = matrix([[5, 6.], [6., 7.]]) # optional - Nonexistent_LP_solver - sage: b1 = matrix([[1, 1.], [1., 1.]]) # optional - Nonexistent_LP_solver - sage: b2 = matrix([[2, 2.], [2., 2.]]) # optional - Nonexistent_LP_solver - sage: b3 = matrix([[3, 3.], [3., 3.]]) # optional - Nonexistent_LP_solver - sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) # optional - Nonexistent_LP_solver - sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver # tol ??? + sage: # optional - nonexistent_lp_solver + sage: p = SemidefiniteProgram(maximization=False, solver="Nonexistent_LP_solver") + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1]) + sage: a1 = matrix([[1, 2.], [2., 3.]]) + sage: a2 = matrix([[3, 4.], [4., 5.]]) + sage: a3 = matrix([[5, 6.], [6., 7.]]) + sage: b1 = matrix([[1, 1.], [1., 1.]]) + sage: b2 = matrix([[2, 2.], [2., 2.]]) + sage: b3 = matrix([[3, 3.], [3., 3.]]) + sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) + sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) + sage: p.solve() -3.0 - sage: B=p.get_backend() # optional - Nonexistent_LP_solver - sage: x=p.get_values(x).values() # optional - Nonexistent_LP_solver - sage: -(a3*B.dual_variable(0)).trace()-(b3*B.dual_variable(1)).trace() # optional - Nonexistent_LP_solver # tol ??? + sage: B = p.get_backend() + sage: x = p.get_values(x).values() + sage: -(a3*B.dual_variable(0)).trace()-(b3*B.dual_variable(1)).trace() -3.0 - sage: g = sum((B.slack(j)*B.dual_variable(j)).trace() for j in range(2)); g # optional - Nonexistent_LP_solver # tol ??? + sage: g = sum((B.slack(j)*B.dual_variable(j)).trace() for j in range(2)); g 0.0 TESTS:: @@ -541,27 +555,28 @@ cdef class GenericSDPBackend: EXAMPLES:: - sage: p = SemidefiniteProgram(maximization = False,solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: x = p.new_variable() # optional - Nonexistent_LP_solver - sage: p.set_objective(x[0] - x[1]) # optional - Nonexistent_LP_solver - sage: a1 = matrix([[1, 2.], [2., 3.]]) # optional - Nonexistent_LP_solver - sage: a2 = matrix([[3, 4.], [4., 5.]]) # optional - Nonexistent_LP_solver - sage: a3 = matrix([[5, 6.], [6., 7.]]) # optional - Nonexistent_LP_solver - sage: b1 = matrix([[1, 1.], [1., 1.]]) # optional - Nonexistent_LP_solver - sage: b2 = matrix([[2, 2.], [2., 2.]]) # optional - Nonexistent_LP_solver - sage: b3 = matrix([[3, 3.], [3., 3.]]) # optional - Nonexistent_LP_solver - sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) # optional - Nonexistent_LP_solver - sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) # optional - Nonexistent_LP_solver - sage: p.solve() # optional - Nonexistent_LP_solver # tol ??? + sage: # optional - nonexistent_lp_solver + sage: p = SemidefiniteProgram(maximization=False, solver="Nonexistent_LP_solver") + sage: x = p.new_variable() + sage: p.set_objective(x[0] - x[1]) + sage: a1 = matrix([[1, 2.], [2., 3.]]) + sage: a2 = matrix([[3, 4.], [4., 5.]]) + sage: a3 = matrix([[5, 6.], [6., 7.]]) + sage: b1 = matrix([[1, 1.], [1., 1.]]) + sage: b2 = matrix([[2, 2.], [2., 2.]]) + sage: b3 = matrix([[3, 3.], [3., 3.]]) + sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) + sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) + sage: p.solve() -3.0 - sage: B=p.get_backend() # optional - Nonexistent_LP_solver - sage: B1 = B.slack(1); B1 # optional - Nonexistent_LP_solver # tol ??? + sage: B = p.get_backend() + sage: B1 = B.slack(1); B1 [0.0 0.0] [0.0 0.0] - sage: B1.is_positive_definite() # optional - Nonexistent_LP_solver + sage: B1.is_positive_definite() True - sage: x = p.get_values(x).values() # optional - Nonexistent_LP_solver - sage: x[0]*b1 + x[1]*b2 - b3 + B1 # optional - Nonexistent_LP_solver # tol ??? + sage: x = p.get_values(x).values() + sage: x[0]*b1 + x[1]*b2 - b3 + B1 [0.0 0.0] [0.0 0.0] @@ -593,11 +608,12 @@ cdef class GenericSDPBackend: EXAMPLES:: + sage: # optional - nonexistent_lp_solver sage: from sage.numerical.backends.generic_sdp_backend import get_solver - sage: p = get_solver(solver = "Nonexistent_LP_solver") # optional - Nonexistent_LP_solver - sage: p.solver_parameter("timelimit") # optional - Nonexistent_LP_solver - sage: p.solver_parameter("timelimit", 60) # optional - Nonexistent_LP_solver - sage: p.solver_parameter("timelimit") # optional - Nonexistent_LP_solver + sage: p = get_solver(solver="Nonexistent_LP_solver") + sage: p.solver_parameter("timelimit") + sage: p.solver_parameter("timelimit", 60) + sage: p.solver_parameter("timelimit") """ raise NotImplementedError() @@ -613,15 +629,15 @@ def default_sdp_solver(solver=None): - ``solver`` -- one of the following: - - the string ``"CVXOPT"``, to make the use of the CVXOPT solver - (see the `CVXOPT `_ web site) the default; + - the string ``"CVXOPT"``, to make the use of the CVXOPT solver + (see the `CVXOPT `_ web site) the default; - - a subclass of - :class:`sage.numerical.backends.generic_sdp_backend.GenericSDPBackend`, - to make it the default; or + - a subclass of + :class:`sage.numerical.backends.generic_sdp_backend.GenericSDPBackend`, + to make it the default; or - - ``None`` (default), in which case the current default solver - (a string or a class) is returned. + - ``None`` (default), in which case the current default solver + (a string or a class) is returned. OUTPUT: @@ -694,14 +710,14 @@ cpdef GenericSDPBackend get_solver(solver=None, base_ring=None) noexcept: - ``solver`` -- one of the following: - - the string ``"CVXOPT"``, designating the use of the CVXOPT solver - (see the `CVXOPT `_ web site); + - the string ``"CVXOPT"``, designating the use of the CVXOPT solver + (see the `CVXOPT `_ web site); - - a subclass of - :class:`sage.numerical.backends.generic_sdp_backend.GenericSDPBackend`; + - a subclass of + :class:`sage.numerical.backends.generic_sdp_backend.GenericSDPBackend`; - - ``None`` (default), in which case the default solver is used (see - :func:`default_sdp_solver`); + - ``None`` (default), in which case the default solver is used (see + :func:`default_sdp_solver`); .. SEEALSO:: diff --git a/src/sage/numerical/backends/glpk_backend.pyx b/src/sage/numerical/backends/glpk_backend.pyx index 0fa5c2d3b98..77cab0ff1b5 100644 --- a/src/sage/numerical/backends/glpk_backend.pyx +++ b/src/sage/numerical/backends/glpk_backend.pyx @@ -1097,6 +1097,7 @@ cdef class GLPKBackend(GenericBackend): the result is not optimal. To do this, we try to compute the maximum number of disjoint balls (of diameter 1) in a hypercube:: + sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) sage: p = MixedIntegerLinearProgram(solver="GLPK") sage: p.solver_parameter("mip_gap_tolerance",100) @@ -1110,6 +1111,7 @@ cdef class GLPKBackend(GenericBackend): Same, now with a time limit:: + sage: # needs sage.graphs sage: p.solver_parameter("mip_gap_tolerance",1) sage: p.solver_parameter("timelimit",3.0) sage: p.solve() # rel tol 100 @@ -1197,6 +1199,7 @@ cdef class GLPKBackend(GenericBackend): EXAMPLES:: + sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) sage: p = MixedIntegerLinearProgram(solver="GLPK") sage: p.solver_parameter("mip_gap_tolerance",100) @@ -1231,6 +1234,7 @@ cdef class GLPKBackend(GenericBackend): EXAMPLES:: + sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) sage: p = MixedIntegerLinearProgram(solver="GLPK") sage: p.solver_parameter("mip_gap_tolerance",100) @@ -1250,7 +1254,7 @@ cdef class GLPKBackend(GenericBackend): Just make sure that the variable *has* been defined, and is not just undefined:: - sage: backend.get_relative_objective_gap() > 1 + sage: backend.get_relative_objective_gap() > 1 # needs sage.graphs True """ return self.search_tree_data.mip_gap diff --git a/src/sage/numerical/backends/glpk_graph_backend.pyx b/src/sage/numerical/backends/glpk_graph_backend.pyx index dcc6425d8de..90431f8a481 100644 --- a/src/sage/numerical/backends/glpk_graph_backend.pyx +++ b/src/sage/numerical/backends/glpk_graph_backend.pyx @@ -1,3 +1,4 @@ +# sage.doctest: needs sage.graphs """ GLPK Backend for access to GLPK graph functions diff --git a/src/sage/numerical/backends/interactivelp_backend.pyx b/src/sage/numerical/backends/interactivelp_backend.pyx index 665631f19de..3062a29eb1f 100644 --- a/src/sage/numerical/backends/interactivelp_backend.pyx +++ b/src/sage/numerical/backends/interactivelp_backend.pyx @@ -53,17 +53,18 @@ cdef class InteractiveLPBackend: This backend can work with irrational algebraic numbers:: - sage: poly = polytopes.dodecahedron(base_ring=AA) # optional - sage.rings.number_field - sage: lp, x = poly.to_linear_program(solver='InteractiveLP', return_variable=True) # optional - sage.rings.number_field - sage: lp.set_objective(x[0] + x[1] + x[2]) # optional - sage.rings.number_field - sage: lp.solve() # optional - sage.rings.number_field + sage: # needs sage.rings.number_field + sage: poly = polytopes.dodecahedron(base_ring=AA) + sage: lp, x = poly.to_linear_program(solver='InteractiveLP', return_variable=True) + sage: lp.set_objective(x[0] + x[1] + x[2]) + sage: lp.solve() 2.291796067500631? - sage: lp.get_values(x[0], x[1], x[2]) # optional - sage.rings.number_field + sage: lp.get_values(x[0], x[1], x[2]) [0.763932022500211?, 0.763932022500211?, 0.763932022500211?] - sage: lp.set_objective(x[0] - x[1] - x[2]) # optional - sage.rings.number_field - sage: lp.solve() # optional - sage.rings.number_field + sage: lp.set_objective(x[0] - x[1] - x[2]) + sage: lp.solve() 2.291796067500631? - sage: lp.get_values(x[0], x[1], x[2]) # optional - sage.rings.number_field + sage: lp.get_values(x[0], x[1], x[2]) [0.763932022500211?, -0.763932022500211?, -0.763932022500211?] """ diff --git a/src/sage/numerical/backends/ppl_backend.pyx b/src/sage/numerical/backends/ppl_backend.pyx index f437527e42c..f3ba2f97236 100644 --- a/src/sage/numerical/backends/ppl_backend.pyx +++ b/src/sage/numerical/backends/ppl_backend.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - pplpy """ PPL Backend @@ -61,7 +62,7 @@ cdef class PPLBackend(GenericBackend): Raise an error if a ``base_ring`` is requested that is not supported:: - sage: p = MixedIntegerLinearProgram(solver = "PPL", base_ring=AA) + sage: p = MixedIntegerLinearProgram(solver="PPL", base_ring=AA) # needs sage.rings.number_field Traceback (most recent call last): ... TypeError: The PPL backend only supports rational data. diff --git a/src/sage/numerical/gauss_legendre.pyx b/src/sage/numerical/gauss_legendre.pyx index 269727c1fdd..81bb5f36af5 100644 --- a/src/sage/numerical/gauss_legendre.pyx +++ b/src/sage/numerical/gauss_legendre.pyx @@ -79,11 +79,11 @@ def nodes_uncached(degree, prec): sage: from sage.numerical.gauss_legendre import nodes_uncached sage: L1 = nodes_uncached(24, 53) - sage: P = RR['x'](sage.functions.orthogonal_polys.legendre_P(24, x)) - sage: Pdif = P.diff() - sage: L2 = [((r + 1)/2, 1/(1 - r^2)/Pdif(r)^2) + sage: P = RR['x'](sage.functions.orthogonal_polys.legendre_P(24, x)) # needs sage.symbolic + sage: Pdif = P.diff() # needs sage.symbolic + sage: L2 = [((r + 1)/2, 1/(1 - r^2)/Pdif(r)^2) # needs sage.symbolic ....: for r, _ in RR['x'](P).roots()] - sage: all((a[0] - b[0]).abs() < 1e-15 and (a[1] - b[1]).abs() < 1e-9 + sage: all((a[0] - b[0]).abs() < 1e-15 and (a[1] - b[1]).abs() < 1e-9 # needs sage.symbolic ....: for a, b in zip(L1, L2)) True @@ -188,11 +188,11 @@ def nodes(degree, prec): sage: from sage.numerical.gauss_legendre import nodes sage: L1 = nodes(24, 53) - sage: P = RR['x'](sage.functions.orthogonal_polys.legendre_P(24, x)) - sage: Pdif = P.diff() - sage: L2 = [((r + 1)/2, 1/(1 - r^2)/Pdif(r)^2) + sage: P = RR['x'](sage.functions.orthogonal_polys.legendre_P(24, x)) # needs sage.symbolic + sage: Pdif = P.diff() # needs sage.symbolic + sage: L2 = [((r + 1)/2, 1/(1 - r^2)/Pdif(r)^2) # needs sage.symbolic ....: for r, _ in RR['x'](P).roots()] - sage: all((a[0] - b[0]).abs() < 1e-15 and (a[1] - b[1]).abs() < 1e-9 + sage: all((a[0] - b[0]).abs() < 1e-15 and (a[1] - b[1]).abs() < 1e-9 # needs sage.symbolic ....: for a, b in zip(L1, L2)) True @@ -343,8 +343,8 @@ def integrate_vector(f, prec, epsilon=None): sage: epsilon = K(2^(-prec + 4)) sage: f = lambda t:V((1 + t^2, 1/(1 + t^2))) sage: I = integrate_vector(f, prec, epsilon=epsilon) - sage: J = V((4/3, pi/4)) - sage: max(c.abs() for c in (I - J)) < epsilon + sage: J = V((4/3, pi/4)) # needs sage.symbolic + sage: max(c.abs() for c in (I - J)) < epsilon # needs sage.symbolic True We can also use complex-valued integrands:: @@ -354,10 +354,10 @@ def integrate_vector(f, prec, epsilon=None): sage: K = ComplexField(prec) sage: V = VectorSpace(K, 2) sage: epsilon = Kreal(2^(-prec + 4)) - sage: f = lambda t: V((t, K(exp(2*pi*t*K.0)))) - sage: I = integrate_vector(f, prec, epsilon=epsilon) + sage: f = lambda t: V((t, K(exp(2*pi*t*K.0)))) # needs sage.symbolic + sage: I = integrate_vector(f, prec, epsilon=epsilon) # needs sage.symbolic sage: J = V((1/2, 0)) - sage: max(c.abs() for c in (I - J)) < epsilon + sage: max(c.abs() for c in (I - J)) < epsilon # needs sage.symbolic True """ results = [] diff --git a/src/sage/numerical/interactive_simplex_method.py b/src/sage/numerical/interactive_simplex_method.py index 184a2c8a434..c2a10d6a4f6 100644 --- a/src/sage/numerical/interactive_simplex_method.py +++ b/src/sage/numerical/interactive_simplex_method.py @@ -64,7 +64,7 @@ Since it has only two variables, we can solve it graphically:: - sage: P.plot() # optional - sage.plot + sage: P.plot() # needs sage.plot Graphics object consisting of 19 graphics primitives @@ -298,9 +298,9 @@ def _latex_product(coefficients, variables, sage: from sage.numerical.interactive_simplex_method import \ ....: _latex_product - sage: var("x, y") + sage: var("x, y") # needs sage.symbolic (x, y) - sage: print(_latex_product([-1, 3], [x, y])) + sage: print(_latex_product([-1, 3], [x, y])) # needs sage.symbolic - \mspace{-6mu}&\mspace{-6mu} x \mspace{-6mu}&\mspace{-6mu} + \mspace{-6mu}&\mspace{-6mu} 3 y """ entries = [] @@ -1534,19 +1534,19 @@ def plot(self, *args, **kwds): sage: b = (1000, 1500) sage: c = (10, 5) sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") - sage: p = P.plot() # optional - sage.plot - sage: p.show() # optional - sage.plot + sage: p = P.plot() # needs sage.plot + sage: p.show() # needs sage.plot In this case the plot works better with the following axes ranges:: - sage: p = P.plot(0, 1000, 0, 1500) # optional - sage.plot - sage: p.show() # optional - sage.plot + sage: p = P.plot(0, 1000, 0, 1500) # needs sage.plot + sage: p.show() # needs sage.plot TESTS: We check that zero objective can be dealt with:: - sage: InteractiveLPProblem(A, b, (0, 0), ["C", "B"], variable_type=">=").plot() # optional - sage.plot + sage: InteractiveLPProblem(A, b, (0, 0), ["C", "B"], variable_type=">=").plot() # needs sage.plot Graphics object consisting of 8 graphics primitives """ FP = self.plot_feasible_set(*args, **kwds) @@ -1611,13 +1611,13 @@ def plot_feasible_set(self, xmin=None, xmax=None, ymin=None, ymax=None, sage: b = (1000, 1500) sage: c = (10, 5) sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=") - sage: p = P.plot_feasible_set() # optional - sage.plot - sage: p.show() # optional - sage.plot + sage: p = P.plot_feasible_set() # needs sage.plot + sage: p.show() # needs sage.plot In this case the plot works better with the following axes ranges:: - sage: p = P.plot_feasible_set(0, 1000, 0, 1500) # optional - sage.plot - sage: p.show() # optional - sage.plot + sage: p = P.plot_feasible_set(0, 1000, 0, 1500) # needs sage.plot + sage: p.show() # needs sage.plot """ if self.n() != 2: raise ValueError("only problems with 2 variables can be plotted") diff --git a/src/sage/numerical/knapsack.py b/src/sage/numerical/knapsack.py index 3a5c14474e8..3f80f517998 100644 --- a/src/sage/numerical/knapsack.py +++ b/src/sage/numerical/knapsack.py @@ -408,6 +408,7 @@ def is_superincreasing(self, seq=None): The sequence must contain only integers:: + sage: # needs sage.symbolic sage: from sage.numerical.knapsack import Superincreasing sage: L = [1.0, 2.1, pi, 21, 69, 189, 376, 919] sage: Superincreasing(L).is_superincreasing() diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 71dc66360da..1e6e6caa7bd 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -315,6 +315,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Computation of a maximum stable set in Petersen's graph:: + sage: # needs sage.graphs sage: g = graphs.PetersenGraph() sage: p = MixedIntegerLinearProgram(maximization=True, solver='GLPK') sage: b = p.new_variable(binary=True) @@ -659,13 +660,15 @@ cdef class MixedIntegerLinearProgram(SageObject): sage: p = MixedIntegerLinearProgram(solver='ppl') sage: p.base_ring() Rational Field - sage: from sage.rings.qqbar import AA # optional - sage.rings.number_field - sage: p = MixedIntegerLinearProgram(solver='InteractiveLP', base_ring=AA) # optional - sage.rings.number_field - sage: p.base_ring() # optional - sage.rings.number_field + sage: from sage.rings.qqbar import AA # needs sage.rings.number_field + sage: p = MixedIntegerLinearProgram(solver='InteractiveLP', base_ring=AA) # needs sage.rings.number_field + sage: p.base_ring() # needs sage.rings.number_field Algebraic Real Field - sage: d = polytopes.dodecahedron() # optional - sage.rings.number_field - sage: p = MixedIntegerLinearProgram(base_ring=d.base_ring()) # optional - sage.rings.number_field - sage: p.base_ring() # optional - sage.rings.number_field + + sage: # needs sage.groups sage.rings.number_field + sage: d = polytopes.dodecahedron() + sage: p = MixedIntegerLinearProgram(base_ring=d.base_ring()) + sage: p.base_ring() Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? """ return self._backend.base_ring() @@ -2629,6 +2632,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Computation of a maximum stable set in Petersen's graph:: + sage: # needs sage.graphs sage: g = graphs.PetersenGraph() sage: p = MixedIntegerLinearProgram(maximization=True, solver='GLPK') sage: b = p.new_variable(nonnegative=True) @@ -2823,14 +2827,15 @@ cdef class MixedIntegerLinearProgram(SageObject): are not recorded, and we can disable this feature providing an empty filename. This is currently working with CPLEX and Gurobi:: - sage: p = MixedIntegerLinearProgram(solver="CPLEX") # optional - CPLEX - sage: p.solver_parameter("logfile") # optional - CPLEX + sage: # optional - cplex + sage: p = MixedIntegerLinearProgram(solver="CPLEX") + sage: p.solver_parameter("logfile") '' - sage: p.solver_parameter("logfile", "/dev/null") # optional - CPLEX - sage: p.solver_parameter("logfile") # optional - CPLEX + sage: p.solver_parameter("logfile", "/dev/null") + sage: p.solver_parameter("logfile") '/dev/null' - sage: p.solver_parameter("logfile", '') # optional - CPLEX - sage: p.solver_parameter("logfile") # optional - CPLEX + sage: p.solver_parameter("logfile", '') + sage: p.solver_parameter("logfile") '' Solver-specific parameters: @@ -2983,6 +2988,7 @@ cdef class MixedIntegerLinearProgram(SageObject): EXAMPLES:: + sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) sage: p = MixedIntegerLinearProgram(solver="GLPK") sage: p.solver_parameter("mip_gap_tolerance",100) @@ -3017,6 +3023,7 @@ cdef class MixedIntegerLinearProgram(SageObject): EXAMPLES:: + sage: # needs sage.graphs sage: g = graphs.CubeGraph(9) sage: p = MixedIntegerLinearProgram(solver="GLPK") sage: p.solver_parameter("mip_gap_tolerance",100) @@ -3035,7 +3042,7 @@ cdef class MixedIntegerLinearProgram(SageObject): Just make sure that the variable *has* been defined, and is not just undefined:: - sage: p.get_relative_objective_gap() > 1 + sage: p.get_relative_objective_gap() > 1 # needs sage.graphs True """ return self._backend.get_relative_objective_gap() diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index f728b2ad89f..708d440a205 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -1,17 +1,17 @@ +# sage.doctest: optional - scipy """ Numerical Root Finding and Optimization AUTHOR: - William Stein (2007): initial version -- Nathann Cohen (2008) : Bin Packing +- Nathann Cohen (2008): Bin Packing Functions and Methods ---------------------- """ -from sage.misc.superseded import deprecation from sage.modules.free_module_element import vector from sage.rings.real_double import RDF @@ -171,6 +171,7 @@ def find_root(f, a, b, xtol=10e-13, rtol=2.0**-50, maxiter=100, full_output=Fals raise NotImplementedError("Brent's method failed to find a zero for f on the interval") return brentqRes + def find_local_maximum(f, a, b, tol=1.48e-08, maxfun=500): """ Numerically find a local maximum of the expression `f` on the interval @@ -191,7 +192,7 @@ def find_local_maximum(f, a, b, tol=1.48e-08, maxfun=500): (0.561096338191..., 0.8603335890...) sage: find_local_maximum(f, 0, 5, tol=0.1, maxfun=10) (0.561090323458..., 0.857926501456...) - sage: find_local_maximum(8*e^(-x)*sin(x) - 1, 0, 7) + sage: find_local_maximum(8*e^(-x)*sin(x) - 1, 0, 7) # needs sage.symbolic (1.579175535558..., 0.7853981...) """ try: @@ -201,6 +202,7 @@ def find_local_maximum(f, a, b, tol=1.48e-08, maxfun=500): minval, x = find_local_minimum(lambda z: -f(z), a=a, b=b, tol=tol, maxfun=maxfun) return -minval, x + def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): """ Numerically find a local minimum of the expression ``f`` on the @@ -215,7 +217,7 @@ def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): - ``f`` -- a function of at most one variable. - - ``a``, ``b`` -- endpoints of interval on which to minimize self. + - ``a``, ``b`` -- endpoints of interval on which to minimize `f`. - ``tol`` -- the convergence tolerance @@ -224,10 +226,10 @@ def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): OUTPUT: - - ``minval`` -- (float) the minimum value that self takes on in the + - ``minval`` -- (float) the minimum value that `f` takes on in the interval `[a,b]` - - ``x`` -- (float) the point at which self takes on the minimum value + - ``x`` -- (float) the point at which `f` takes on the minimum value EXAMPLES:: @@ -239,7 +241,7 @@ def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): (-3.28837136189098..., 3.42575079030572...) sage: find_local_minimum(f, 1, 5, tol=1e-2, maxfun=10) (-3.28837084598..., 3.4250840220...) - sage: show(plot(f, 0, 20)) + sage: show(plot(f, 0, 20)) # needs sage.plot sage: find_local_minimum(f, 1, 15) (-9.4772942594..., 9.5293344109...) @@ -248,12 +250,14 @@ def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): :: + sage: # needs sage.symbolic sage: f(x) = -x*sin(x^2) sage: find_local_minimum(f, -2.5, -1) (-2.182769784677722, -2.1945027498534686) Enlarging the interval returns a larger minimum:: + sage: # needs sage.symbolic sage: find_local_minimum(f, -2.5, 2) (-1.3076194129914434, 1.3552111405712108) @@ -262,9 +266,10 @@ def find_local_minimum(f, a, b, tol=1.48e-08, maxfun=500): numerics (observe the small number of decimal places that we actually test):: - sage: plot(f, (x,-2.5, -1)).ymin() + sage: # needs sage.plot sage.symbolic + sage: plot(f, (x, -2.5, -1)).ymin() -2.182... - sage: plot(f, (x,-2.5, 2)).ymin() + sage: plot(f, (x, -2.5, 2)).ymin() -2.182... ALGORITHM: @@ -318,15 +323,15 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", ``'default'`` (for Python functions, the simplex method is the default) (for symbolic functions bfgs is the default): - - ``'simplex'`` -- using the downhill simplex algorithm + - ``'simplex'`` -- using the downhill simplex algorithm - - ``'powell'`` -- use the modified Powell algorithm + - ``'powell'`` -- use the modified Powell algorithm - - ``'bfgs'`` -- (Broyden-Fletcher-Goldfarb-Shanno) requires gradient + - ``'bfgs'`` -- (Broyden-Fletcher-Goldfarb-Shanno) requires gradient - - ``'cg'`` -- (conjugate-gradient) requires gradient + - ``'cg'`` -- (conjugate-gradient) requires gradient - - ``'ncg'`` -- (newton-conjugate gradient) requires gradient and hessian + - ``'ncg'`` -- (newton-conjugate gradient) requires gradient and hessian - ``verbose`` -- (optional, default: False) print convergence message @@ -341,27 +346,27 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", Minimize a fourth order polynomial in three variables (see the :wikipedia:`Rosenbrock_function`):: - sage: vars = var('x y z') - sage: f = 100*(y-x^2)^2+(1-x)^2+100*(z-y^2)^2+(1-y)^2 - sage: minimize(f, [.1,.3,.4]) # abs tol 1e-6 + sage: vars = var('x y z') # needs sage.symbolic + sage: f = 100*(y-x^2)^2 + (1-x)^2 + 100*(z-y^2)^2 + (1-y)^2 # needs sage.symbolic + sage: minimize(f, [.1,.3,.4]) # abs tol 1e-6 # needs sage.symbolic (1.0, 1.0, 1.0) Try the newton-conjugate gradient method; the gradient and hessian are computed automatically:: - sage: minimize(f, [.1, .3, .4], algorithm="ncg") # abs tol 1e-6 + sage: minimize(f, [.1, .3, .4], algorithm="ncg") # abs tol 1e-6 # needs sage.symbolic (1.0, 1.0, 1.0) We get additional convergence information with the `verbose` option:: - sage: minimize(f, [.1, .3, .4], algorithm="ncg", verbose=True) + sage: minimize(f, [.1, .3, .4], algorithm="ncg", verbose=True) # needs sage.symbolic Optimization terminated successfully. ... (0.9999999..., 0.999999..., 0.999999...) Same example with just Python functions:: - sage: def rosen(x): # The Rosenbrock function + sage: def rosen(x): # The Rosenbrock function ....: return sum(100.0r*(x[1r:]-x[:-1r]**2.0r)**2.0r + (1r-x[:-1r])**2.0r) sage: minimize(rosen, [.1,.3,.4]) # abs tol 3e-5 (1.0, 1.0, 1.0) @@ -369,7 +374,8 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", Same example with a pure Python function and a Python function to compute the gradient:: - sage: def rosen(x): # The Rosenbrock function + sage: # needs numpy + sage: def rosen(x): # The Rosenbrock function ....: return sum(100.0r*(x[1r:]-x[:-1r]**2.0r)**2.0r + (1r-x[:-1r])**2.0r) sage: import numpy sage: from numpy import zeros @@ -382,7 +388,8 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", ....: der[0] = -400r*x[0r]*(x[1r]-x[0r]**2r) - 2r*(1r-x[0]) ....: der[-1] = 200r*(x[-1r]-x[-2r]**2r) ....: return der - sage: minimize(rosen, [.1,.3,.4], gradient=rosen_der, algorithm="bfgs") # abs tol 1e-6 + sage: minimize(rosen, [.1,.3,.4], gradient=rosen_der, # abs tol 1e-6 + ....: algorithm="bfgs") (1.0, 1.0, 1.0) """ from sage.structure.element import Expression @@ -434,7 +441,7 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) INPUT: - ``func`` -- Either a symbolic function, or a Python function whose - argument is a tuple with n components + argument is a tuple with `n` components - ``cons`` -- constraints. This should be either a function or list of functions that must be positive. Alternatively, the constraints can @@ -465,7 +472,6 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) `50x + 24y \leq 2400`, `30x + 33y \leq 2100`, `x \geq 45`, and `y \geq 5`:: - sage: y = var('y') sage: f = lambda p: -p[0]-p[1]+50 sage: c_1 = lambda p: p[0]-45 sage: c_2 = lambda p: p[1]-5 @@ -477,31 +483,35 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) Let's find a minimum of `\sin(xy)`:: - sage: x,y = var('x y') - sage: f(x,y) = sin(x*y) - sage: minimize_constrained(f, [(None,None),(4,10)],[5,5]) + sage: x,y = var('x y') # needs sage.symbolic + sage: f(x,y) = sin(x*y) # needs sage.symbolic + sage: minimize_constrained(f, [(None,None),(4,10)],[5,5]) # needs sage.symbolic (4.8..., 4.8...) Check if L-BFGS-B finds the same minimum:: - sage: minimize_constrained(f, [(None,None),(4,10)],[5,5], algorithm='l-bfgs-b') + sage: minimize_constrained(f, [(None,None),(4,10)],[5,5], # needs sage.symbolic + ....: algorithm='l-bfgs-b') (4.7..., 4.9...) Rosenbrock function (see the :wikipedia:`Rosenbrock_function`):: sage: from scipy.optimize import rosen, rosen_der - sage: minimize_constrained(rosen, [(-50,-10),(5,10)],[1,1],gradient=rosen_der,algorithm='l-bfgs-b') + sage: minimize_constrained(rosen, [(-50,-10),(5,10)],[1,1], + ....: gradient=rosen_der, algorithm='l-bfgs-b') (-10.0, 10.0) - sage: minimize_constrained(rosen, [(-50,-10),(5,10)],[1,1],algorithm='l-bfgs-b') + sage: minimize_constrained(rosen, [(-50,-10),(5,10)],[1,1], + ....: algorithm='l-bfgs-b') (-10.0, 10.0) TESTS: Check if :trac:`6592` is fixed:: + sage: # needs sage.symbolic sage: x, y = var('x y') sage: f(x,y) = (100 - x) + (1000 - y) - sage: c(x,y) = x + y - 479 # > 0 + sage: c(x,y) = x + y - 479 # > 0 sage: minimize_constrained(f, [c], [100, 300]) (805.985..., 1005.985...) sage: minimize_constrained(f, c, [100, 300]) @@ -510,6 +520,7 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) If ``func`` is symbolic, its minimizer should be in the same order as its arguments (:trac:`32511`):: + sage: # needs sage.symbolic sage: x,y = SR.var('x,y') sage: f(y,x) = x - y sage: c1(y,x) = x @@ -563,119 +574,6 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) return vector(RDF, min) -def linear_program(c, G, h, A=None, b=None, solver=None): - r""" - Solve the dual linear programs: - - - Minimize `c'x` subject to `Gx + s = h`, `Ax = b`, and `s \geq 0` where - `'` denotes transpose. - - - Maximize `-h'z - b'y` subject to `G'z + A'y + c = 0` and `z \geq 0`. - - This function is deprecated. Use :class:`MixedIntegerLinearProgram` instead. - - This function depends on the optional package ``cvxopt``. - - INPUT: - - - ``c`` -- a vector - - - ``G`` -- a matrix - - - ``h`` -- a vector - - - ``A`` -- a matrix - - - ``b`` --- a vector - - - ``solver`` (optional) --- solver to use. If None, the cvxopt's lp-solver - is used. If it is 'glpk', then glpk's solver - is used. - - These can be over any field that can be turned into a floating point - number. - - - OUTPUT: - - A dictionary ``sol`` with keys ``x``, ``s``, ``y``, ``z`` corresponding - to the variables above: - - - ``sol['x']`` -- the solution to the linear program - - - ``sol['s']`` -- the slack variables for the solution - - - ``sol['z']``, ``sol['y']`` -- solutions to the dual program - - - EXAMPLES: - - First, we minimize `-4x_1 - 5x_2` subject to `2x_1 + x_2 \leq 3`, - `x_1 + 2x_2 \leq 3`, `x_1 \geq 0`, and `x_2 \geq 0`:: - - sage: c=vector(RDF,[-4,-5]) - sage: G=matrix(RDF,[[2,1],[1,2],[-1,0],[0,-1]]) - sage: h=vector(RDF,[3,3,0,0]) - sage: sol=linear_program(c,G,h) # optional - cvxopt - doctest:warning... - DeprecationWarning: linear_program is deprecated; use MixedIntegerLinearProgram instead - See https://github.com/sagemath/sage/issues/32226 for details. - sage: sol['x'] # optional - cvxopt - (0.999..., 1.000...) - - Here we solve the same problem with 'glpk' interface to 'cvxopt':: - - sage: sol=linear_program(c,G,h,solver='glpk') # optional - cvxopt - GLPK Simplex Optimizer... - ... - OPTIMAL LP SOLUTION FOUND - sage: sol['x'] # optional - cvxopt - (1.0, 1.0) - - Next, we maximize `x+y-50` subject to `50x + 24y \leq 2400`, - `30x + 33y \leq 2100`, `x \geq 45`, and `y \geq 5`:: - - sage: v=vector([-1.0,-1.0,-1.0]) - sage: m=matrix([[50.0,24.0,0.0],[30.0,33.0,0.0],[-1.0,0.0,0.0],[0.0,-1.0,0.0],[0.0,0.0,1.0],[0.0,0.0,-1.0]]) - sage: h=vector([2400.0,2100.0,-45.0,-5.0,1.0,-1.0]) - sage: sol=linear_program(v,m,h) # optional - cvxopt - sage: sol['x'] # optional - cvxopt - (45.000000..., 6.2499999..., 1.00000000...) - sage: sol=linear_program(v,m,h,solver='glpk') # optional - cvxopt - GLPK Simplex Optimizer... - OPTIMAL LP SOLUTION FOUND - sage: sol['x'] # optional - cvxopt - (45.0..., 6.25..., 1.0...) - """ - deprecation(32226, 'linear_program is deprecated; use MixedIntegerLinearProgram instead') - - from cvxopt.base import matrix as m - from cvxopt import solvers - solvers.options['show_progress'] = False - if solver == 'glpk': - from cvxopt import glpk - glpk.options['LPX_K_MSGLEV'] = 0 - c_ = m(c.base_extend(RDF).numpy()) - G_ = m(G.base_extend(RDF).numpy()) - h_ = m(h.base_extend(RDF).numpy()) - if A is not None and b is not None: - A_ = m(A.base_extend(RDF).numpy()) - b_ = m(b.base_extend(RDF).numpy()) - sol = solvers.lp(c_,G_,h_,A_,b_,solver=solver) - else: - sol = solvers.lp(c_,G_,h_,solver=solver) - status = sol['status'] - if status != 'optimal': - return {'primal objective': None, 'x': None, 's': None, 'y': None, - 'z': None, 'status': status} - x = vector(RDF, list(sol['x'])) - s = vector(RDF, list(sol['s'])) - y = vector(RDF, list(sol['y'])) - z = vector(RDF, list(sol['z'])) - return {'primal objective': sol['primal objective'], - 'x': x, 's': s, 'y': y, 'z': z, 'status': status} - - def find_fit(data, model, initial_guess=None, parameters=None, variables=None, solution_dict=False): r""" Finds numerical estimates for the parameters of the function model to @@ -719,30 +617,34 @@ def find_fit(data, model, initial_guess=None, parameters=None, variables=None, s perturbations:: sage: set_random_seed(0) - sage: data = [(i, 1.2 * sin(0.5*i-0.2) + 0.1 * normalvariate(0, 1)) for i in xsrange(0, 4*pi, 0.2)] - sage: var('a, b, c, x') + sage: data = [(i, 1.2 * sin(0.5*i-0.2) + 0.1 * normalvariate(0, 1)) # needs sage.symbolic + ....: for i in xsrange(0, 4*pi, 0.2)] + sage: var('a, b, c, x') # needs sage.symbolic (a, b, c, x) We define a function with free parameters `a`, `b` and `c`:: - sage: model(x) = a * sin(b * x - c) + sage: model(x) = a * sin(b * x - c) # needs sage.symbolic We search for the parameters that give the best fit to the data:: - sage: find_fit(data, model) + sage: find_fit(data, model) # needs sage.symbolic [a == 1.21..., b == 0.49..., c == 0.19...] We can also use a Python function for the model:: sage: def f(x, a, b, c): return a * sin(b * x - c) - sage: fit = find_fit(data, f, parameters = [a, b, c], variables = [x], solution_dict = True) - sage: fit[a], fit[b], fit[c] + sage: fit = find_fit(data, f, parameters=[a, b, c], variables=[x], # needs sage.symbolic + ....: solution_dict = True) + sage: fit[a], fit[b], fit[c] # needs sage.symbolic (1.21..., 0.49..., 0.19...) We search for a formula for the `n`-th prime number:: + sage: # needs sage.libs.pari sage: dataprime = [(i, nth_prime(i)) for i in range(1, 5000, 100)] - sage: find_fit(dataprime, a * x * log(b * x), parameters = [a, b], variables = [x]) + sage: find_fit(dataprime, a * x * log(b * x), # needs sage.symbolic + ....: parameters=[a, b], variables=[x]) [a == 1.11..., b == 1.24...] @@ -898,24 +800,24 @@ def binpacking(items, maximum=1, k=None, solver=None, verbose=0, sage: from sage.numerical.optimize import binpacking sage: values = [1/5, 1/3, 2/3, 3/4, 5/7] - sage: bins = binpacking(values) - sage: len(bins) + sage: bins = binpacking(values) # needs sage.numerical.mip + sage: len(bins) # needs sage.numerical.mip 3 Checking the bins are of correct size :: - sage: all(sum(b) <= 1 for b in bins) + sage: all(sum(b) <= 1 for b in bins) # needs sage.numerical.mip True Checking every item is in a bin :: - sage: b1, b2, b3 = bins - sage: all((v in b1 or v in b2 or v in b3) for v in values) + sage: b1, b2, b3 = bins # needs sage.numerical.mip + sage: all((v in b1 or v in b2 or v in b3) for v in values) # needs sage.numerical.mip True And only in one bin :: - sage: sum(len(b) for b in bins) == len(values) + sage: sum(len(b) for b in bins) == len(values) # needs sage.numerical.mip True One way to use only three boxes (which is best possible) is to put @@ -925,7 +827,7 @@ def binpacking(items, maximum=1, k=None, solver=None, verbose=0, Of course, we can also check that there is no solution using only two boxes :: sage: from sage.numerical.optimize import binpacking - sage: binpacking([0.2,0.3,0.8,0.9], k=2) + sage: binpacking([0.2,0.3,0.8,0.9], k=2) # needs sage.numerical.mip Traceback (most recent call last): ... ValueError: this problem has no solution @@ -934,8 +836,8 @@ def binpacking(items, maximum=1, k=None, solver=None, verbose=0, its weight. Then, the bins contain the name of the items inside it :: sage: values = {'a':1/5, 'b':1/3, 'c':2/3, 'd':3/4, 'e':5/7} - sage: bins = binpacking(values) - sage: set(flatten(bins)) == set(values.keys()) + sage: bins = binpacking(values) # needs sage.numerical.mip + sage: set(flatten(bins)) == set(values.keys()) # needs sage.numerical.mip True TESTS: diff --git a/src/sage/numerical/sdp.pyx b/src/sage/numerical/sdp.pyx index e7b96a2abef..3f5f8a47cfb 100644 --- a/src/sage/numerical/sdp.pyx +++ b/src/sage/numerical/sdp.pyx @@ -72,17 +72,19 @@ The following example shows all these steps:: sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) sage: p.add_constraint(c1*x[0] + c2*x[1] >= matrix.zero(2,2,sparse=True)) - sage: p.solver_parameter("show_progress", True) # optional - cvxopt - sage: opt = p.solve() # optional - cvxopt + + sage: # needs cvxopt + sage: p.solver_parameter("show_progress", True) + sage: opt = p.solve() pcost dcost gap pres dres k/t 0: ... ... Optimal solution found. - sage: print('Objective Value: {}'.format(N(opt,3))) # optional - cvxopt + sage: print('Objective Value: {}'.format(N(opt,3))) Objective Value: 1.0 - sage: [N(x, 3) for x in sorted(p.get_values(x).values())] # optional - cvxopt + sage: [N(x, 3) for x in sorted(p.get_values(x).values())] [3.0e-8, 1.0] - sage: p.show() # optional - cvxopt + sage: p.show() Maximization: x_0 - x_1 Constraints: @@ -97,46 +99,49 @@ of primal and dual problems. Thus we can get the optimizer `X` of the dual probl as follows, as diagonal blocks, one per each constraint, via :meth:`~SemidefiniteProgram.dual_variable`. E.g.:: - sage: p.dual_variable(1) # rel tol 2e-03 # optional - cvxopt + sage: p.dual_variable(1) # rel tol 2e-03 # needs cvxopt [ 85555.0 -85555.0] [-85555.0 85555.0] We can see that the optimal value of the dual is equal (up to numerical noise) to `opt`.:: - sage: opt-((p.dual_variable(0)*a3).trace()+(p.dual_variable(1)*b3).trace()) # tol 8e-08 # optional - cvxopt + sage: opt - ((p.dual_variable(0)*a3).trace() # tol 8e-08 # needs cvxopt + ....: + (p.dual_variable(1)*b3).trace()) 0.0 Dual variable blocks at optimality are orthogonal to "slack variables", that is, matrices `C-\sum_k x_k A_k`, cf. (Primal problem) above, available via :meth:`~SemidefiniteProgram.slack`. E.g.:: - sage: (p.slack(0)*p.dual_variable(0)).trace() # tol 2e-07 # optional - cvxopt + sage: (p.slack(0)*p.dual_variable(0)).trace() # tol 2e-07 # needs cvxopt 0.0 More interesting example, the :func:`Lovasz theta ` of the 7-gon:: - sage: c=graphs.CycleGraph(7) - sage: c2=c.distance_graph(2).adjacency_matrix() - sage: c3=c.distance_graph(3).adjacency_matrix() - sage: p.=SemidefiniteProgram() + sage: # needs sage.graphs + sage: c = graphs.CycleGraph(7) + sage: c2 = c.distance_graph(2).adjacency_matrix() + sage: c3 = c.distance_graph(3).adjacency_matrix() + sage: p. = SemidefiniteProgram() sage: p.add_constraint((1/7)*matrix.identity(7)>=-y[0]*c2-y[1]*c3) sage: p.set_objective(y[0]*(c2**2).trace()+y[1]*(c3**2).trace()) - sage: x=p.solve(); x+1 # optional - cvxopt + sage: x = p.solve(); x + 1 # needs cvxopt 3.31766... Unlike in the previous example, the slack variable is very far from 0:: - sage: p.slack(0).trace() # tol 1e-14 # optional - cvxopt + sage: p.slack(0).trace() # tol 1e-14 # needs cvxopt sage.graphs 1.0 The default CVXOPT backend computes with the Real Double Field, for example:: - sage: p = SemidefiniteProgram(solver='cvxopt') # optional - cvxopt - sage: p.base_ring() # optional - cvxopt + sage: # needs cvxopt + sage: p = SemidefiniteProgram(solver='cvxopt') + sage: p.base_ring() Real Double Field - sage: x = p.new_variable() # optional - cvxopt - sage: 0.5 + 3/2*x[1] # optional - cvxopt + sage: x = p.new_variable() + sage: 0.5 + 3/2*x[1] 0.5 + 1.5*x_0 For representing an SDP with exact data, there is another backend:: @@ -285,7 +290,7 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) - sage: N(p.solve(), 2) # optional - cvxopt + sage: N(p.solve(), 2) # needs cvxopt -3.0 """ @@ -301,7 +306,7 @@ cdef class SemidefiniteProgram(SageObject): - CVXOPT (``solver="CVXOPT"``). See the `CVXOPT `_ web site. - -If ``solver=None`` (default), the default solver is used (see + - If ``solver=None`` (default), the default solver is used (see ``default_sdp_solver`` method. - ``maximization`` @@ -335,7 +340,6 @@ cdef class SemidefiniteProgram(SageObject): # Associates an index to the variables self._variables = {} - def linear_functions_parent(self): """ Return the parent for all linear functions. @@ -479,8 +483,8 @@ cdef class SemidefiniteProgram(SageObject): def new_variable(self, name=""): r""" - Returns an instance of ``SDPVariable`` associated - to the current instance of ``SemidefiniteProgram``. + Returns an instance of :class:`SDPVariable` associated + to the current instance of :class:`SemidefiniteProgram`. A new variable ``x`` is defined by:: @@ -504,7 +508,7 @@ cdef class SemidefiniteProgram(SageObject): sage: p = SemidefiniteProgram() sage: x = p.new_variable() sage: a1 = matrix([[1, 2.], [2., 3.]]) - sage: p.add_constraint(a1*x[0]+a1*x[3] <= 0) + sage: p.add_constraint(a1*x[0] + a1*x[3] <= 0) sage: p.show() Maximization: @@ -567,7 +571,7 @@ cdef class SemidefiniteProgram(SageObject): cpdef int number_of_constraints(self) noexcept: r""" - Returns the number of constraints assigned so far. + Return the number of constraints assigned so far. EXAMPLES:: @@ -589,7 +593,7 @@ cdef class SemidefiniteProgram(SageObject): cpdef int number_of_variables(self) noexcept: r""" - Returns the number of variables used so far. + Return the number of variables used so far. EXAMPLES:: @@ -602,11 +606,9 @@ cdef class SemidefiniteProgram(SageObject): """ return self._backend.ncols() - - def show(self): r""" - Displays the ``SemidefiniteProgram`` in a human-readable way. + Display the :class:`SemidefiniteProgram` in a human-readable way. EXAMPLES: @@ -618,7 +620,7 @@ cdef class SemidefiniteProgram(SageObject): sage: a2 = matrix([[2,3],[3,4]]) sage: a3 = matrix([[3,4],[4,5]]) sage: p.set_objective(x[0] - x[1]) - sage: p.add_constraint(a1*x[0]+a2*x[1]<= a3) + sage: p.add_constraint(a1*x[0] + a2*x[1]<= a3) sage: p.show() Maximization: hihi[0] - hihi[1] @@ -692,25 +694,23 @@ cdef class SemidefiniteProgram(SageObject): print(str(varid_name[i]) + ", ", end=" ") print(str(varid_name[b.ncols()-1])) - def get_values(self, *lists): r""" Return values found by the previous call to ``solve()``. INPUT: - - Any instance of ``SDPVariable`` (or one of its elements), + - Any instance of :class:`SDPVariable` (or one of its elements), or lists of them. OUTPUT: - - Each instance of ``SDPVariable`` is replaced by a dictionary + - Each instance of :class:`SDPVariable` is replaced by a dictionary containing the numerical values found for each corresponding variable in the instance. - - Each element of an instance of a ``SDPVariable`` is replaced + - Each element of an instance of a :class:`SDPVariable` is replaced by its corresponding numerical value. - EXAMPLES:: sage: p = SemidefiniteProgram(solver = "cvxopt", maximization = False) @@ -724,19 +724,19 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[3] + a2*x[5] <= a3) sage: p.add_constraint(b1*x[3] + b2*x[5] <= b3) - sage: N(p.solve(),3) # optional - cvxopt + sage: N(p.solve(), 3) # needs cvxopt -3.0 To return the optimal value of ``x[3]``:: - sage: N(p.get_values(x[3]),3) # optional - cvxopt + sage: N(p.get_values(x[3]),3) # needs cvxopt -1.0 To get a dictionary identical to ``x`` containing optimal values for the corresponding variables :: - sage: x_sol = p.get_values(x) # optional - cvxopt - sage: sorted(x_sol) # optional - cvxopt + sage: x_sol = p.get_values(x) # needs cvxopt + sage: sorted(x_sol) # needs cvxopt [3, 5] """ @@ -765,13 +765,13 @@ cdef class SemidefiniteProgram(SageObject): def set_objective(self, obj): r""" - Sets the objective of the ``SemidefiniteProgram``. + Sets the objective of the :class:`SemidefiniteProgram`. INPUT: - ``obj`` -- A semidefinite function to be optimized. - ( can also be set to ``None`` or ``0`` when just - looking for a feasible solution ) + (can also be set to ``None`` or ``0`` when just + looking for a feasible solution) EXAMPLES: @@ -794,11 +794,11 @@ cdef class SemidefiniteProgram(SageObject): sage: a1 = matrix([[1,2],[2,3]]) sage: a2 = matrix([[1,1],[1,1]]) sage: a3 = matrix([[1,-1],[-1,1]]) - sage: p.add_constraint(a1*x[1]+a2*x[2] <= a3) - sage: N(p.solve(),digits=3) # optional - cvxopt + sage: p.add_constraint(a1*x[1] + a2*x[2] <= a3) + sage: N(p.solve(), digits=3) # needs cvxopt 16.2 sage: p.set_objective(None) - sage: _ = p.solve() # optional - cvxopt + sage: _ = p.solve() # needs cvxopt """ cdef list values = [] @@ -825,11 +825,13 @@ cdef class SemidefiniteProgram(SageObject): INPUT: - ``linear_function`` -- Two different types of arguments are possible: - - A linear function. In this case, arguments ``min`` or ``max`` - have to be specified. - - A linear constraint of the form ``A <= B``, ``A >= B``, - ``A <= B <= C``, ``A >= B >= C`` or ``A == B``. In this - case, arguments ``min`` and ``max`` will be ignored. + + - A linear function. In this case, arguments ``min`` or ``max`` + have to be specified. + - A linear constraint of the form ``A <= B``, ``A >= B``, + ``A <= B <= C``, ``A >= B >= C`` or ``A == B``. In this + case, arguments ``min`` and ``max`` will be ignored. + - ``name`` -- A name for the constraint. EXAMPLES: @@ -853,8 +855,8 @@ cdef class SemidefiniteProgram(SageObject): sage: a1 = matrix([[1,2],[2,3]]) sage: a2 = matrix([[1,1],[1,1]]) sage: a3 = matrix([[1,-1],[-1,1]]) - sage: p.add_constraint(a1*x[1]+a2*x[2] <= a3) - sage: N(p.solve(),digits=3) # optional - cvxopt + sage: p.add_constraint(a1*x[1] + a2*x[2] <= a3) + sage: N(p.solve(), digits=3) # needs cvxopt 16.2 One can also define double-bounds or equality using the symbol @@ -867,7 +869,7 @@ cdef class SemidefiniteProgram(SageObject): sage: a2 = matrix([[1,1],[1,1]]) sage: a3 = matrix([[1,-1],[-1,1]]) sage: p.add_constraint(a3 >= a1*x[1] + a2*x[2]) - sage: N(p.solve(),digits=3) # optional - cvxopt + sage: N(p.solve(), digits=3) # needs cvxopt 16.2 TESTS: @@ -892,7 +894,6 @@ cdef class SemidefiniteProgram(SageObject): sage: p = SemidefiniteProgram() sage: p.add_constraint(sum([])) - """ if linear_function is 0: return @@ -918,7 +919,7 @@ cdef class SemidefiniteProgram(SageObject): def solve(self, objective_only=False): r""" - Solves the ``SemidefiniteProgram``. + Solve the :class:`SemidefiniteProgram`. INPUT: @@ -947,12 +948,14 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) - sage: N(p.solve(),4) # optional - cvxopt + + sage: # needs cvxopt + sage: N(p.solve(), 4) -11. - sage: x = p.get_values(x) # optional - cvxopt - sage: N(x[0],4) # optional - cvxopt + sage: x = p.get_values(x) + sage: N(x[0],4) -8.0 - sage: N(x[1],4) # optional - cvxopt + sage: N(x[1],4) 3.0 """ self._backend.solve() @@ -977,7 +980,7 @@ cdef class SemidefiniteProgram(SageObject): Dual objective value is the same as the primal one:: - sage: p = SemidefiniteProgram(maximization = False) + sage: p = SemidefiniteProgram(maximization=False) sage: x = p.new_variable() sage: p.set_objective(x[0] - x[1]) sage: a1 = matrix([[1, 2.], [2., 3.]]) @@ -988,20 +991,23 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) - sage: p.solve() # tol 1e-08 # optional - cvxopt + + sage: # needs cvxopt + sage: p.solve() # tol 1e-08 -3.0 - sage: x = p.get_values(x).values() # optional - cvxopt - sage: -(a3*p.dual_variable(0)).trace()-(b3*p.dual_variable(1)).trace() # tol 1e-07 # optional - cvxopt + sage: x = p.get_values(x).values() + sage: -(a3*p.dual_variable(0)).trace() - (b3*p.dual_variable(1)).trace() # tol 1e-07 -3.0 Dual variable is orthogonal to the slack :: - sage: g = sum((p.slack(j)*p.dual_variable(j)).trace() for j in range(2)); g # tol 1.2e-08 # optional - cvxopt + sage: # needs cvxopt + sage: g = sum((p.slack(j)*p.dual_variable(j)).trace() for j in range(2)); g # tol 1.2e-08 0.0 TESTS:: - sage: p.dual_variable(7) # optional - cvxopt + sage: p.dual_variable(7) # needs cvxopt Traceback (most recent call last): ... IndexError: list index out of range @@ -1035,21 +1041,23 @@ cdef class SemidefiniteProgram(SageObject): sage: b3 = matrix([[3, 3.], [3., 3.]]) sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) - sage: p.solve() # tol 1e-08 # optional - cvxopt + + sage: # needs cvxopt + sage: p.solve() # tol 1e-08 -3.0 - sage: B1 = p.slack(1); B1 # tol 1e-08 # optional - cvxopt + sage: B1 = p.slack(1); B1 # tol 1e-08 [0.0 0.0] [0.0 0.0] - sage: B1.is_positive_definite() # optional - cvxopt + sage: B1.is_positive_definite() True - sage: x = sorted(p.get_values(x).values()) # optional - cvxopt - sage: x[0]*b1 + x[1]*b2 - b3 + B1 # tol 1e-09 # optional - cvxopt + sage: x = sorted(p.get_values(x).values()) + sage: x[0]*b1 + x[1]*b2 - b3 + B1 # tol 1e-09 [0.0 0.0] [0.0 0.0] TESTS:: - sage: p.slack(7) # optional - cvxopt + sage: p.slack(7) # needs cvxopt Traceback (most recent call last): ... IndexError: list index out of range @@ -1066,7 +1074,6 @@ cdef class SemidefiniteProgram(SageObject): (If you do not know which solver you are using, then you are using CVXOPT). - INPUT: - ``name`` (string) -- the parameter @@ -1076,20 +1083,22 @@ cdef class SemidefiniteProgram(SageObject): EXAMPLES:: - sage: p. = SemidefiniteProgram(solver = "cvxopt", maximization = False) # optional - cvxopt - sage: p.solver_parameter("show_progress", True) # optional - cvxopt - sage: p.solver_parameter("show_progress") # optional - cvxopt + sage: # needs cvxopt + sage: p. = SemidefiniteProgram(solver="cvxopt", + ....: maximization=False) + sage: p.solver_parameter("show_progress", True) + sage: p.solver_parameter("show_progress") True - sage: p.set_objective(x[0] - x[1]) # optional - cvxopt + sage: p.set_objective(x[0] - x[1]) sage: a1 = matrix([[1, 2.], [2., 3.]]) sage: a2 = matrix([[3, 4.], [4., 2.]]) sage: a3 = matrix([[5, 6.], [6., 7.]]) sage: b1 = matrix([[1, 1.], [1., 1.]]) sage: b2 = matrix([[2, 2.], [2., 1.]]) sage: b3 = matrix([[3, 3.], [3., 3.]]) - sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) # optional - cvxopt - sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) # optional - cvxopt - sage: N(p.solve(),4) # optional - cvxopt + sage: p.add_constraint(a1*x[0] + a2*x[1] <= a3) + sage: p.add_constraint(b1*x[0] + b2*x[1] <= b3) + sage: N(p.solve(), 4) pcost dcost gap pres dres k/t 0: 1... ... @@ -1177,13 +1186,14 @@ class SDPSolverException(RuntimeError): No solution:: - sage: p = SemidefiniteProgram(solver="cvxopt") # optional - cvxopt - sage: x = p.new_variable() # optional - cvxopt - sage: p.set_objective(x[0]) # optional - cvxopt + sage: # needs cvxopt + sage: p = SemidefiniteProgram(solver="cvxopt") + sage: x = p.new_variable() + sage: p.set_objective(x[0]) sage: a = matrix([[1,2],[2,4]]) sage: b = matrix([[1,9],[9,4]]) - sage: p.add_constraint( a*x[0] == b ) # optional - cvxopt - sage: p.solve() # optional - cvxopt + sage: p.add_constraint(a*x[0] == b) + sage: p.solve() Traceback (most recent call last): ... SDPSolverException: ... @@ -1220,7 +1230,6 @@ cdef class SDPVariable(Element): - ``sdp`` -- :class:`SemidefiniteProgram`. The underlying linear program. - - ``name`` -- A name for the ``SDPVariable``. - ``lower_bound``, ``upper_bound`` -- lower bound and upper @@ -1244,7 +1253,7 @@ cdef class SDPVariable(Element): def __getitem__(self, i): r""" - Returns the symbolic variable corresponding to the key. + Return the symbolic variable corresponding to the key. Returns the element asked, otherwise creates it. @@ -1275,8 +1284,8 @@ cdef class SDPVariable(Element): EXAMPLES:: - sage: p=SemidefiniteProgram() - sage: v=p.new_variable() + sage: p = SemidefiniteProgram() + sage: v = p.new_variable() sage: v SDPVariable """