Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit f2e52f8

Browse files
committed
Return coordinate transformation for problems in standard form.
1 parent 5fd3547 commit f2e52f8

File tree

1 file changed

+48
-6
lines changed

1 file changed

+48
-6
lines changed

src/sage/numerical/interactive_simplex_method.py

+48-6
Original file line numberDiff line numberDiff line change
@@ -1240,7 +1240,7 @@ def is_optimal(self, *x):
12401240
sage: P.is_optimal(501, -3)
12411241
False
12421242
"""
1243-
return self.optimal_value() == self.value(x) and self.is_feasible(x)
1243+
return self.optimal_value() == self.value(*x) and self.is_feasible(*x)
12441244

12451245
def n_constraints(self):
12461246
r"""
@@ -1555,26 +1555,31 @@ def plot_feasible_set(self, xmin=None, xmax=None, ymin=None, ymax=None,
15551555
result.set_aspect_ratio(1)
15561556
return result
15571557

1558-
def standard_form(self, **kwds):
1558+
def standard_form(self, transformation=False, **kwds):
15591559
r"""
15601560
Construct the LP problem in standard form equivalent to ``self``.
15611561
15621562
INPUT:
15631563
1564+
- ``transformation`` -- (default: ``False``) if ``True``, a map
1565+
converting solutions of the problem in standard form to the original
1566+
one will be returned as well
1567+
15641568
- you can pass (as keywords only) ``slack_variables``,
15651569
``auxiliary_variable``,``objective_name`` to the constructor of
15661570
:class:`InteractiveLPProblemStandardForm`
15671571
15681572
OUTPUT:
15691573
1570-
- an :class:`InteractiveLPProblemStandardForm`
1574+
- an :class:`InteractiveLPProblemStandardForm` by itself or a tuple
1575+
with variable transformation as the second component
15711576
15721577
EXAMPLES::
15731578
15741579
sage: A = ([1, 1], [3, 1])
15751580
sage: b = (1000, 1500)
15761581
sage: c = (10, 5)
1577-
sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=")
1582+
sage: P = InteractiveLPProblem(A, b, c, variable_type=">=")
15781583
sage: DP = P.dual()
15791584
sage: DPSF = DP.standard_form()
15801585
sage: DPSF.b()
@@ -1584,8 +1589,38 @@ def standard_form(self, **kwds):
15841589
sage: DPSF = DP.standard_form(slack_variables=["L", "F"])
15851590
sage: DPSF.slack_variables()
15861591
(L, F)
1592+
sage: DPSF, f = DP.standard_form(True)
1593+
sage: f
1594+
Vector space morphism represented by the matrix:
1595+
[1 0]
1596+
[0 1]
1597+
Domain: Vector space of dimension 2 over Rational Field
1598+
Codomain: Vector space of dimension 2 over Rational Field
1599+
1600+
A more complicated transfromation map::
1601+
1602+
sage: P = InteractiveLPProblem(A, b, c, variable_type=["<=", ""])
1603+
sage: PSF, f = P.standard_form(True)
1604+
sage: f
1605+
Vector space morphism represented by the matrix:
1606+
[-1 0]
1607+
[ 0 1]
1608+
[ 0 -1]
1609+
Domain: Vector space of dimension 3 over Rational Field
1610+
Codomain: Vector space of dimension 2 over Rational Field
1611+
sage: PSF.optimal_solution()
1612+
(0, 1000, 0)
1613+
sage: P.optimal_solution()
1614+
(0, 1000)
1615+
sage: P.is_optimal(PSF.optimal_solution())
1616+
Traceback (most recent call last):
1617+
...
1618+
TypeError: given input is not a solution for this problem
1619+
sage: P.is_optimal(f(PSF.optimal_solution()))
1620+
True
15871621
"""
15881622
A, b, c, x = self.Abcx()
1623+
f = identity_matrix(self.n()).columns()
15891624
if not all(ct == "<=" for ct in self._constraint_types):
15901625
newA = []
15911626
newb = []
@@ -1602,11 +1637,14 @@ def standard_form(self, **kwds):
16021637
newA = []
16031638
newc = []
16041639
newx = []
1605-
for vt, Aj, cj, xj in zip(self._variable_types, A.columns(), c, x):
1640+
newf = []
1641+
for vt, Aj, cj, xj, fj in zip(
1642+
self._variable_types, A.columns(), c, x, f):
16061643
xj = str(xj)
16071644
if vt in [">=", ""]:
16081645
newA.append(Aj)
16091646
newc.append(cj)
1647+
newf.append(fj)
16101648
if vt == ">=":
16111649
newx.append(xj)
16121650
if vt == "":
@@ -1615,9 +1653,11 @@ def standard_form(self, **kwds):
16151653
newA.append(-Aj)
16161654
newc.append(-cj)
16171655
newx.append(xj + "_n")
1656+
newf.append(-fj)
16181657
A = column_matrix(newA)
16191658
c = vector(newc)
16201659
x = newx
1660+
f = newf
16211661

16221662
objective_name = SR(kwds.get("objective_name", default_variable_name(
16231663
"primal objective" if self.is_primal() else "dual objective")))
@@ -1629,7 +1669,9 @@ def standard_form(self, **kwds):
16291669
kwds["objective_name"] = objective_name
16301670
kwds["problem_type"] = "-max" if is_negative else "max"
16311671
kwds["is_primal"] = self.is_primal()
1632-
return InteractiveLPProblemStandardForm(A, b, c, x, **kwds)
1672+
P = InteractiveLPProblemStandardForm(A, b, c, x, **kwds)
1673+
f = P.c().parent().hom(f, self.c().parent())
1674+
return (P, f) if transformation else P
16331675

16341676
def value(self, *x):
16351677
r"""

0 commit comments

Comments
 (0)