Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expanded expression template support #1433

Merged
merged 34 commits into from
Jun 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
379da67
Ading an indirection layer to Set.__iter__
jsiirola Apr 15, 2020
2754ab2
Updating index template to admit None as a valid value
jsiirola Apr 15, 2020
0d3c24a
Updating the string representation of GetItemExpression to use '[]'
jsiirola Apr 16, 2020
43d7ca1
Merge branch 'master' into templates
jsiirola Apr 20, 2020
a922f6e
Add the ability to templatize sum() in rules
jsiirola Apr 20, 2020
86679d4
Adding GetAttrExpression to template expressions
jsiirola Apr 20, 2020
2d71754
Consolidating template expressions in core.expr.template_expr
jsiirola Apr 20, 2020
ee22b6e
Adding a resolve_template method; flushing out TemplateSumExpression
jsiirola Apr 22, 2020
6e7557f
Adding pyomo.core.base.template_expr deprecation module
jsiirola Apr 22, 2020
8926610
Merge branch 'master' into templates
jsiirola Apr 27, 2020
f140321
Create PyomoModelingObject common base class for NumericValue and Com…
jsiirola Apr 27, 2020
1c90b9b
Add initializeWalker callback to the StreamBasedExpressionVisitor
jsiirola Apr 27, 2020
8f0183d
Simplify 'except' logic
jsiirola Apr 27, 2020
098fd23
Remove 'no cover' pragmas
jsiirola Apr 27, 2020
f27ef5a
Rework GetItemExpression to include the base arg in the arg list
jsiirola Apr 27, 2020
ca148f0
Remove access of private attribute
jsiirola Apr 27, 2020
3cbb112
Fixing tests
jsiirola Apr 27, 2020
8d0ab7d
Update _IndexedComponent_slice to aviod side effects
jsiirola Apr 29, 2020
734ec54
Rename _IndexedComponent_slice -> IndexedComponent_slice
jsiirola Apr 29, 2020
9e315c0
Removing debugging
jsiirola Apr 30, 2020
9f002ea
Cleaning up template code, adding tests
jsiirola Apr 30, 2020
32074d7
Initial implementation of Pyomo2Scipy for blocked models
jsiirola Apr 30, 2020
197f1d0
Adding child_idx to StreamBasedExpressionVisitor child callbacks
jsiirola May 4, 2020
140527a
Add additional methods from Set API to _UnindexedComponentSet
jsiirola May 5, 2020
1d0d697
Allow Expression nodes to hook into enterNode/exitNode
jsiirola May 5, 2020
1cf7d1d
Fix support for template sums over indirect set references
jsiirola May 5, 2020
0f052ae
Merge branch 'master' into templates
jsiirola May 11, 2020
db865fa
Removing mock_globals function
jsiirola May 11, 2020
5884e60
Removing new Pyomo2Scipy_Visitor (will be added on a separate PR)
jsiirola May 11, 2020
db86056
Ensure that all args context managers are finalized
jsiirola May 11, 2020
4e67148
Removing use of is_parameter_type()
jsiirola May 11, 2020
e96ac5e
Fix __builtin__ access in pypy
jsiirola May 11, 2020
3841bbb
Python 3.x fix
jsiirola May 11, 2020
da86137
Move & rename PyomoModelingObject to PyomoObject in pyomo.core
jsiirola May 31, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyomo/contrib/mcpp/pyomo_mcpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def exitNode(self, node, data):

return ans

def beforeChild(self, node, child):
def beforeChild(self, node, child, child_idx):
if type(child) in nonpyomo_leaf_types:
# This means the child is POD
# i.e., int, float, string
Expand All @@ -322,7 +322,7 @@ def beforeChild(self, node, child):
# this is an expression node
return True, None

def acceptChildResult(self, node, data, child_result):
def acceptChildResult(self, node, data, child_result, child_idx):
self.refs.add(child_result)
data.append(child_result)
return data
Expand Down
18 changes: 9 additions & 9 deletions pyomo/contrib/satsolver/satsolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,20 +277,20 @@ def exitNode(self, node, data):
raise NotImplementedError(str(type(node)) + " expression not handled by z3 interface")
return ans

def beforeChild(self, node, child):
def beforeChild(self, node, child, child_idx):
if type(child) in nonpyomo_leaf_types:
# This means the child is POD
# i.e., int, float, string
return False, str(child)
elif child.is_variable_type():
return False, str(self.variable_label_map.getSymbol(child))
elif child.is_parameter_type():
return False, str(value(child))
elif not child.is_expression_type():
return False, str(child)
else:
# this is an expression node
elif child.is_expression_type():
return True, ""
elif child.is_numeric_type():
if child.is_fixed():
return False, str(value(child))
else:
return False, str(self.variable_label_map.getSymbol(child))
else:
return False, str(child)

def finalizeResult(self, node_result):
return node_result
15 changes: 6 additions & 9 deletions pyomo/core/base/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import pyomo.common
from pyomo.common import deprecated
from pyomo.core.pyomoobject import PyomoObject
from pyomo.core.base.misc import tabular_writer, sorted_robust

logger = logging.getLogger('pyomo.core')
Expand Down Expand Up @@ -75,7 +76,7 @@ def cname(*args, **kwds):
class CloneError(pyomo.common.errors.PyomoException):
pass

