Exemplo n.º 1
0
    def test_default_initializer(self):
        a = Initializer({1: 5})
        d = DefaultInitializer(a, None, KeyError)
        self.assertFalse(d.constant())
        self.assertTrue(d.contains_indices())
        self.assertEqual(list(d.indices()), [1])
        self.assertEqual(d(None, 1), 5)
        self.assertIsNone(d(None, 2))

        def rule(m, i):
            if i == 0:
                return 10
            elif i == 1:
                raise KeyError("key")
            elif i == 2:
                raise TypeError("type")
            else:
                raise RuntimeError("runtime")

        a = Initializer(rule)
        d = DefaultInitializer(a, 100, (KeyError, RuntimeError))
        self.assertFalse(d.constant())
        self.assertFalse(d.contains_indices())
        self.assertEqual(d(None, 0), 10)
        self.assertEqual(d(None, 1), 100)
        with self.assertRaisesRegex(TypeError, 'type'):
            d(None, 2)
        self.assertEqual(d(None, 3), 100)
Exemplo n.º 2
0
 def test_dict(self):
     m = ConcreteModel()
     a = Initializer({1:5})
     self.assertIs(type(a), ItemInitializer)
     self.assertFalse(a.constant())
     self.assertFalse(a.verified)
     self.assertTrue(a.contains_indices())
     self.assertEqual(list(a.indices()), [1])
     self.assertEqual(a(None, 1), 5)
Exemplo n.º 3
0
    def test_pickle(self):
        m = ConcreteModel()
        a = Initializer(5)
        a.verified = True
        b = pickle.loads(pickle.dumps(a))
        self.assertIsNot(a, b)
        self.assertEqual(a.val, b.val)
        self.assertEqual(a.verified, b.verified)

        a = Initializer({1:5})
        b = pickle.loads(pickle.dumps(a))
        self.assertIsNot(a, b)
        self.assertEqual(a._dict, b._dict)
        self.assertIsNot(a._dict, b._dict)
        self.assertEqual(a.verified, b.verified)

        a = Initializer(_init_scalar)
        b = pickle.loads(pickle.dumps(a))
        self.assertIsNot(a, b)
        self.assertIs(a._fcn, b._fcn)
        self.assertEqual(a.verified, b.verified)
        self.assertEqual(a(None, None), 1)
        self.assertEqual(b(None, None), 1)

        m.x = Var([1,2,3])
        a = Initializer(_init_indexed)
        b = pickle.loads(pickle.dumps(a))
        self.assertIsNot(a, b)
        self.assertIs(a._fcn, b._fcn)
        self.assertEqual(a.verified, b.verified)
        self.assertEqual(a(None, 1), 2)
        self.assertEqual(b(None, 2), 3)
Exemplo n.º 4
0
    def __init__(self, *args, **kwargs):
        _init = self._pop_from_kwargs('Constraint', kwargs, ('rule', 'expr'),
                                      None)
        # Special case: we accept 2- and 3-tuples as constraints
        if type(_init) is tuple:
            self.rule = Initializer(_init, treat_sequences_as_mappings=False)
        else:
            self.rule = Initializer(_init)

        kwargs.setdefault('ctype', Constraint)
        ActiveIndexedComponent.__init__(self, *args, **kwargs)
Exemplo n.º 5
0
 def test_initializer_initializer(self):
     d = {'col1': [1, 2, 4], 'col2': [10, 20, 40]}
     df = pd.DataFrame(data=d)
     a = Initializer(DataFrameInitializer(df, 'col2'))
     self.assertIs(type(a), DataFrameInitializer)
     self.assertFalse(a.constant())
     self.assertFalse(a.verified)
     self.assertTrue(a.contains_indices())
     self.assertEqual(list(a.indices()), [0, 1, 2])
     self.assertEqual(a(None, 0), 10)
     self.assertEqual(a(None, 1), 20)
     self.assertEqual(a(None, 2), 40)
Exemplo n.º 6
0
 def __init__(self, *args, **kwds):
     # This will get called regardless of what class we are instantiating
     self._init_model = Initializer(kwds.pop('model', None))
     self._init_time = Initializer(kwds.pop('time', None),
                                   treat_sequences_as_mappings=False)
     self._init_inputs = Initializer(kwds.pop('inputs', None),
                                     treat_sequences_as_mappings=False)
     self._init_measurements = Initializer(
         kwds.pop('measurements', None), treat_sequences_as_mappings=False)
     self._init_category_dict = Initializer(
         kwds.pop('category_dict', None), treat_sequences_as_mappings=False)
     Block.__init__(self, *args, **kwds)
