Skip to content

Commit

Permalink
Merge branch 'main' into benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
blnicho authored Dec 19, 2023
2 parents 934b153 + d5b53d5 commit 973fb23
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 56 deletions.
4 changes: 2 additions & 2 deletions doc/OnlineDocs/contributed_packages/doe/doe.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ It allows users to define any number of design decisions. Heatmaps can be drawn
The function ``run_grid_search`` enumerates over the design space, each MBDoE problem accomplished by ``compute_FIM`` method.
Therefore, ``run_grid_search`` supports only two modes: ``sequential_finite`` and ``direct_kaug``.

.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_FIM.py
.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_grid_search.py
:language: python
:pyobject: main

Expand All @@ -284,7 +284,7 @@ Pyomo.DoE accomplishes gradient-based optimization with the ``stochastic_program

This function solves twice: It solves the square version of the MBDoE problem first, and then unfixes the design variables as degree of freedoms and solves again. In this way the optimization problem can be well initialized.

.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_FIM.py
.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_optimize_doe.py
:language: python
:pyobject: main

Expand Down
1 change: 0 additions & 1 deletion doc/OnlineDocs/model_debugging/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ Debugging Pyomo Models
model_interrogation.rst
FAQ.rst
getting_help.rst
latex_printing.rst
8 changes: 3 additions & 5 deletions pyomo/contrib/incidence_analysis/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ class IncidenceMethod(enum.Enum):
_linear_only = ConfigValue(
default=False,
domain=bool,
description="Identify variables that participate linearly",
description="Identify only variables that participate linearly",
doc=(
"Flag indicating whether only variables that participate linearly should"
" be included. Note that these are included even if they participate"
" nonlinearly as well."
" be included."
),
)

Expand All @@ -61,8 +60,7 @@ class IncidenceMethod(enum.Enum):
- ``include_fixed`` -- Flag indicating whether fixed variables should be included
in the incidence graph
- ``linear_only`` -- Flag indicating whether only variables that participate linearly
should be included. Note that these are included even if they participate
nonlinearly as well
should be included.
- ``method`` -- Method used to identify incident variables. Must be a value of the
``IncidenceMethod`` enum.
Expand Down
18 changes: 11 additions & 7 deletions pyomo/core/base/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def __contains__(self, value):
return False

