From 22319eaa3487bc891289330556bb04cbe41b9914 Mon Sep 17 00:00:00 2001 From: Takshak Mudgal Date: Thu, 6 Apr 2023 15:09:44 +0530 Subject: [PATCH 01/12] remove_constraint method implemented --- src/sage/numerical/backends/cvxpy_backend.pyx | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/sage/numerical/backends/cvxpy_backend.pyx b/src/sage/numerical/backends/cvxpy_backend.pyx index ca559d0d319..c7e756edf8f 100644 --- a/src/sage/numerical/backends/cvxpy_backend.pyx +++ b/src/sage/numerical/backends/cvxpy_backend.pyx @@ -932,3 +932,46 @@ cdef class CVXPYBackend: self.col_lower_bound[index] = value else: return self.col_lower_bound[index] + + cpdef remove_constraint(self, 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: p.add_linear_constraint( zip(range(5), range(5)), 2, 2) + sage: p.add_linear_constraint( zip(range(5), range(5)), 1, 1, name='foo') + sage: p.remove_constraint(0) + sage: p.nrows() + 1 + """ + del self.Matrix[index] + del self.row_lower_bound[index] + del self.row_upper_bound[index] + del self.constraint_names[index] + + constraints = [] + for i, row in enumerate(self.Matrix): + terms = [v * self.variables[j] for j, v in enumerate(row)] + if terms: + expr = AddExpression(terms) + else: + expr = Constant(0) + lower_bound = self.row_lower_bound[i] + upper_bound = self.row_upper_bound[i] + if lower_bound is not None and lower_bound == upper_bound: + constraints.append(expr == upper_bound) + elif lower_bound is not None: + constraints.append(lower_bound <= expr) + elif upper_bound is not None: + constraints.append(expr <= upper_bound) + + self.problem = cvxpy.Problem(self.problem.objective, constraints) From 931e41d38b40e315274127d5c29cbb2587dc52c6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 20 Apr 2023 17:26:14 -0700 Subject: [PATCH 02/12] src/sage/numerical/backends/cvxpy_backend.pyx: Fix signature of remove_constraint --- src/sage/numerical/backends/cvxpy_backend.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/numerical/backends/cvxpy_backend.pyx b/src/sage/numerical/backends/cvxpy_backend.pyx index c7e756edf8f..f7908f5d1a2 100644 --- a/src/sage/numerical/backends/cvxpy_backend.pyx +++ b/src/sage/numerical/backends/cvxpy_backend.pyx @@ -933,7 +933,7 @@ cdef class CVXPYBackend: else: return self.col_lower_bound[index] - cpdef remove_constraint(self, index): + cpdef remove_constraint(self, int index): """ Remove a linear constraint by index. From 28d0f28bbb6dbcc1abc462808571a8987c47feb3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 20 Apr 2023 21:32:23 -0700 Subject: [PATCH 03/12] CVXPYBackend.remove_constraint: Fix/expand doctest --- src/sage/numerical/backends/cvxpy_backend.pyx | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/sage/numerical/backends/cvxpy_backend.pyx b/src/sage/numerical/backends/cvxpy_backend.pyx index f7908f5d1a2..70a170d8f13 100644 --- a/src/sage/numerical/backends/cvxpy_backend.pyx +++ b/src/sage/numerical/backends/cvxpy_backend.pyx @@ -947,11 +947,28 @@ cdef class CVXPYBackend: sage: p = get_solver(solver="CVXPY") sage: p.add_variables(5) 4 - sage: p.add_linear_constraint( zip(range(5), range(5)), 2, 2) - sage: p.add_linear_constraint( zip(range(5), range(5)), 1, 1, name='foo') - sage: p.remove_constraint(0) - sage: p.nrows() + 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 + [Inequality(Constant(CONSTANT, ZERO, ())), + Inequality(Constant(CONSTANT, ZERO, ())), + Inequality(Constant(CONSTANT, ZERO, ())), + Inequality(Constant(CONSTANT, ZERO, ())), + Inequality(Constant(CONSTANT, ZERO, ())), + Equality(Expression(AFFINE, UNKNOWN, ()), Constant(CONSTANT, NONNEGATIVE, ()))] """ del self.Matrix[index] del self.row_lower_bound[index] From dbdb3b096b20326f492717115819cb620e4d725d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 Mar 2023 13:57:33 -0700 Subject: [PATCH 04/12] build/pkgs/sage_numerical_backends_coin: Mark experimental / deprecated --- build/pkgs/sage_numerical_backends_coin/SPKG.rst | 9 +++++++-- build/pkgs/sage_numerical_backends_coin/type | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) 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/type b/build/pkgs/sage_numerical_backends_coin/type index 134d9bc32d5..9839eb20815 100644 --- a/build/pkgs/sage_numerical_backends_coin/type +++ b/build/pkgs/sage_numerical_backends_coin/type @@ -1 +1 @@ -optional +experimental From 3551f9716581f92a60d48582a45f96de57197c26 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 30 Jul 2022 16:26:31 -0700 Subject: [PATCH 05/12] src/sage/numerical/backends/generic_backend.pyx: Make solver='Coin' an alias for solver='CVXPy/CBC' --- src/sage/numerical/backends/generic_backend.pyx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) 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() From cda3f62a2bdb6e15baa91a6b97f06012807d0c1b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 30 Jul 2022 16:27:52 -0700 Subject: [PATCH 06/12] .github/workflows/ci-cygwin-standard.yml: Replace sage_numerical_backends_coin --- .github/workflows/ci-cygwin-standard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: From 1b90f73b319b8103352696cb30d68eda268113db Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 30 Jul 2022 16:30:29 -0700 Subject: [PATCH 07/12] src/doc/en/thematic_tutorials/linear_programming.rst: Update install guide --- src/doc/en/thematic_tutorials/linear_programming.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/en/thematic_tutorials/linear_programming.rst b/src/doc/en/thematic_tutorials/linear_programming.rst index c8bf14c4eb4..e6cf56f7702 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 CyLP and CVXPy, + which can be installed using the shell command:: - $ sage -i -c sage_numerical_backends_coin + $ sage -i -c cylp cvxpy * `CPLEX `_: From 05a09d5300b3935398e6b47df73f23a58abd6230 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 Mar 2023 14:06:56 -0700 Subject: [PATCH 08/12] src/doc/en/thematic_tutorials/linear_programming.rst: Fix wording --- src/doc/en/thematic_tutorials/linear_programming.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/en/thematic_tutorials/linear_programming.rst b/src/doc/en/thematic_tutorials/linear_programming.rst index e6cf56f7702..2e7be4f6e3e 100644 --- a/src/doc/en/thematic_tutorials/linear_programming.rst +++ b/src/doc/en/thematic_tutorials/linear_programming.rst @@ -447,8 +447,8 @@ 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. Sage can use CBC via the CyLP and CVXPy, - which 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 cylp cvxpy From 05eebc0d28edd637ddc0524d7b4a0eeffd480c17 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 Mar 2023 14:13:06 -0700 Subject: [PATCH 09/12] build/pkgs/cbc: Update to 2.10.8 --- build/pkgs/cbc/checksums.ini | 6 +++--- build/pkgs/cbc/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/cbc/checksums.ini b/build/pkgs/cbc/checksums.ini index 063d4b0c1df..c9cba80ef07 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=1af3d6f09e584c02d7d3e89fe1e3e88bcdc29128 +md5=8a2eb3185e033b9cf61ca02c30090f37 +cksum=2353193016 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..c63c9a75248 100644 --- a/build/pkgs/cbc/package-version.txt +++ b/build/pkgs/cbc/package-version.txt @@ -1 +1 @@ -2.9.4.p0 +2.10.8 From b1f9b2244a0a7cfd4dd4196d04f435070dbb3900 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 27 Mar 2023 14:21:38 -0700 Subject: [PATCH 10/12] build/pkgs/sage_numerical_backends_coin/dependencies: Add replacements here --- build/pkgs/sage_numerical_backends_coin/dependencies | 4 +++- build/pkgs/sage_numerical_backends_coin/type | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) 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/build/pkgs/sage_numerical_backends_coin/type b/build/pkgs/sage_numerical_backends_coin/type index 9839eb20815..134d9bc32d5 100644 --- a/build/pkgs/sage_numerical_backends_coin/type +++ b/build/pkgs/sage_numerical_backends_coin/type @@ -1 +1 @@ -experimental +optional From aecb19093236c392128515a0a1960a4ae5a41959 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 22 Apr 2023 22:31:12 -0700 Subject: [PATCH 11/12] CVXPYBackend: Implement remove_constraint as special case of remove_constraints --- src/sage/numerical/backends/cvxpy_backend.pyx | 68 ++++++++++++------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/src/sage/numerical/backends/cvxpy_backend.pyx b/src/sage/numerical/backends/cvxpy_backend.pyx index 70a170d8f13..df1e2901163 100644 --- a/src/sage/numerical/backends/cvxpy_backend.pyx +++ b/src/sage/numerical/backends/cvxpy_backend.pyx @@ -338,6 +338,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)): @@ -962,33 +965,46 @@ cdef class CVXPYBackend: 'foo' sage: p.row_bounds(row_index) (1, 1) - sage: p.cvxpy_problem().constraints - [Inequality(Constant(CONSTANT, ZERO, ())), - Inequality(Constant(CONSTANT, ZERO, ())), - Inequality(Constant(CONSTANT, ZERO, ())), - Inequality(Constant(CONSTANT, ZERO, ())), - Inequality(Constant(CONSTANT, ZERO, ())), - Equality(Expression(AFFINE, UNKNOWN, ()), Constant(CONSTANT, NONNEGATIVE, ()))] + sage: p.cvxpy_problem().constraints[row_index:] + [Equality(Expression(AFFINE, UNKNOWN, ()), Constant(CONSTANT, NONNEGATIVE, ()))] """ - del self.Matrix[index] - del self.row_lower_bound[index] - del self.row_upper_bound[index] - del self.constraint_names[index] + self.remove_constraints([index]) - constraints = [] - for i, row in enumerate(self.Matrix): - terms = [v * self.variables[j] for j, v in enumerate(row)] - if terms: - expr = AddExpression(terms) - else: - expr = Constant(0) - lower_bound = self.row_lower_bound[i] - upper_bound = self.row_upper_bound[i] - if lower_bound is not None and lower_bound == upper_bound: - constraints.append(expr == upper_bound) - elif lower_bound is not None: - constraints.append(lower_bound <= expr) - elif upper_bound is not None: - constraints.append(expr <= upper_bound) + 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) From 2a13db9d143ff442d8cb43cb84596f23ee5b82d7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 22 Apr 2023 22:36:23 -0700 Subject: [PATCH 12/12] build/pkgs/cbc: Update to 2.10.10 --- build/pkgs/cbc/checksums.ini | 6 +++--- build/pkgs/cbc/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/cbc/checksums.ini b/build/pkgs/cbc/checksums.ini index c9cba80ef07..4a92c28dd1f 100644 --- a/build/pkgs/cbc/checksums.ini +++ b/build/pkgs/cbc/checksums.ini @@ -1,5 +1,5 @@ tarball=cbc-VERSION.tar.gz -sha1=1af3d6f09e584c02d7d3e89fe1e3e88bcdc29128 -md5=8a2eb3185e033b9cf61ca02c30090f37 -cksum=2353193016 +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 c63c9a75248..9fdd305a8e4 100644 --- a/build/pkgs/cbc/package-version.txt +++ b/build/pkgs/cbc/package-version.txt @@ -1 +1 @@ -2.10.8 +2.10.10