Exemplo n.º 7
0
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('ctype', Complementarity)
        kwargs.setdefault('dense', False)
        _init = tuple(_arg for _arg in (kwargs.pop('initialize', None),
                                        kwargs.pop('rule', None),
                                        kwargs.pop('expr', None))
                      if _arg is not None)
        if len(_init) > 1:
            raise ValueError(
                "Duplicate initialization: Complementarity() only accepts "
                "one of 'initialize=', 'rule=', and 'expr='")
        elif _init:
            _init = _init[0]
        else:
            _init = None

        self._init_rule = Initializer(_init,
                                      treat_sequences_as_mappings=False,
                                      allow_generators=True)

        if self._init_rule is not None:
            kwargs['rule'] = Complementarity._complementarity_rule
        Block.__init__(self, *args, **kwargs)

        # HACK to make the "counted call" syntax work.  We wait until
        # after the base class is set up so that is_indexed() is
        # reliable.
        if self._init_rule is not None \
           and self._init_rule.__class__ is IndexedCallInitializer:
            self._init_rule = CountedCallInitializer(self, self._init_rule)
Exemplo n.º 8
0
    def construct(self, data=None):
        """ Apply the rule to construct values in this set """
        if self._constructed:
            return
        self._constructed = True

        timer = ConstructionTimer(self)
        if is_debug_set(logger):
            logger.debug("Constructing Expression, name=%s, from data=%s" %
                         (self.name, str(data)))

        rule = self.rule
        try:
            # We do not (currently) accept data for constructing Constraints
            index = None
            assert data is None

            if rule is None:
                # Historically, Expression objects were dense (but None):
                rule = Initializer(lambda *args: None)
                # If there is no rule, then we are immediately done.
                #return

            block = self.parent_block()
            if rule.contains_indices():
                # The index is coming in externally; we need to validate it
                for index in rule.indices():
                    self[index] = rule(block, index)
            elif not self.index_set().isfinite():
                # If the index is not finite, then we cannot iterate
                # over it.  Since the rule doesn't provide explicit
                # indices, then there is nothing we can do (the
                # assumption is that the user will trigger specific
                # indices to be created at a later time).
                pass
            else:
                # Bypass the index validation and create the member directly
                for index in self.index_set():
                    self._setitem_when_not_present(index, rule(block, index))
        except Exception:
            err = sys.exc_info()[1]
            logger.error("Rule failed when generating expression for "
                         "Expression %s with index %s:\n%s: %s" %
                         (self.name, str(index), type(err).__name__, err))
            raise
        finally:
            timer.report()
Exemplo n.º 9
0
    def __init__(self, *args, **kwargs):
        _sense = kwargs.pop('sense', minimize)
        _init = tuple(_arg for _arg in (kwargs.pop('rule', None),
                                        kwargs.pop('expr', None))
                      if _arg is not None)
        if len(_init) == 1:
            _init = _init[0]
        elif not _init:
            _init = None
        else:
            raise ValueError("Duplicate initialization: Objective() only "
                             "accepts one of 'rule=' and 'expr='")

        kwargs.setdefault('ctype', Objective)
        ActiveIndexedComponent.__init__(self, *args, **kwargs)

        self.rule = Initializer(_init)
        self._init_sense = Initializer(_sense)
Exemplo n.º 10
0
    def test_sequence(self):
        m = ConcreteModel()
        a = Initializer([0,5])
        self.assertIs(type(a), ItemInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertTrue(a.contains_indices())
        self.assertEqual(list(a.indices()), [0,1])
        self.assertEqual(a(None, 1), 5)

        a = Initializer([0,5], treat_sequences_as_mappings=False)
        self.assertIs(type(a), ConstantInitializer)
        self.assertTrue(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, 1), [0,5])
