Skip to content

Commit 927c46c

Browse files
committed
Add 'mixed' option to standard form writer
1 parent 4103225 commit 927c46c

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

pyomo/repn/plugins/standard_form.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ class LinearStandardFormCompiler(object):
139139
description='Add slack variables and return `min cTx s.t. Ax == b`',
140140
),
141141
)
142+
CONFIG.declare(
143+
'mixed_form',
144+
ConfigValue(
145+
default=False,
146+
domain=bool,
147+
description='Return A in mixed form (the comparison operator is a '
148+
'mix of <=, ==, and >=)',
149+
),
150+
)
142151
CONFIG.declare(
143152
'show_section_timing',
144153
ConfigValue(
@@ -332,6 +341,9 @@ def write(self, model):
332341
# Tabulate constraints
333342
#
334343
slack_form = self.config.slack_form
344+
mixed_form = self.config.mixed_form
345+
if slack_form and mixed_form:
346+
raise ValueError("cannot specify both slack_form and mixed_form")
335347
rows = []
336348
rhs = []
337349
con_data = []
@@ -372,7 +384,30 @@ def write(self, model):
372384
f"model contains a trivially infeasible constraint, '{con.name}'"
373385
)
374386

375-
if slack_form:
387+
if mixed_form:
388+
N = len(repn.linear)
389+
_data = np.fromiter(repn.linear.values(), float, N)
390+
_index = np.fromiter(map(var_order.__getitem__, repn.linear), float, N)
391+
if ub == lb:
392+
rows.append(RowEntry(con, 0))
393+
rhs.append(ub - offset)
394+
con_data.append(_data)
395+
con_index.append(_index)
396+
con_index_ptr.append(con_index_ptr[-1] + N)
397+
else:
398+
if ub is not None:
399+
rows.append(RowEntry(con, 1))
400+
rhs.append(ub - offset)
401+
con_data.append(_data)
402+
con_index.append(_index)
403+
con_index_ptr.append(con_index_ptr[-1] + N)
404+
if lb is not None:
405+
rows.append(RowEntry(con, -1))
406+
rhs.append(lb - offset)
407+
con_data.append(_data)
408+
con_index.append(_index)
409+
con_index_ptr.append(con_index_ptr[-1] + N)
410+
elif slack_form:
376411
_data = list(repn.linear.values())
377412
_index = list(map(var_order.__getitem__, repn.linear))
378413
if lb == ub: # TODO: add tolerance?

0 commit comments

Comments
 (0)