@@ -1240,7 +1240,7 @@ def is_optimal(self, *x):
1240
1240
sage: P.is_optimal(501, -3)
1241
1241
False
1242
1242
"""
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 )
1244
1244
1245
1245
def n_constraints (self ):
1246
1246
r"""
@@ -1555,26 +1555,31 @@ def plot_feasible_set(self, xmin=None, xmax=None, ymin=None, ymax=None,
1555
1555
result .set_aspect_ratio (1 )
1556
1556
return result
1557
1557
1558
- def standard_form (self , ** kwds ):
1558
+ def standard_form (self , transformation = False , ** kwds ):
1559
1559
r"""
1560
1560
Construct the LP problem in standard form equivalent to ``self``.
1561
1561
1562
1562
INPUT:
1563
1563
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
+
1564
1568
- you can pass (as keywords only) ``slack_variables``,
1565
1569
``auxiliary_variable``,``objective_name`` to the constructor of
1566
1570
:class:`InteractiveLPProblemStandardForm`
1567
1571
1568
1572
OUTPUT:
1569
1573
1570
- - an :class:`InteractiveLPProblemStandardForm`
1574
+ - an :class:`InteractiveLPProblemStandardForm` by itself or a tuple
1575
+ with variable transformation as the second component
1571
1576
1572
1577
EXAMPLES::
1573
1578
1574
1579
sage: A = ([1, 1], [3, 1])
1575
1580
sage: b = (1000, 1500)
1576
1581
sage: c = (10, 5)
1577
- sage: P = InteractiveLPProblem(A, b, c, ["C", "B"], variable_type=">=")
1582
+ sage: P = InteractiveLPProblem(A, b, c, variable_type=">=")
1578
1583
sage: DP = P.dual()
1579
1584
sage: DPSF = DP.standard_form()
1580
1585
sage: DPSF.b()
@@ -1584,8 +1589,38 @@ def standard_form(self, **kwds):
1584
1589
sage: DPSF = DP.standard_form(slack_variables=["L", "F"])
1585
1590
sage: DPSF.slack_variables()
1586
1591
(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
1587
1621
"""
1588
1622
A , b , c , x = self .Abcx ()
1623
+ f = identity_matrix (self .n ()).columns ()
1589
1624
if not all (ct == "<=" for ct in self ._constraint_types ):
1590
1625
newA = []
1591
1626
newb = []
@@ -1602,11 +1637,14 @@ def standard_form(self, **kwds):
1602
1637
newA = []
1603
1638
newc = []
1604
1639
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 ):
1606
1643
xj = str (xj )
1607
1644
if vt in [">=" , "" ]:
1608
1645
newA .append (Aj )
1609
1646
newc .append (cj )
1647
+ newf .append (fj )
1610
1648
if vt == ">=" :
1611
1649
newx .append (xj )
1612
1650
if vt == "" :
@@ -1615,9 +1653,11 @@ def standard_form(self, **kwds):
1615
1653
newA .append (- Aj )
1616
1654
newc .append (- cj )
1617
1655
newx .append (xj + "_n" )
1656
+ newf .append (- fj )
1618
1657
A = column_matrix (newA )
1619
1658
c = vector (newc )
1620
1659
x = newx
1660
+ f = newf
1621
1661
1622
1662
objective_name = SR (kwds .get ("objective_name" , default_variable_name (
1623
1663
"primal objective" if self .is_primal () else "dual objective" )))
@@ -1629,7 +1669,9 @@ def standard_form(self, **kwds):
1629
1669
kwds ["objective_name" ] = objective_name
1630
1670
kwds ["problem_type" ] = "-max" if is_negative else "max"
1631
1671
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
1633
1675
1634
1676
def value (self , * x ):
1635
1677
r"""
0 commit comments