Skip to content

Commit 8b8f6e5

Browse files
authored
Merge branch 'main' into xpress_slack_bug
2 parents 402784b + 25d5910 commit 8b8f6e5

File tree

4 files changed

+91
-15
lines changed

4 files changed

+91
-15
lines changed

pyomo/neos/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
'minos': 'SLC NLP solver',
3131
'minto': 'MILP solver',
3232
'mosek': 'Interior point NLP solver',
33-
'octeract': 'Deterministic global MINLP solver',
33+
#'octeract': 'Deterministic global MINLP solver',
3434
'ooqp': 'Convex QP solver',
3535
'path': 'Nonlinear MCP solver',
3636
'snopt': 'SQP NLP solver',

pyomo/neos/tests/test_neos.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ def test_doc(self):
7979
doc = pyomo.neos.doc
8080
dockeys = set(doc.keys())
8181

82+
# Octeract interface is disabled, see #3321
83+
amplsolvers.remove('octeract')
84+
8285
self.assertEqual(amplsolvers, dockeys)
8386

8487
# gamssolvers = set(v[0].lower() for v in tmp if v[1]=='GAMS')
@@ -149,8 +152,11 @@ def test_minto(self):
149152
def test_mosek(self):
150153
self._run('mosek')
151154

152-
def test_octeract(self):
153-
self._run('octeract')
155+
# [16 Jul 24] Octeract is erroring. We will disable the interface
156+
# (and testing) until we have time to resolve #3321
157+
#
158+
# def test_octeract(self):
159+
# self._run('octeract')
154160

155161
def test_ooqp(self):
156162
if self.sense == pyo.maximize:

pyomo/repn/plugins/nl_writer.py

+13-12
Original file line numberDiff line numberDiff line change
@@ -1988,6 +1988,18 @@ def _record_named_expression_usage(self, named_exprs, src, comp_type):
19881988
elif info[comp_type] != src:
19891989
info[comp_type] = 0
19901990

1991+
def _resolve_subexpression_args(self, nl, args):
1992+
final_args = []
1993+
for arg in args:
1994+
if arg in self.var_id_to_nl_map:
1995+
final_args.append(self.var_id_to_nl_map[arg])
1996+
else:
1997+
_nl, _ids, _ = self.subexpression_cache[arg][1].compile_repn(
1998+
self.visitor
1999+
)
2000+
final_args.append(self._resolve_subexpression_args(_nl, _ids))
2001+
return nl % tuple(final_args)
2002+
19912003
def _write_nl_expression(self, repn, include_const):
19922004
# Note that repn.mult should always be 1 (the AMPLRepn was
19932005
# compiled before this point). Omitting the assertion for
@@ -2007,18 +2019,7 @@ def _write_nl_expression(self, repn, include_const):
20072019
nl % tuple(map(self.var_id_to_nl_map.__getitem__, args))
20082020
)
20092021
except KeyError:
2010-
final_args = []
2011-
for arg in args:
2012-
if arg in self.var_id_to_nl_map:
2013-
final_args.append(self.var_id_to_nl_map[arg])
2014-
else:
2015-
_nl, _ids, _ = self.subexpression_cache[arg][1].compile_repn(
2016-
self.visitor
2017-
)
2018-
final_args.append(
2019-
_nl % tuple(map(self.var_id_to_nl_map.__getitem__, _ids))
2020-
)
2021-
self.ostream.write(nl % tuple(final_args))
2022+
self.ostream.write(self._resolve_subexpression_args(nl, args))
20222023

20232024
elif include_const:
20242025
self.ostream.write(self.template.const % repn.const)

pyomo/repn/tests/ampl/test_nlv2.py

+69
Original file line numberDiff line numberDiff line change
@@ -2703,3 +2703,72 @@ def test_presolve_check_invalid_monomial_constraints(self):
27032703
r"\(fixed body value 5.0 outside bounds \[10, None\]\)\.",
27042704
):
27052705
nl_writer.NLWriter().write(m, OUT, linear_presolve=True)
2706+
2707+
def test_nested_external_expressions(self):
2708+
# This tests nested external functions in a single expression
2709+
DLL = find_GSL()
2710+
if not DLL:
2711+
self.skipTest("Could not find the amplgsl.dll library")
2712+
2713+
m = ConcreteModel()
2714+
m.hypot = ExternalFunction(library=DLL, function="gsl_hypot")
2715+
m.p = Param(initialize=1, mutable=True)
2716+
m.x = Var(bounds=(None, 3))
2717+
m.y = Var(bounds=(3, None))
2718+
m.z = Var(initialize=1)
2719+
m.o = Objective(expr=m.z**2 * m.hypot(m.z, m.hypot(m.x, m.y)) ** 2)
2720+
m.c = Constraint(expr=m.x == m.y)
2721+
2722+
OUT = io.StringIO()
2723+
nl_writer.NLWriter().write(
2724+
m, OUT, symbolic_solver_labels=True, linear_presolve=False
2725+
)
2726+
self.assertEqual(
2727+
*nl_diff(
2728+
"""g3 1 1 0 #problem unknown
2729+
3 1 1 0 1 #vars, constraints, objectives, ranges, eqns
2730+
0 1 0 0 0 0 #nonlinear constrs, objs; ccons: lin, nonlin, nd, nzlb
2731+
0 0 #network constraints: nonlinear, linear
2732+
0 3 0 #nonlinear vars in constraints, objectives, both
2733+
0 1 0 1 #linear network variables; functions; arith, flags
2734+
0 0 0 0 0 #discrete variables: binary, integer, nonlinear (b,c,o)
2735+
2 3 #nonzeros in Jacobian, obj. gradient
2736+
1 1 #max name lengths: constraints, variables
2737+
0 0 0 0 0 #common exprs: b,c,o,c1,o1
2738+
F0 1 -1 gsl_hypot
2739+
C0 #c
2740+
n0
2741+
O0 0 #o
2742+
o2 #*
2743+
o5 #^
2744+
v0 #z
2745+
n2
2746+
o5 #^
2747+
f0 2 #hypot
2748+
v0 #z
2749+
f0 2 #hypot
2750+
v1 #x
2751+
v2 #y
2752+
n2
2753+
x1 #initial guess
2754+
0 1 #z
2755+
r #1 ranges (rhs's)
2756+
4 0 #c
2757+
b #3 bounds (on variables)
2758+
3 #z
2759+
1 3 #x
2760+
2 3 #y
2761+
k2 #intermediate Jacobian column lengths
2762+
0
2763+
1
2764+
J0 2 #c
2765+
1 1
2766+
2 -1
2767+
G0 3 #o
2768+
0 0
2769+
1 0
2770+
2 0
2771+
""",
2772+
OUT.getvalue(),
2773+
)
2774+
)

0 commit comments

Comments
 (0)