Exemplo n.º 1
0
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))
Exemplo n.º 2
0
 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__,))
Exemplo n.º 3
0
 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))
Exemplo n.º 4
0
 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__, ))
Exemplo n.º 5
0
    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,) )
Exemplo n.º 6
0
 def _default(self, index):
     """Returns the default component data value"""
     raise DeveloperError(
         "Derived component %s failed to define _default()." %
         (self.__class__.__name__, ))