class _ComponentBase(object):
class _ComponentBase(PyomoObject):
"""A base class for Component and ComponentData

This class defines some fundamental methods and properties that are
Expand All @@ -86,6 +87,10 @@ class _ComponentBase(object):

_PPRINT_INDENT = " "

def is_component_type(self):
"""Return True if this class is a Pyomo component"""
return True

def __deepcopy__(self, memo):
# The problem we are addressing is when we want to clone a
# sub-block in a model. In that case, the block can have
Expand Down Expand Up @@ -594,10 +599,6 @@ def is_indexed(self):
"""Return true if this component is indexed"""
return False

def is_component_type(self):
"""Return True if this class is a Pyomo component"""
return True

def clear_suffix_value(self, suffix_or_name, expand=True):
"""Clear the suffix value for this component data"""
if isinstance(suffix_or_name, six.string_types):
Expand Down Expand Up @@ -912,10 +913,6 @@ def is_indexed(self):
"""Return true if this component is indexed"""
return False

def is_component_type(self):
"""Return True if this class is a Pyomo component"""
return True

def clear_suffix_value(self, suffix_or_name, expand=True):
"""Set the suffix value for this component data"""
if isinstance(suffix_or_name, six.string_types):
Expand Down
15 changes: 13 additions & 2 deletions pyomo/core/base/global_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,22 @@ def get(self, value, default):
return value
return default
def __iter__(self):
yield None
return (None,).__iter__()
def subsets(self):
return [self]
return [ self ]
def construct(self):
pass
def __len__(self):
return 1
def __eq__(self, other):
return self is other
def __ne__(self, other):
return self is not other
def isdiscrete(self):
return True
def isfinite(self):
return True
def isordered(self):
# As this set only has a single element, it is implicitly "ordered"
return True
UnindexedComponent_set = _UnindexedComponent_set('UnindexedComponent_set')
22 changes: 11 additions & 11 deletions pyomo/core/base/indexed_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from pyomo.core.expr.expr_errors import TemplateExpressionError
from pyomo.core.expr.numvalue import native_types
from pyomo.core.base.indexed_component_slice import _IndexedComponent_slice
from pyomo.core.base.indexed_component_slice import IndexedComponent_slice
from pyomo.core.base.component import Component, ActiveComponent
from pyomo.core.base.config import PyomoOptions
from pyomo.core.base.global_set import UnindexedComponent_set
Expand Down Expand Up @@ -375,7 +375,7 @@ def __getitem__(self, index):
index = TypeError
if index is TypeError:
raise
if index.__class__ is _IndexedComponent_slice:
if index.__class__ is IndexedComponent_slice:
return index
# The index could have contained constant but nonhashable
# objects (e.g., scalar immutable Params).
Expand All @@ -401,7 +401,7 @@ def __getitem__(self, index):
# _processUnhashableIndex could have found a slice, or
# _validate could have found an Ellipsis and returned a
# slicer
if index.__class__ is _IndexedComponent_slice:
if index.__class__ is IndexedComponent_slice:
return index
obj = self._data.get(index, _NotFound)
#
Expand Down Expand Up @@ -438,7 +438,7 @@ def __setitem__(self, index, val):
# If we didn't find the index in the data, then we need to
# validate it against the underlying set (as long as
# _processUnhashableIndex didn't return a slicer)
if index.__class__ is not _IndexedComponent_slice:
if index.__class__ is not IndexedComponent_slice:
index = self._validate_index(index)
else:
return self._setitem_impl(index, obj, val)
Expand All @@ -447,10 +447,10 @@ def __setitem__(self, index, val):
# dictionary and set the value
#
# Note that we need to RECHECK the class against
# _IndexedComponent_slice, as _validate_index could have found
# IndexedComponent_slice, as _validate_index could have found
# an Ellipsis (which is hashable) and returned a slicer
#
if index.__class__ is _IndexedComponent_slice:
if index.__class__ is IndexedComponent_slice:
# support "m.x[:,1] = 5" through a simple recursive call.
#
# Assert that this slice was just generated
Expand Down Expand Up @@ -480,11 +480,11 @@ def __delitem__(self, index):
index = self._processUnhashableIndex(index)

if obj is _NotFound:
if index.__class__ is not _IndexedComponent_slice:
if index.__class__ is not IndexedComponent_slice:
index = self._validate_index(index)

# this supports "del m.x[:,1]" through a simple recursive call
if index.__class__ is _IndexedComponent_slice:
if index.__class__ is IndexedComponent_slice:
# Assert that this slice ws just generated
assert len(index._call_stack) == 1
# Make a copy of the slicer items *before* we start
Expand Down Expand Up @@ -525,7 +525,7 @@ def _validate_index(self, idx):
# indexing set is a complex set operation)!
return validated_idx

if idx.__class__ is _IndexedComponent_slice:
if idx.__class__ is IndexedComponent_slice:
return idx

if normalize_index.flatten:
Expand Down Expand Up @@ -627,7 +627,7 @@ def _processUnhashableIndex(self, idx):
# templatized expression.
#
from pyomo.core.expr import current as EXPR
return EXPR.GetItemExpression(tuple(idx), self)
return EXPR.GetItemExpression((self,) + tuple(idx))

except EXPR.NonConstantExpressionError:
#
Expand Down Expand Up @@ -666,7 +666,7 @@ def _processUnhashableIndex(self, idx):
fixed[i - len(idx)] = val

if sliced or ellipsis is not None:
return _IndexedComponent_slice(self, fixed, sliced, ellipsis)
return IndexedComponent_slice(self, fixed, sliced, ellipsis)
elif _found_numeric:
if len(idx) == 1:
return fixed[0]
Expand Down
Loading