Exemplo n.º 11
0
    def __init__(self, *args, **kwargs):
        _init = tuple( _arg for _arg in (
            kwargs.pop('rule', None),
            kwargs.pop('expr', None) ) if _arg is not None )
        if len(_init) == 1:
            _init = _init[0]
        elif not _init:
            _init = None
        else:
            raise ValueError("Duplicate initialization: Constraint() only "
                             "accepts one of 'rule=' and 'expr='")

        kwargs.setdefault('ctype', Constraint)
        ActiveIndexedComponent.__init__(self, *args, **kwargs)

        # Special case: we accept 2- and 3-tuples as constraints
        if type(_init) is tuple:
            self.rule = Initializer(_init, treat_sequences_as_mappings=False)
        else:
            self.rule = Initializer(_init)
Exemplo n.º 12
0
 def __init__(self, *args, **kwargs):
     #
     # Default keyword values
     #
     self._rule_init = Initializer(self._pop_from_kwargs(
         'Var', kwargs, ('rule', 'initialize'), None))
     self._rule_domain = SetInitializer(self._pop_from_kwargs(
         'Var', kwargs, ('domain', 'within'), Reals))
     _bounds_arg = kwargs.pop('bounds', None)
     self._dense = kwargs.pop('dense', True)
     self._units = kwargs.pop('units', None)
     if self._units is not None:
         self._units = units.get_units(self._units)
     #
     # Initialize the base class
     #
     kwargs.setdefault('ctype', Var)
     IndexedComponent.__init__(self, *args, **kwargs)
     #
     # Now that we can call is_indexed(), process bounds initializer
     #
     if self.is_indexed():
         treat_bounds_sequences_as_mappings = not (
             isinstance(_bounds_arg, Sequence)
             and len(_bounds_arg) == 2
             and not isinstance(_bounds_arg[0], Sequence)
         )
     else:
         treat_bounds_sequences_as_mappings = False
         if not self._dense:
             logger.warning(
                 "ScalarVar object '%s': dense=False is not allowed "
                 "for scalar variables; converting to dense=True"
                 % (self.name,))
             self._dense = True
     self._rule_bounds = Initializer(
         _bounds_arg,
         treat_sequences_as_mappings=treat_bounds_sequences_as_mappings
     )
Exemplo n.º 13
0
    def __init__(self, *args, **kwds):
        _init = self._pop_from_kwargs(
            'Expression', kwds, ('rule', 'expr', 'initialize'), None)
        # Historically, Expression objects were dense (but None):
        # setting arg_not_specified causes Initializer to recognize
        # _init==None as a constant initializer returning None
        #
        # To initialize a completely empty Expression, pass either
        # initialize={} (to require explicit setitem before a getitem),
        # or initialize=NOTSET (to allow getitem before setitem)
        self._rule = Initializer(_init, arg_not_specified=NOTSET)

        kwds.setdefault('ctype', Expression)
        IndexedComponent.__init__(self, *args, **kwds)
Exemplo n.º 14
0
    def test_generators(self):
        m = ConcreteModel()
        with self.assertRaisesRegex(ValueError, "Generators are not allowed"):
            a = Initializer(iter([0, 3]))

        a = Initializer(iter([0, 3]), allow_generators=True)
        self.assertIs(type(a), ConstantInitializer)
        self.assertTrue(a.constant())
        self.assertFalse(a.verified)
        self.assertEqual(list(a(None, 1)), [0, 3])

        def x_init():
            yield 0
            yield 3

        with self.assertRaisesRegex(ValueError, "Generators are not allowed"):
            a = Initializer(x_init())

        a = Initializer(x_init(), allow_generators=True)
        self.assertIs(type(a), ConstantInitializer)
        self.assertTrue(a.constant())
        self.assertFalse(a.verified)
        self.assertEqual(list(a(None, 1)), [0, 3])
Exemplo n.º 15
0
    def __init__(self, **kwargs):
        """Constructor"""
        if 'expr' in kwargs:
            raise ValueError(
                "ObjectiveList does not accept the 'expr' keyword")
        _rule = kwargs.pop('rule', None)

        args = (Set(dimen=1),)
        super().__init__(*args, **kwargs)

        self.rule = Initializer(_rule, allow_generators=True)
        # HACK to make the "counted call" syntax work.  We wait until
        # after the base class is set up so that is_indexed() is
        # reliable.
        if self.rule is not None and type(self.rule) is IndexedCallInitializer:
            self.rule = CountedCallInitializer(self, self.rule)