if self.step:
_dir = math.copysign(1, self.step)
_dir = int(math.copysign(1, self.step))
_from_start = value - self.start
return (
0 <= _dir * _from_start <= _dir * (self.end - self.start)
Expand Down Expand Up @@ -411,14 +411,13 @@ def _split_ranges(cnr, new_step):

assert new_step >= abs(cnr.step)
assert new_step % cnr.step == 0
_dir = math.copysign(1, cnr.step)
_dir = int(math.copysign(1, cnr.step))
_subranges = []
for i in range(int(abs(new_step // cnr.step))):
if _dir * (cnr.start + i * cnr.step) > _dir * cnr.end:
# Once we walk past the end of the range, we are done
# (all remaining offsets will be farther past the end)
break

_subranges.append(
NumericRange(cnr.start + i * cnr.step, cnr.end, _dir * new_step)
)
Expand Down Expand Up @@ -458,7 +457,7 @@ def _step_lcm(self, other_ranges):
else:
# one of the steps was 0: add to preserve the non-zero step
a += b
return abs(a)
return int(abs(a))

def _push_to_discrete_element(self, val, push_to_next_larger_value):
if not self.step or val in _infinite:
Expand Down Expand Up @@ -557,9 +556,14 @@ def range_difference(self, other_ranges):
NumericRange(t.start, start, 0, (t.closed[0], False))
)
if s.step: # i.e., not a single point
for i in range(int(start // s.step), int(end // s.step)):
for i in range(int((end - start) // s.step)):
_new_subranges.append(
NumericRange(i * s.step, (i + 1) * s.step, 0, '()')
NumericRange(
start + i * s.step,
start + (i + 1) * s.step,
0,
'()',
)
)
if t.end > end:
_new_subranges.append(
Expand Down Expand Up @@ -605,7 +609,7 @@ def range_difference(self, other_ranges):
)
elif t_max == s_max and t_c[1] and not s_c[1]:
_new_subranges.append(NumericRange(t_max, t_max, 0))
_this = _new_subranges
_this = _new_subranges
return _this

def range_intersection(self, other_ranges):
Expand Down
58 changes: 28 additions & 30 deletions pyomo/core/base/set.py
Original file line number Diff line number Diff line change
Expand Up @@ -1584,28 +1584,26 @@ def _to_0_based_index(self, item):
# implementation does not guarantee that the index is valid (it
# could be outside of abs(i) <= len(self)).
try:
if item != int(item):
raise IndexError(
"%s indices must be integers, not %s"
% (self.name, type(item).__name__)
)
item = int(item)
_item = int(item)
if item != _item:
raise IndexError()
except:
raise IndexError(
"%s indices must be integers, not %s" % (self.name, type(item).__name__)
)

if item >= 1:
return item - 1
elif item < 0:
item += len(self)
if item < 0:
raise IndexError("%s index out of range" % (self.name,))
return item
f"Set '{self.name}' positional indices must be integers, "
f"not {type(item).__name__}"
) from None

if _item >= 1:
return _item - 1
elif _item < 0:
_item += len(self)
if _item < 0:
raise IndexError(f"{self.name} index out of range")
return _item
else:
raise IndexError(
"Pyomo Sets are 1-indexed: valid index values for Sets are "
"[1 .. len(Set)] or [-1 .. -len(Set)]"
"Accessing Pyomo Sets by position is 1-based: valid Set positional "
"index values are [1 .. len(Set)] or [-1 .. -len(Set)]"
)


Expand Down Expand Up @@ -1683,7 +1681,7 @@ def at(self, index):
try:
return self._ordered_values[i]
except IndexError:
raise IndexError("%s index out of range" % (self.name))
raise IndexError(f"{self.name} index out of range") from None

def ord(self, item):
"""
Expand Down Expand Up @@ -2023,7 +2021,7 @@ def __init__(
filter=None,
validate=None,
name=None,
doc=None
doc=None,
):
...

Expand Down Expand Up @@ -2545,7 +2543,7 @@ def at(self, index):
try:
return self._ref[i]
except IndexError:
raise IndexError("%s index out of range" % (self.name))
raise IndexError(f"{self.name} index out of range") from None

def ord(self, item):
# The bulk of single-value set members are stored as scalars.
Expand Down Expand Up @@ -2686,7 +2684,7 @@ def at(self, index):
if not idx:
return ans
idx -= 1
raise IndexError("%s index out of range" % (self.name,))
raise IndexError(f"{self.name} index out of range")

def ord(self, item):
if len(self._ranges) == 1:
Expand Down Expand Up @@ -2861,7 +2859,7 @@ def __init__(
filter=None,
validate=None,
name=None,
doc=None
doc=None,
):
...

Expand All @@ -2878,7 +2876,7 @@ def __init__(
filter=None,
validate=None,
name=None,
doc=None
doc=None,
):
...

Expand All @@ -2892,7 +2890,7 @@ def __init__(
filter=None,
validate=None,
name=None,
doc=None
doc=None,
):
...

Expand Down Expand Up @@ -3505,7 +3503,7 @@ def at(self, index):
if val not in self._sets[0]:
idx -= 1
except StopIteration:
raise IndexError("%s index out of range" % (self.name,))
raise IndexError(f"{self.name} index out of range") from None
return val

def ord(self, item):
Expand Down Expand Up @@ -3642,7 +3640,7 @@ def at(self, index):
idx -= 1
return next(_iter)
except StopIteration:
raise IndexError("%s index out of range" % (self.name,))
raise IndexError(f"{self.name} index out of range") from None

def ord(self, item):
"""
Expand Down Expand Up @@ -3736,7 +3734,7 @@ def at(self, index):
idx -= 1
return next(_iter)
except StopIteration:
raise IndexError("%s index out of range" % (self.name,))
raise IndexError(f"{self.name} index out of range") from None

def ord(self, item):
"""
Expand Down Expand Up @@ -3846,7 +3844,7 @@ def at(self, index):
idx -= 1
return next(_iter)
except StopIteration:
raise IndexError("%s index out of range" % (self.name,))
raise IndexError(f"{self.name} index out of range") from None

def ord(self, item):
"""
Expand Down Expand Up @@ -4128,7 +4126,7 @@ def at(self, index):
i -= 1
_ord[i], _idx = _idx % _ord[i], _idx // _ord[i]
if _idx:
raise IndexError("%s index out of range" % (self.name,))
raise IndexError(f"{self.name} index out of range")
ans = tuple(s.at(i + 1) for s, i in zip(self._sets, _ord))
if FLATTEN_CROSS_PRODUCT and normalize_index.flatten and self.dimen != len(ans):
return self._flatten_product(ans)
Expand Down
50 changes: 40 additions & 10 deletions pyomo/core/tests/unit/test_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -1530,8 +1530,8 @@ def test_ordered_setof(self):
self.assertEqual(i[-1], 0)
with self.assertRaisesRegex(
IndexError,
"valid index values for Sets are "
r"\[1 .. len\(Set\)\] or \[-1 .. -len\(Set\)\]",
"Accessing Pyomo Sets by position is 1-based: valid Set positional "
r"index values are \[1 .. len\(Set\)\] or \[-1 .. -len\(Set\)\]",
):
i[0]
with self.assertRaisesRegex(IndexError, "OrderedSetOf index out of range"):
Expand Down Expand Up @@ -1589,8 +1589,8 @@ def test_ordered_setof(self):
self.assertEqual(i[-1], 0)
with self.assertRaisesRegex(
IndexError,
"valid index values for Sets are "
r"\[1 .. len\(Set\)\] or \[-1 .. -len\(Set\)\]",
"Accessing Pyomo Sets by position is 1-based: valid Set positional "
r"index values are \[1 .. len\(Set\)\] or \[-1 .. -len\(Set\)\]",
):
i[0]
with self.assertRaisesRegex(IndexError, "OrderedSetOf index out of range"):
Expand Down Expand Up @@ -1752,8 +1752,8 @@ def test_ord_index(self):
self.assertEqual(r[i + 1], v)
with self.assertRaisesRegex(
IndexError,
"valid index values for Sets are "
r"\[1 .. len\(Set\)\] or \[-1 .. -len\(Set\)\]",
"Accessing Pyomo Sets by position is 1-based: valid Set positional "
r"index values are \[1 .. len\(Set\)\] or \[-1 .. -len\(Set\)\]",
):
r[0]
with self.assertRaisesRegex(
Expand All @@ -1769,8 +1769,8 @@ def test_ord_index(self):
self.assertEqual(r[i + 1], v)
with self.assertRaisesRegex(
IndexError,
"valid index values for Sets are "
r"\[1 .. len\(Set\)\] or \[-1 .. -len\(Set\)\]",
"Accessing Pyomo Sets by position is 1-based: valid Set positional "
r"index values are \[1 .. len\(Set\)\] or \[-1 .. -len\(Set\)\]",
):
r[0]
with self.assertRaisesRegex(
Expand Down Expand Up @@ -2647,6 +2647,34 @@ def test_infinite_setdifference(self):
list(RangeSet(ranges=[NR(0, 2, 0, (True, False))]).ranges()),
)

x = RangeSet(0, 6, 0) - RangeSet(1, 5, 2)
self.assertIs(type(x), SetDifference_InfiniteSet)
self.assertFalse(x.isfinite())
self.assertFalse(x.isordered())

self.assertIn(0, x)
self.assertNotIn(1, x)
self.assertIn(2, x)
self.assertNotIn(3, x)
self.assertIn(4, x)
self.assertNotIn(5, x)
self.assertIn(6, x)
self.assertNotIn(7, x)

self.assertEqual(
list(x.ranges()),
list(
RangeSet(
ranges=[
NR(0, 1, 0, (True, False)),
NR(1, 3, 0, (False, False)),
NR(3, 5, 0, (False, False)),
NR(5, 6, 0, (False, True)),
]
).ranges()
),
)


class TestSetSymmetricDifference(unittest.TestCase):
def test_pickle(self):
Expand Down Expand Up @@ -4191,10 +4219,12 @@ def test_indexing(self):
m.I = [1, 3, 2]
self.assertEqual(m.I[2], 3)
with self.assertRaisesRegex(
IndexError, "I indices must be integers, not float"
IndexError, "Set 'I' positional indices must be integers, not float"
):
m.I[2.5]
with self.assertRaisesRegex(IndexError, "I indices must be integers, not str"):
with self.assertRaisesRegex(
IndexError, "Set 'I' positional indices must be integers, not str"
):
m.I['a']

def test_add_filter_validate(self):
Expand Down
4 changes: 3 additions & 1 deletion pyomo/core/tests/unit/test_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -3395,7 +3395,9 @@ def test_getitem(self):
with self.assertRaisesRegex(RuntimeError, ".*before it has been constructed"):
a[0]
a.construct()
with self.assertRaisesRegex(IndexError, "Pyomo Sets are 1-indexed"):
with self.assertRaisesRegex(
IndexError, "Accessing Pyomo Sets by position is 1-based"
):
a[0]
self.assertEqual(a[1], 2)

Expand Down

0 comments on commit 973fb23

Please sign in to comment.