diff --git a/.github/workflows/ci-cygwin-standard.yml b/.github/workflows/ci-cygwin-standard.yml index 326dd62490e..d7808b4a052 100644 --- a/.github/workflows/ci-cygwin-standard.yml +++ b/.github/workflows/ci-cygwin-standard.yml @@ -117,7 +117,7 @@ jobs: with: stage: v-c previous_stages: iv - targets: sage_numerical_backends_coin + targets: cylp cvxopt needs: [cygwin-stage-iv] cygwin-stage-v-d: diff --git a/build/pkgs/cbc/checksums.ini b/build/pkgs/cbc/checksums.ini index 063d4b0c1df..4a92c28dd1f 100644 --- a/build/pkgs/cbc/checksums.ini +++ b/build/pkgs/cbc/checksums.ini @@ -1,5 +1,5 @@ tarball=cbc-VERSION.tar.gz -sha1=d937d6af1ee8838d44659ebd4cf7bbb1b20372ce -md5=2134576233cc95cdfedc63991a4944ec -cksum=1215468781 +sha1=1ead967d3d5610e3c434c9aec76a31ea90eb578f +md5=c31255a6bd4ab7136f1d044f39c372da +cksum=3510659652 upstream_url=https://github.com/coin-or/Cbc/archive/refs/tags/releases/VERSION.tar.gz diff --git a/build/pkgs/cbc/package-version.txt b/build/pkgs/cbc/package-version.txt index 4a90452c956..9fdd305a8e4 100644 --- a/build/pkgs/cbc/package-version.txt +++ b/build/pkgs/cbc/package-version.txt @@ -1 +1 @@ -2.9.4.p0 +2.10.10 diff --git a/build/pkgs/sage_numerical_backends_coin/SPKG.rst b/build/pkgs/sage_numerical_backends_coin/SPKG.rst index 54db2204600..b531f68093c 100644 --- a/build/pkgs/sage_numerical_backends_coin/SPKG.rst +++ b/build/pkgs/sage_numerical_backends_coin/SPKG.rst @@ -1,11 +1,16 @@ -sage_numerical_backends_coin: COIN-OR backend for Sage MixedIntegerLinearProgram -================================================================================ +sage_numerical_backends_coin: COIN-OR backend for Sage MixedIntegerLinearProgram (deprecated) +============================================================================================= Description ----------- COIN-OR backend for Sage MixedIntegerLinearProgram +This package is deprecated and will be removed soon. + +Install packages ``cvxpy`` and ``cylp`` instead. + + License ------- diff --git a/build/pkgs/sage_numerical_backends_coin/dependencies b/build/pkgs/sage_numerical_backends_coin/dependencies index 4cbde1164f2..fca91432acf 100644 --- a/build/pkgs/sage_numerical_backends_coin/dependencies +++ b/build/pkgs/sage_numerical_backends_coin/dependencies @@ -1,4 +1,6 @@ -cbc cysignals $(SAGE_SRC)/sage/numerical/backends/generic_backend.pxd $(SAGE_SRC)/sage/cpython/string.pxd $(SAGE_SRC)/sage/cpython/string_impl.h | $(SAGERUNTIME) $(PYTHON_TOOLCHAIN) cython ipywidgets +cylp cvxpy cbc cysignals $(SAGE_SRC)/sage/numerical/backends/generic_backend.pxd $(SAGE_SRC)/sage/cpython/string.pxd $(SAGE_SRC)/sage/cpython/string_impl.h | $(SAGERUNTIME) $(PYTHON_TOOLCHAIN) cython ipywidgets ---------- All lines of this file are ignored except the first. + +cylp and cvxpy are the recommended replacement for this deprecated package - added them to the dependencies. diff --git a/src/doc/en/thematic_tutorials/linear_programming.rst b/src/doc/en/thematic_tutorials/linear_programming.rst index c8bf14c4eb4..2e7be4f6e3e 100644 --- a/src/doc/en/thematic_tutorials/linear_programming.rst +++ b/src/doc/en/thematic_tutorials/linear_programming.rst @@ -447,10 +447,10 @@ following libraries are currently supported: * `CBC `_: A solver from `COIN-OR `_, provided under the Eclipse Public License (EPL), which is an open source - license but incompatible with GPL. CBC and the Sage CBC backend can be - installed using the shell command:: + license but incompatible with GPL. Sage can use CBC via the optional + packages CyLP and CVXPy, which can be installed using the shell command:: - $ sage -i -c sage_numerical_backends_coin + $ sage -i -c cylp cvxpy * `CPLEX `_: diff --git a/src/sage/numerical/backends/cvxpy_backend.pyx b/src/sage/numerical/backends/cvxpy_backend.pyx index 4ffae61809a..857dc04b1ed 100644 --- a/src/sage/numerical/backends/cvxpy_backend.pyx +++ b/src/sage/numerical/backends/cvxpy_backend.pyx @@ -336,6 +336,9 @@ cdef class CVXPYBackend: sage: p.row_name(1) 'constraint_1' """ + if not isinstance(coefficients, (list, tuple)): + # may be generator + coefficients = list(coefficients) last = len(self.Matrix) self.Matrix.append([]) for i in range(len(self.objective_coefficients)): @@ -930,3 +933,76 @@ cdef class CVXPYBackend: self.col_lower_bound[index] = value else: return self.col_lower_bound[index] + + cpdef remove_constraint(self, int index): + """ + Remove a linear constraint by index. + + INPUT: + + - ``index`` -- integer. The index of the constraint to remove. + + EXAMPLES:: + + sage: from sage.numerical.backends.generic_backend import get_solver + sage: p = get_solver(solver="CVXPY") + sage: p.add_variables(5) + 4 + sage: row_index = p.nrows(); row_index + 5 + sage: p.add_linear_constraint(zip(range(5), range(5)), 2, 2) + sage: p.nrows() - row_index + 1 + sage: p.add_linear_constraint(zip(range(5), range(5)), 1, 1, name='foo') + sage: p.nrows() - row_index + 2 + sage: p.remove_constraint(row_index) + sage: p.nrows() - row_index + 1 + sage: p.row_name(row_index) + 'foo' + sage: p.row_bounds(row_index) + (1, 1) + sage: p.cvxpy_problem().constraints[row_index:] + [Equality(Expression(AFFINE, UNKNOWN, ()), Constant(CONSTANT, NONNEGATIVE, ()))] + """ + self.remove_constraints([index]) + + cpdef remove_constraints(self, indices): + r""" + Remove several constraints. + + INPUT: + + - ``indices`` -- iterable of integers. The indices of the constraints to remove, + in arbitrary order. + + EXAMPLES:: + + sage: from sage.numerical.backends.generic_backend import get_solver + sage: p = get_solver(solver="CVXPY") + sage: p.add_variables(5) + 4 + sage: row_index = p.nrows(); row_index + 5 + sage: for i in range(3): + ....: p.add_linear_constraint(zip(range(5), range(5)), None, 5) + sage: p.add_linear_constraint(zip(range(5), range(5)), 1, 1, name='foo') + sage: p.cvxpy_problem().constraints[row_index:] + [Inequality(Expression(AFFINE, UNKNOWN, ())), + Inequality(Expression(AFFINE, UNKNOWN, ())), + Inequality(Expression(AFFINE, UNKNOWN, ())), + Equality(Expression(AFFINE, UNKNOWN, ()), Constant(CONSTANT, NONNEGATIVE, ()))] + sage: p.remove_constraints(range(row_index, row_index + 3)) + sage: p.cvxpy_problem().constraints[row_index:] + [Equality(Expression(AFFINE, UNKNOWN, ()), Constant(CONSTANT, NONNEGATIVE, ()))] + """ + indices = sorted(indices) + constraints = list(self.problem.constraints) + for index in reversed(indices): + del self.Matrix[index] + del self.row_lower_bound[index] + del self.row_upper_bound[index] + del self.constraint_names[index] + del constraints[index] + self.problem = cvxpy.Problem(self.problem.objective, constraints) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 20eb36cbd00..3b688d9e7f9 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -1595,7 +1595,7 @@ def default_mip_solver(solver=None): return default_solver else: - for s in ["Cplex", "Gurobi", "Cvxpy/cbc", "Coin", "Glpk", "SCIP"]: + for s in ["Cplex", "Gurobi", "Cvxpy/cbc", "Glpk", "SCIP"]: try: default_mip_solver(s) return s @@ -1608,6 +1608,9 @@ def default_mip_solver(solver=None): solver = solver.capitalize() + if solver == "Coin": + solver = "Cvxpy/cbc" + if solver == "Cplex": try: from sage_numerical_backends_cplex.cplex_backend import CPLEXBackend @@ -1615,13 +1618,6 @@ def default_mip_solver(solver=None): except ImportError: raise ValueError("CPLEX is not available. Please refer to the documentation to install it.") - elif solver == "Coin": - try: - from sage_numerical_backends_coin.coin_backend import CoinBackend - default_solver = solver - except ImportError: - raise ValueError("COIN is not available. Please refer to the documentation to install it.") - elif solver == "Cvxopt": try: from sage.numerical.backends.cvxopt_backend import CVXOPTBackend @@ -1801,10 +1797,9 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None, ba solver = solver.capitalize() if solver == "Coin": - from sage_numerical_backends_coin.coin_backend import CoinBackend - return CoinBackend() + solver = "Cvxpy/cbc" - elif solver == "Glpk": + if solver == "Glpk": from sage.numerical.backends.glpk_backend import GLPKBackend return GLPKBackend()