Exemplo n.º 16
0
 def test_constant(self):
     m = ConcreteModel()
     a = Initializer(5)
     self.assertIs(type(a), ConstantInitializer)
     self.assertTrue(a.constant())
     self.assertFalse(a.verified)
     self.assertFalse(a.contains_indices())
     with self.assertRaisesRegex(
             RuntimeError, "Initializer ConstantInitializer does "
             "not contain embedded indices"):
         a.indices()
     self.assertEqual(a(None, 1), 5)
Exemplo n.º 17
0
    def __init__(self, *args, **kwds):
        _init = tuple(arg
                      for arg in (kwds.pop(_arg, None)
                                  for _arg in ('rule', 'expr', 'initialize'))
                      if arg is not None)
        if len(_init) == 1:
            _init = _init[0]
        elif not _init:
            _init = None
        else:
            raise ValueError(
                "Duplicate initialization: Expression() only "
                "accepts one of 'rule=', 'expr=', and 'initialize='")

        kwds.setdefault('ctype', Expression)
        IndexedComponent.__init__(self, *args, **kwds)

        self.rule = Initializer(_init)
Exemplo n.º 18
0
    def _construct_from_rule_using_setitem(self):
        if self._rule is None:
            return
        index = None
        rule = self._rule
        block = self.parent_block()
        try:
            if rule.constant() and self.is_indexed():
                # A constant rule could return a dict-like thing or
                # matrix that we would then want to process with
                # Initializer().  If the rule actually returned a
                # constant, then this is just a little overhead.
                self._rule = rule = Initializer(
                    rule(block, None),
                    treat_sequences_as_mappings=False,
                    arg_not_specified=NOTSET)

            if rule.contains_indices():
                # The index is coming in externally; we need to validate it
                for index in rule.indices():
                    self[index] = rule(block, index)
            elif not self.index_set().isfinite():
                # If the index is not finite, then we cannot iterate
                # over it.  Since the rule doesn't provide explicit
                # indices, then there is nothing we can do (the
                # assumption is that the user will trigger specific
                # indices to be created at a later time).
                pass
            elif rule.constant():
                # Slight optimization: if the initializer is known to be
                # constant, then only call the rule once.
                val = rule(block, None)
                for index in self.index_set():
                    self._setitem_when_not_present(index, val)
            else:
                for index in self.index_set():
                    self._setitem_when_not_present(index, rule(block, index))
        except:
            err = sys.exc_info()[1]
            logger.error("Rule failed for %s '%s' with index %s:\n%s: %s" %
                         (self.ctype.__name__, self.name, str(index),
                          type(err).__name__, err))
            raise
Exemplo n.º 19
0
    def __init__(self, *args, **kwds):
        _init = tuple(arg
                      for arg in (kwds.pop(_arg, None)
                                  for _arg in ('rule', 'expr', 'initialize'))
                      if arg is not None)
        if len(_init) == 1:
            _init = _init[0]
        elif not _init:
            _init = None
        else:
            raise ValueError(
                "Duplicate initialization: Expression() only "
                "accepts one of 'rule=', 'expr=', and 'initialize='")

        kwds.setdefault('ctype', Expression)
        IndexedComponent.__init__(self, *args, **kwds)

        # Historically, Expression objects were dense (but None):
        # setting arg_not_specified causes Initializer to recognize
        # _init==None as a constant initializer returning None
        self._rule = Initializer(_init, arg_not_specified=NOTSET)
Exemplo n.º 20
0
    def __init__(self, *args, **kwd):
        _init = self._pop_from_kwargs('Param', kwd, ('rule', 'initialize'),
                                      NOTSET)
        self._rule = Initializer(_init,
                                 treat_sequences_as_mappings=False,
                                 arg_not_specified=NOTSET)
        self.domain = self._pop_from_kwargs('Param', kwd, ('domain', 'within'))
        if self.domain is None:
            self.domain = _ImplicitAny(owner=self, name='Any')

        self._validate = kwd.pop('validate', None)
        self._mutable = kwd.pop('mutable', Param.DefaultMutable)
        self._default_val = kwd.pop('default', Param.NoValue)
        self._dense_initialize = kwd.pop('initialize_as_dense', False)
        self._units = kwd.pop('units', None)
        if self._units is not None:
            self._units = units.get_units(self._units)
            self._mutable = True

        kwd.setdefault('ctype', Param)
        IndexedComponent.__init__(self, *args, **kwd)
