@@ -52,19 +52,22 @@ cdef class InteractiveLPBackend:
52
52
This backend can work with irrational algebraic numbers::
53
53
54
54
sage: poly = polytopes.dodecahedron(base_ring=AA)
55
- sage: lp = poly.to_linear_program(solver='InteractiveLP')
56
- sage: b = lp.get_backend()
57
- sage: for k in range(3): b.variable_lower_bound(k, 0)
58
- sage: b.set_objective([1, 1, 1])
55
+ sage: lp, x = poly.to_linear_program(solver='InteractiveLP', return_variable=True)
56
+ sage: lp.set_objective(x[0] + x[1] + x[2])
59
57
sage: lp.solve()
60
58
2.291796067500631?
61
- sage: [b.get_variable_value(k) for k in range(3)]
59
+ sage: lp.get_values(x[0], x[1], x[2])
62
60
[0.763932022500211?, 0.763932022500211?, 0.763932022500211?]
61
+ sage: lp.set_objective(x[0] - x[1] - x[2])
62
+ sage: lp.solve()
63
+ 2.291796067500631?
64
+ sage: lp.get_values(x[0], x[1], x[2])
65
+ [0.763932022500211?, -0.763932022500211?, -0.763932022500211?]
63
66
"""
64
67
65
68
if base_ring is None :
66
- from sage.rings.all import AA
67
- base_ring = AA
69
+ from sage.rings.all import QQ
70
+ base_ring = QQ
68
71
69
72
self .lp = InteractiveLPProblem([], [], [], base_ring = base_ring)
70
73
self .set_verbosity(0 )
@@ -74,8 +77,6 @@ cdef class InteractiveLPBackend:
74
77
else :
75
78
self .set_sense(- 1 )
76
79
77
- self .obj_constant_term = 0
78
-
79
80
self .row_names = []
80
81
81
82
cpdef base_ring(self ):
@@ -91,7 +92,7 @@ cdef class InteractiveLPBackend:
91
92
sage: from sage.numerical.backends.generic_backend import get_solver
92
93
sage: p = get_solver(solver = "InteractiveLP")
93
94
sage: p.base_ring()
94
- Algebraic Real Field
95
+ Rational Field
95
96
"""
96
97
return self .lp.base_ring()
97
98
@@ -196,7 +197,7 @@ cdef class InteractiveLPBackend:
196
197
sage: p.objective_coefficient(1)
197
198
1
198
199
"""
199
- A, b, c, x, constraint_types, variable_types, problem_type, ring = self ._AbcxCVPR ()
200
+ A, b, c, x, constraint_types, variable_types, problem_type, ring, d = self ._AbcxCVPRd ()
200
201
cdef int vtype = int (binary) + int (continuous) + int (integer)
201
202
if vtype == 0 :
202
203
continuous = True
@@ -219,7 +220,7 @@ cdef class InteractiveLPBackend:
219
220
x = tuple (x) + (name,)
220
221
self .lp = InteractiveLPProblem(A, b, c, x,
221
222
constraint_types, variable_types,
222
- problem_type, ring)
223
+ problem_type, ring, objective_constant_term = d )
223
224
return self .ncols() - 1
224
225
225
226
cpdef int add_variables(self , int n, lower_bound = 0 , upper_bound = None , binary = False , continuous = True , integer = False , obj = None , names = None ) except - 1 :
@@ -298,23 +299,24 @@ cdef class InteractiveLPBackend:
298
299
else :
299
300
raise NotImplementedError ()
300
301
301
- def _AbcxCVPR (self ):
302
+ def _AbcxCVPRd (self ):
302
303
"""
303
304
Retrieve all problem data from the LP.
304
305
305
306
EXAMPLE::
306
307
307
308
sage: from sage.numerical.backends.generic_backend import get_solver
308
309
sage: p = get_solver(solver = "InteractiveLP")
309
- sage: p._AbcxCVPR ()
310
- ([], (), (), (), (), (), 'max', Algebraic Real Field)
310
+ sage: p._AbcxCVPRd ()
311
+ ([], (), (), (), (), (), 'max', Rational Field, 0 )
311
312
"""
312
313
A, b, c, x = self .lp.Abcx()
313
314
constraint_types = self .lp.constraint_types()
314
315
variable_types = self .lp.variable_types()
315
316
problem_type = self .lp.problem_type()
316
317
base_ring = self .lp.base_ring()
317
- return A, b, c, x, constraint_types, variable_types, problem_type, base_ring
318
+ d = self .lp.objective_constant_term()
319
+ return A, b, c, x, constraint_types, variable_types, problem_type, base_ring, d
318
320
319
321
cpdef set_sense(self , int sense):
320
322
"""
@@ -337,14 +339,14 @@ cdef class InteractiveLPBackend:
337
339
sage: p.is_maximization()
338
340
False
339
341
"""
340
- A, b, c, x, constraint_types, variable_types, problem_type, ring = self ._AbcxCVPR ()
342
+ A, b, c, x, constraint_types, variable_types, problem_type, ring, d = self ._AbcxCVPRd ()
341
343
if sense == + 1 :
342
344
problem_type = " max"
343
345
else :
344
346
problem_type = " min"
345
347
self .lp = InteractiveLPProblem(A, b, c, x,
346
348
constraint_types, variable_types,
347
- problem_type, ring)
349
+ problem_type, ring, objective_constant_term = d )
348
350
349
351
cpdef objective_coefficient(self , int variable, coeff = None ):
350
352
"""
@@ -372,12 +374,38 @@ cdef class InteractiveLPBackend:
372
374
if coeff is None :
373
375
return self .lp.objective_coefficients()[variable]
374
376
else :
375
- A, b, c, x, constraint_types, variable_types, problem_type, ring = self ._AbcxCVPR ()
377
+ A, b, c, x, constraint_types, variable_types, problem_type, ring, d = self ._AbcxCVPRd ()
376
378
c = list (c)
377
379
c[variable] = coeff
378
380
self .lp = InteractiveLPProblem(A, b, c, x,
379
381
constraint_types, variable_types,
380
- problem_type, ring)
382
+ problem_type, ring, objective_constant_term = d)
383
+
384
+ cpdef objective_constant_term(self , d = None ):
385
+ """
386
+ Set or get the constant term in the objective function
387
+
388
+ INPUT:
389
+
390
+ - ``d`` (double) -- its coefficient. If `None` (default), return the current value.
391
+
392
+ EXAMPLE::
393
+
394
+ sage: from sage.numerical.backends.generic_backend import get_solver
395
+ sage: p = get_solver(solver = "InteractiveLP")
396
+ sage: p.objective_constant_term()
397
+ 0
398
+ sage: p.objective_constant_term(42)
399
+ sage: p.objective_constant_term()
400
+ 42
401
+ """
402
+ if d is None :
403
+ return self .lp.objective_constant_term()
404
+ else :
405
+ A, b, c, x, constraint_types, variable_types, problem_type, ring, _ = self ._AbcxCVPRd()
406
+ self .lp = InteractiveLPProblem(A, b, c, x,
407
+ constraint_types, variable_types,
408
+ problem_type, ring, objective_constant_term = d)
381
409
382
410
cpdef set_objective(self , list coeff, d = 0 ):
383
411
"""
@@ -423,12 +451,11 @@ cdef class InteractiveLPBackend:
423
451
-47/5
424
452
425
453
"""
426
- A, b, c , x, constraint_types, variable_types, problem_type, ring = self ._AbcxCVPR ()
454
+ A, b, _ , x, constraint_types, variable_types, problem_type, ring, _ = self ._AbcxCVPRd ()
427
455
c = coeff
428
456
self .lp = InteractiveLPProblem(A, b, c, x,
429
457
constraint_types, variable_types,
430
- problem_type, ring)
431
- self .obj_constant_term = d
458
+ problem_type, ring, objective_constant_term = d)
432
459
433
460
cpdef set_verbosity(self , int level):
434
461
"""
@@ -470,13 +497,13 @@ cdef class InteractiveLPBackend:
470
497
sage: p. get_values( [x,y ])
471
498
[0, 3 ]
472
499
"""
473
- A, b, c, x, constraint_types, variable_types, problem_type, ring = self ._AbcxCVPR ()
500
+ A, b, c, x, constraint_types, variable_types, problem_type, ring, d = self ._AbcxCVPRd ()
474
501
A = A.delete_rows((i,))
475
502
b = list (b); del b[i]
476
503
constraint_types= list (constraint_types); del constraint_types[i]
477
504
self .lp = InteractiveLPProblem(A, b, c, x,
478
505
constraint_types, variable_types,
479
- problem_type, ring)
506
+ problem_type, ring, objective_constant_term = d )
480
507
481
508
cpdef add_linear_constraint(self , coefficients, lower_bound, upper_bound, name = None ):
482
509
"""
@@ -511,7 +538,7 @@ cdef class InteractiveLPBackend:
511
538
sage: p.row_name(1)
512
539
'foo'
513
540
"""
514
- A, b, c, x, constraint_types, variable_types, problem_type, ring = self ._AbcxCVPR ()
541
+ A, b, c, x, constraint_types, variable_types, problem_type, ring, d = self ._AbcxCVPRd ()
515
542
if lower_bound is None :
516
543
if upper_bound is None :
517
544
raise ValueError (" At least one of lower_bound and upper_bound must be provided" )
@@ -537,7 +564,7 @@ cdef class InteractiveLPBackend:
537
564
538
565
self .lp = InteractiveLPProblem(A, b, c, x,
539
566
constraint_types, variable_types,
540
- problem_type, ring)
567
+ problem_type, ring, objective_constant_term = d )
541
568
542
569
543
570
cpdef add_col(self , list indices, list coeffs):
@@ -633,7 +660,8 @@ cdef class InteractiveLPBackend:
633
660
"""
634
661
# # FIXME: standard_form should allow to pass slack names (which we would take from row_names).
635
662
# # FIXME: Perhaps also pass the problem name as objective name
636
- lp_std_form = self .lp_std_form = self .lp.standard_form()
663
+ lp_std_form, transformation = self .lp.standard_form(transformation = True )
664
+ self .lp_std_form, self .std_form_transformation = lp_std_form, transformation
637
665
output = lp_std_form.run_revised_simplex_method()
638
666
# # FIXME: Display output as a side effect if verbosity is high enough
639
667
d = self .final_dictionary = lp_std_form.final_revised_dictionary()
@@ -674,7 +702,7 @@ cdef class InteractiveLPBackend:
674
702
v = d.objective_value()
675
703
if self .lp_std_form.is_negative():
676
704
v = - v
677
- return self .obj_constant_term + v
705
+ return v
678
706
679
707
cpdef get_variable_value(self , int variable):
680
708
"""
@@ -701,9 +729,8 @@ cdef class InteractiveLPBackend:
701
729
sage: p.get_variable_value(1)
702
730
3/2
703
731
"""
704
- if str (self .lp.decision_variables()[variable]) != str (self .lp_std_form.decision_variables()[variable]):
705
- raise NotImplementedError (" Undoing the standard-form transformation is not implemented" )
706
- return self .final_dictionary.basic_solution()[variable]
732
+ solution = self .std_form_transformation(self .final_dictionary.basic_solution())
733
+ return solution[variable]
707
734
708
735
cpdef int ncols(self ):
709
736
"""
@@ -1027,12 +1054,12 @@ cdef class InteractiveLPBackend:
1027
1054
else :
1028
1055
if value != bounds[1 ]:
1029
1056
bounds = (bounds[0 ], value)
1030
- A, b, c, x, constraint_types, variable_types, problem_type, ring = self ._AbcxCVPR ()
1057
+ A, b, c, x, constraint_types, variable_types, problem_type, ring, d = self ._AbcxCVPRd ()
1031
1058
variable_types = list (variable_types)
1032
1059
variable_types[index] = self ._variable_type_from_bounds(* bounds)
1033
1060
self .lp = InteractiveLPProblem(A, b, c, x,
1034
1061
constraint_types, variable_types,
1035
- problem_type, ring)
1062
+ problem_type, ring, objective_constant_term = d )
1036
1063
1037
1064
cpdef variable_lower_bound(self , int index, value = False ):
1038
1065
"""
@@ -1071,12 +1098,12 @@ cdef class InteractiveLPBackend:
1071
1098
else :
1072
1099
if value != bounds[0 ]:
1073
1100
bounds = (value, bounds[1 ])
1074
- A, b, c, x, constraint_types, variable_types, problem_type, ring = self ._AbcxCVPR ()
1101
+ A, b, c, x, constraint_types, variable_types, problem_type, ring, d = self ._AbcxCVPRd ()
1075
1102
variable_types = list (variable_types)
1076
1103
variable_types[index] = self ._variable_type_from_bounds(* bounds)
1077
1104
self .lp = InteractiveLPProblem(A, b, c, x,
1078
1105
constraint_types, variable_types,
1079
- problem_type, ring)
1106
+ problem_type, ring, objective_constant_term = d )
1080
1107
1081
1108
cpdef bint is_variable_basic(self , int index):
1082
1109
"""
0 commit comments