def _map_sympy2pyomo(expr, sympy2pyomo): _stack = [([expr], 0, 1)] while 1: _argList, _idx, _len = _stack.pop() while _idx < _len: _sub = _argList[_idx] _idx += 1 if not _sub._args: if _sub in sympy2pyomo: _sub = _argList[_idx - 1] = sympy2pyomo[_sub] else: _sub = _argList[_idx - 1] = float(_sub.evalf()) continue _stack.append((_argList, _idx, _len)) _argList = list(_sub._args) _idx = 0 _len = len(_argList) # Substitute the operator if not _stack: return _argList[0] else: _sympyOp = _stack[-1][0][_stack[-1][1] - 1] _op = _operatorMap.get(type(_sympyOp), None) if _op is None: raise DeveloperError( "sympy expression type '%s' not found in the operator " "map for expression %s" % (type(_sympyOp), expr)) _stack[-1][0][_stack[-1][1] - 1] = _op(*tuple(_argList))
def clear(self): """Clear the data in this component""" if self.is_indexed(): self._data = {} else: raise DeveloperError( "Derived scalar component %s failed to define clear()." % (self.__class__.__name__,))
def visit(self, node, values): """ Visit nodes that have been expanded """ _sympyOp = node _op = _operatorMap.get( type(_sympyOp), None ) if _op is None: raise DeveloperError( "sympy expression type '%s' not found in the operator " "map" % type(_sympyOp) ) return _op(*tuple(values))
def set_value(self, value): """Set the value of a scalar component.""" if self.is_indexed(): raise ValueError( "Cannot set the value for the indexed component '%s' " "without specifying an index value.\n" "\tFor example, model.%s[i] = value" % (self.name, self.name)) else: raise DeveloperError( "Derived component %s failed to define set_value() " "for scalar instances." % (self.__class__.__name__, ))
def _processUnhashableIndex(self, idx, _exception=None): """Process a call to __getitem__ with unhashable elements There are three basic ways to get here: 1) the index contains one or more slices or ellipsis 2) the index contains an unhashable type (e.g., a Pyomo (Simple)Component 3) the index contains an IndexTemplate """ # # Iterate through the index and look for slices and constant # components # fixed = {} sliced = {} ellipsis = None _found_numeric = False # # Setup the slice template (in fixed) # if type(idx) is tuple: # We would normally do "flatten()" here, but the current # (10/2016) implementation of flatten() is too aggressive: # it will attempt to expand *any* iterable, including # SimpleParam. idx = pyutilib.misc.flatten_tuple(idx) elif type(idx) is list: idx = pyutilib.misc.flatten_tuple(tuple(idx)) else: idx = (idx,) for i,val in enumerate(idx): if type(val) is slice: if val.start is not None or val.stop is not None: raise IndexError( "Indexed components can only be indexed with simple " "slices: start and stop values are not allowed.") if val.step is not None: logger.warning( "DEPRECATION WARNING: The special wildcard slice " "(::0) is deprecated. Please use an ellipsis (...) " "to indicate '0 or more' indices") val = Ellipsis else: if ellipsis is None: sliced[i] = val else: sliced[i-len(idx)] = val continue if val is Ellipsis: if ellipsis is not None: raise IndexError( "Indexed components can only be indexed with simple " "slices: the Pyomo wildcard slice (Ellipsis; " "e.g., '...') can only appear once") ellipsis = i continue if hasattr(val, 'as_numeric'): _num_val = val.as_numeric() # Attempt to retrieve the numeric value .. if this # is a template expression generation, then it # should raise a TemplateExpressionError try: # Disable all logging for the time being. We are # not keeping the result of this calculation - only # seeing if it is possible. Any errors generated # evaluating the expression are not informative to # the user logging.disable(logging.CRITICAL) _num_val() except TemplateExpressionError: # Not good: we have to defer this import to now # due to circular imports (expr imports _VarData # imports indexed_component, but we need expr # here from pyomo.core.base import expr as EXPR return EXPR._GetItemExpression(self, idx) except: # There are other ways we could get an exception # that is not TemplateExpressionError; most notably, # evaluating a Param / Var that is not initialized. # At this point, we will silently eat that # error... it will come back again below. pass finally: logging.disable(logging.NOTSET) if _num_val.is_constant(): _found_numeric = True val = _num_val() elif _num_val.is_fixed(): raise RuntimeError( """Error retrieving the value of an indexed item %s: index %s is a fixed but not constant value. This is likely not what you meant to do, as if you later change the fixed value of the object this lookup will not change. If you understand the implications of using fixed but not constant values, you can get the current value using the value() function.""" % ( self.name, i )) else: raise RuntimeError( """Error retrieving the value of an indexed item %s: index %s is not a constant value. This is likely not what you meant to do, as if you later change the fixed value of the object this lookup will not change. If you understand the implications of using non-constant values, you can get the current value of the object using the value() function.""" % ( self.name, i )) # verify that the value is hashable hash(val) if ellipsis is None: fixed[i] = val else: fixed[i - len(idx)] = val if sliced or ellipsis is not None: return _IndexedComponent_slicer(self, fixed, sliced, ellipsis) elif _found_numeric: if len(idx) == 1: return fixed[0] else: return tuple( fixed[i] for i in range(len(idx)) ) elif _exception is not None: raise else: raise DeveloperError( "Unknown problem encountered when trying to retrieve " "index for component %s" % (self.name,) )
def _default(self, index): """Returns the default component data value""" raise DeveloperError( "Derived component %s failed to define _default()." % (self.__class__.__name__, ))