Exemplo n.º 21
0
    def test_config_integration(self):
        c = ConfigList()
        c.add(1)
        c.add(3)
        c.add(5)
        a = Initializer(c)
        self.assertIs(type(a), ItemInitializer)
        self.assertTrue(a.contains_indices())
        self.assertEqual(list(a.indices()), [0, 1, 2])
        self.assertEqual(a(None, 0), 1)
        self.assertEqual(a(None, 1), 3)
        self.assertEqual(a(None, 2), 5)

        c = ConfigDict()
        c.declare('opt_1', ConfigValue(default=1))
        c.declare('opt_3', ConfigValue(default=3))
        c.declare('opt_5', ConfigValue(default=5))
        a = Initializer(c)
        self.assertIs(type(a), ItemInitializer)
        self.assertTrue(a.contains_indices())
        self.assertEqual(list(a.indices()), ['opt_1', 'opt_3', 'opt_5'])
        self.assertEqual(a(None, 'opt_1'), 1)
        self.assertEqual(a(None, 'opt_3'), 3)
        self.assertEqual(a(None, 'opt_5'), 5)
Exemplo n.º 22
0
class Var(IndexedComponent, IndexedComponent_NDArrayMixin):
    """A numeric variable, which may be defined over an index.

    Args:
        domain (Set or function, optional): A Set that defines valid
            values for the variable (e.g., ``Reals``, ``NonNegativeReals``,
            ``Binary``), or a rule that returns Sets.  Defaults to ``Reals``.
        within (Set or function, optional): An alias for ``domain``.
        bounds (tuple or function, optional): A tuple of ``(lower, upper)``
            bounds for the variable, or a rule that returns tuples.
            Defaults to ``(None, None)``.
        initialize (float or function, optional): The initial value for
            the variable, or a rule that returns initial values.
        rule (float or function, optional): An alias for ``initialize``.
        dense (bool, optional): Instantiate all elements from
            :meth:`index_set` when constructing the Var (True) or just the
            variables returned by ``initialize``/``rule`` (False).  Defaults
            to ``True``.
        units (pyomo units expression, optional): Set the units corresponding
            to the entries in this variable.
        name (str, optional): Name for this component.
        doc (str, optional): Text describing this component.
    """

    _ComponentDataClass = _GeneralVarData

    def __new__(cls, *args, **kwargs):
        if cls is not Var:
            return super(Var, cls).__new__(cls)
        if not args or (args[0] is UnindexedComponent_set and len(args)==1):
            return super(Var, cls).__new__(AbstractScalarVar)
        else:
            return super(Var, cls).__new__(IndexedVar)

    @overload
    def __init__(self, *indexes, domain=Reals, within=Reals, bounds=None,
                 initialize=None, rule=None, dense=True, units=None,
                 name=None, doc=None): ...
    
    def __init__(self, *args, **kwargs):
        #
        # Default keyword values
        #
        self._rule_init = Initializer(self._pop_from_kwargs(
            'Var', kwargs, ('rule', 'initialize'), None))
        self._rule_domain = SetInitializer(self._pop_from_kwargs(
            'Var', kwargs, ('domain', 'within'), Reals))
        _bounds_arg = kwargs.pop('bounds', None)
        self._dense = kwargs.pop('dense', True)
        self._units = kwargs.pop('units', None)
        if self._units is not None:
            self._units = units.get_units(self._units)
        #
        # Initialize the base class
        #
        kwargs.setdefault('ctype', Var)
        IndexedComponent.__init__(self, *args, **kwargs)
        #
        # Now that we can call is_indexed(), process bounds initializer
        #
        if self.is_indexed():
            treat_bounds_sequences_as_mappings = not (
                isinstance(_bounds_arg, Sequence)
                and len(_bounds_arg) == 2
                and not isinstance(_bounds_arg[0], Sequence)
            )
        else:
            treat_bounds_sequences_as_mappings = False
            if not self._dense:
                logger.warning(
                    "ScalarVar object '%s': dense=False is not allowed "
                    "for scalar variables; converting to dense=True"
                    % (self.name,))
                self._dense = True
        self._rule_bounds = Initializer(
            _bounds_arg,
            treat_sequences_as_mappings=treat_bounds_sequences_as_mappings
        )

    def flag_as_stale(self):
        """
        Set the 'stale' attribute of every variable data object to True.
        """
        for var_data in self._data.values():
            var_data.stale = True

    def get_values(self, include_fixed_values=True):
        """
        Return a dictionary of index-value pairs.
        """
        if include_fixed_values:
            return {idx:vardata.value for idx,vardata in self._data.items()}
        return {idx:vardata.value
                            for idx, vardata in self._data.items()
                                                if not vardata.fixed}

    extract_values = get_values

    def set_values(self, new_values, skip_validation=False):
        """
        Set the values of a dictionary.

        The default behavior is to validate the values in the
        dictionary.
        """
        for index, new_value in new_values.items():
            self[index].set_value(new_value, skip_validation)

    def get_units(self):
        """Return the units expression for this Var."""
        return self._units

    # TODO: deprecate this?  __getitem__ is generally preferable"
    def add(self, index):
        """Add a variable with a particular index."""
        return self[index]

    def construct(self, data=None):
        """
        Construct the _VarData objects for this variable
        """
        if self._constructed:
            return
        self._constructed=True

        timer = ConstructionTimer(self)
        if is_debug_set(logger):
            logger.debug("Constructing Variable %s" % (self.name,))

        # Note: define 'index' to avoid 'variable referenced before
        # assignment' in the error message generated in the 'except:'
        # block below.
        index = None
        try:
            # We do not (currently) accept data for constructing Variables
            assert data is None

            if not self.index_set().isfinite() and self._dense:
                # Note: if the index is not finite, then we cannot
                # iterate over it.  This used to be fatal; now we
                # just warn
                logger.warning(
                    "Var '%s' indexed by a non-finite set, but declared "
                    "with 'dense=True'.  Reverting to 'dense=False' as "
                    "it is not possible to make this variable dense.  "
                    "This warning can be suppressed by specifying "
                    "'dense=False'" % (self.name,))
                self._dense = False

            if ( self._rule_init is not None and
                 self._rule_init.contains_indices() ):
                # Historically we have allowed Vars to be initialized by
                # a sparse map (i.e., a dict containing only some of the
                # keys).  We will wrap the incoming initializer to map
                # KeyErrors to None
                self._rule_init = DefaultInitializer(
                    self._rule_init, None, KeyError)
                # The index is coming in externally; we need to validate it
                for index in self._rule_init.indices():
                    self[index]
                # If this is a dense object, we need to ensure that it
                # has been filled in.
                if self._dense:
                    for index in self.index_set():
                        if index not in self._data:
                            self._getitem_when_not_present(index)
            elif not self.is_indexed():
                # As there is only a single VarData to populate, just do
                # so and bypass all special-case testing below
                self._getitem_when_not_present(None)
            elif self._dense:
                # Special case: initialize every VarData.  For the
                # initializers that are constant, we can avoid
                # re-calling (and re-validating) the inputs in certain
                # cases.  To support this, we will create the first
                # _VarData and then use it as a template to initialize
                # (constant portions of) every VarData so as to not
                # repeat all the domain/bounds validation.
                try:
                    ref = self._getitem_when_not_present(
                        next(iter(self.index_set())))
                except StopIteration:
                    # Empty index!
                    return
                call_domain_rule = not self._rule_domain.constant()
                call_bounds_rule = self._rule_bounds is not None and (
                        not self._rule_bounds.constant())
                call_init_rule = self._rule_init is not None and (
                    not self._rule_init.constant()
                    # If either the domain or bounds change, then we
                    # need to re-verify the initial value, even if it is
                    # constant:
                    or call_domain_rule or call_bounds_rule
                )
                # Initialize all the component datas with the common data
                for index in self.index_set():
                    self._data[index] = self._ComponentDataClass.copy(ref)
                # Now go back and initialize any index-specific data
                block = self.parent_block()
                if call_domain_rule:
                    for index, obj in self._data.items():
                        # We can directly set the attribute (not the
                        # property) because the SetInitializer ensures
                        # that the value is a proper Set.
                        obj._domain = self._rule_domain(block, index)
                if call_bounds_rule:
                    for index, obj in self._data.items():
                        obj.lower, obj.upper = self._rule_bounds(block, index)
                if call_init_rule:
                    for index, obj in self._data.items():
                        obj.set_value(self._rule_init(block, index))
            else:
                # non-dense indexed var with generic
                # (non-index-containing) initializer: nothing to do
                pass

        except Exception:
            err = sys.exc_info()[1]
            logger.error(
                "Rule failed when initializing variable for "
                "Var %s with index %s:\n%s: %s"
                % (self.name,
                   str(index),
                   type(err).__name__,
                   err))
            raise
        finally:
            timer.report()

    #
    # This method must be defined on subclasses of
    # IndexedComponent that support implicit definition
    #
    def _getitem_when_not_present(self, index):
        """Returns the default component data value."""
        if index is None and not self.is_indexed():
            obj = self._data[index] = self
        else:
            obj = self._data[index] = self._ComponentDataClass(component=self)
        parent = self.parent_block()
        # We can directly set the attribute (not the property) because
        # the SetInitializer ensures that the value is a proper Set.
        obj._domain = self._rule_domain(parent, index)
        if self._rule_bounds is not None:
            obj.lower, obj.upper = self._rule_bounds(parent, index)
        if self._rule_init is not None:
            obj.set_value(self._rule_init(parent, index))
        return obj

    #
    # Because we need to do more initialization than simply calling
    # set_value(), we need to override _setitem_when_not_present
    #
    def _setitem_when_not_present(self, index, value=NOTSET):
        if value is self.Skip:
            return None
        try:
            obj = self._getitem_when_not_present(index)
            if value is not NOTSET:
                obj.set_value(value)
        except:
            self._data.pop(index, None)
            raise
        return obj

    def _pprint(self):
        """Print component information."""
        headers = [
            ("Size", len(self)),
            ("Index", self._index if self.is_indexed() else None),
        ]
        if self._units is not None:
            headers.append(('Units', str(self._units)))
        return ( headers,
                 self._data.items(),
                 ( "Lower","Value","Upper","Fixed","Stale","Domain"),
                 lambda k, v: [ value(v.lb),
                                v.value,
                                value(v.ub),
                                v.fixed,
                                v.stale,
                                v.domain
                                ]
                 )
Exemplo n.º 23
0
 def __init__(self, *args, **kwds):
     kwds.setdefault('ctype', ExternalGreyBoxBlock)
     self._init_model = Initializer(kwds.pop('external_model', None))
     Block.__init__(self, *args, **kwds)
Exemplo n.º 24
0
    def test_staticmethod(self):
        class Init(object):
            @staticmethod
            def a_init(m):
                return 0

            @staticmethod
            def x_init(m, i):
                return i+1

            @staticmethod
            def x2_init(m):
                return 0

            @staticmethod
            def y_init(m, i, j):
                return j*(i+1)

        m = ConcreteModel()
        a = Initializer(Init.a_init)
        self.assertIs(type(a), ScalarCallInitializer)
        self.assertTrue(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, 1), 0)

        m.x = Var([1,2,3])
        a = Initializer(Init.x_init)
        self.assertIs(type(a), IndexedCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, 1), 2)

        a = Initializer(Init.x2_init)
        self.assertIs(type(a), ScalarCallInitializer)
        self.assertTrue(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, 1), 0)

        m.y = Var([1,2,3], [4,5,6])
        a = Initializer(Init.y_init)
        self.assertIs(type(a), IndexedCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, (1, 4)), 8)

        b = CountedCallInitializer(m.x, a)
        self.assertIs(type(b), CountedCallInitializer)
        self.assertFalse(b.constant())
        self.assertFalse(b.verified)
        self.assertFalse(a.contains_indices())
        self.assertFalse(b._scalar)
        self.assertIs(a._fcn, b._fcn)
        c = b(None, 1)
        self.assertIs(type(c), CountedCallGenerator)
        self.assertEqual(next(c), 2)
        self.assertEqual(next(c), 3)
        self.assertEqual(next(c), 4)
Exemplo n.º 25
0
    def test_generator_fcn(self):
        m = ConcreteModel()
        def a_init(m):
            yield 0
            yield 3
        with self.assertRaisesRegex(
                ValueError, "Generator functions are not allowed"):
            a = Initializer(a_init)

        a = Initializer(a_init, allow_generators=True)
        self.assertIs(type(a), ScalarCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertEqual(list(a(None, 1)), [0,3])

        m.x = Var([1,2,3])
        def x_init(m, i):
            yield i
            yield i+1
        a = Initializer(x_init, allow_generators=True)
        self.assertIs(type(a), IndexedCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertEqual(list(a(None, 1)), [1,2])

        m.y = Var([1,2,3], [4,5,6])
        def y_init(m, i, j):
            yield j
            yield i+1
        a = Initializer(y_init, allow_generators=True)
        self.assertIs(type(a), IndexedCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertEqual(list(a(None, (1, 4))), [4,2])
Exemplo n.º 26
0
    def test_generator_method(self):
        class Init(object):
            def a_init(self, m):
                yield 0
                yield 3

            def x_init(self, m, i):
                yield i
                yield i+1

            def y_init(self, m, i, j):
                yield j
                yield i+1
        init = Init()

        m = ConcreteModel()
        with self.assertRaisesRegex(
                ValueError, "Generator functions are not allowed"):
            a = Initializer(init.a_init)

        a = Initializer(init.a_init, allow_generators=True)
        self.assertIs(type(a), ScalarCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertEqual(list(a(None, 1)), [0,3])

        m.x = Var([1,2,3])
        a = Initializer(init.x_init, allow_generators=True)
        self.assertIs(type(a), IndexedCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertEqual(list(a(None, 1)), [1,2])

        m.y = Var([1,2,3], [4,5,6])
        a = Initializer(init.y_init, allow_generators=True)
        self.assertIs(type(a), IndexedCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertEqual(list(a(None, (1, 4))), [4,2])
Exemplo n.º 27
0
    def test_function(self):
        m = ConcreteModel()
        def a_init(m):
            return 0
        a = Initializer(a_init)
        self.assertIs(type(a), ScalarCallInitializer)
        self.assertTrue(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, 1), 0)

        m.x = Var([1,2,3])
        def x_init(m, i):
            return i+1
        a = Initializer(x_init)
        self.assertIs(type(a), IndexedCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, 1), 2)

        def x2_init(m):
            return 0
        a = Initializer(x2_init)
        self.assertIs(type(a), ScalarCallInitializer)
        self.assertTrue(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, 1), 0)

        m.y = Var([1,2,3], [4,5,6])
        def y_init(m, i, j):
            return j*(i+1)
        a = Initializer(y_init)
        self.assertIs(type(a), IndexedCallInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertFalse(a.contains_indices())
        self.assertEqual(a(None, (1, 4)), 8)

        b = CountedCallInitializer(m.x, a)
        self.assertIs(type(b), CountedCallInitializer)
        self.assertFalse(b.constant())
        self.assertFalse(b.verified)
        self.assertFalse(a.contains_indices())
        self.assertFalse(b._scalar)
        self.assertIs(a._fcn, b._fcn)
        c = b(None, 1)
        self.assertIs(type(c), CountedCallGenerator)
        self.assertEqual(next(c), 2)
        self.assertEqual(next(c), 3)
        self.assertEqual(next(c), 4)
Exemplo n.º 28
0
    def test_dataframe(self):
        d = {'col1': [1, 2, 4]}
        df = pd.DataFrame(data=d)
        a = Initializer(df)
        self.assertIs(type(a), DataFrameInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertTrue(a.contains_indices())
        self.assertEqual(list(a.indices()), [0, 1, 2])
        self.assertEqual(a(None, 0), 1)
        self.assertEqual(a(None, 1), 2)
        self.assertEqual(a(None, 2), 4)

        d = {'col1': [1, 2, 4], 'col2': [10, 20, 40]}
        df = pd.DataFrame(data=d)
        with self.assertRaisesRegex(
                ValueError,
                'DataFrameInitializer for DataFrame with multiple columns'):
            a = Initializer(df)
        a = DataFrameInitializer(df, 'col2')
        self.assertIs(type(a), DataFrameInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertTrue(a.contains_indices())
        self.assertEqual(list(a.indices()), [0, 1, 2])
        self.assertEqual(a(None, 0), 10)
        self.assertEqual(a(None, 1), 20)
        self.assertEqual(a(None, 2), 40)

        df = pd.DataFrame([10, 20, 30, 40], index=[[0, 0, 1, 1], [0, 1, 0, 1]])
        a = Initializer(df)
        self.assertIs(type(a), DataFrameInitializer)
        self.assertFalse(a.constant())
        self.assertFalse(a.verified)
        self.assertTrue(a.contains_indices())
        self.assertEqual(list(a.indices()), [(0, 0), (0, 1), (1, 0), (1, 1)])
        self.assertEqual(a(None, (0, 0)), 10)
        self.assertEqual(a(None, (0, 1)), 20)
        self.assertEqual(a(None, (1, 0)), 30)
        self.assertEqual(a(None, (1, 1)), 40)