Exemple #1
0
def simple_objectivelist_rule(rule):
    """
    This is a decorator that translates None into ObjectiveList.End.
    This supports a simpler syntax in objective rules, though these
    can be more difficult to debug when errors occur.

    Example use:

    @simple_objectivelist_rule
    def O_rule(model, i, j):
        ...

    model.o = ObjectiveList(expr=simple_objectivelist_rule(...))
    """
    return rule_wrapper(rule, {None: ObjectiveList.End})
Exemple #2
0
def simple_constraintlist_rule(rule):
    """
    This is a decorator that translates None/True/False return values
    into ConstraintList.End/Constraint.Feasible/Constraint.Infeasible.
    This supports a simpler syntax in constraint rules, though these can be
    more difficult to debug when errors occur.

    Example use:

    @simple_constraintlist_rule
    def C_rule(model, i, j):
        ...

    model.c = ConstraintList(expr=simple_constraintlist_rule(...))
    """
    return rule_wrapper(rule, {
        None: ConstraintList.End,
        True: Constraint.Feasible,
        False: Constraint.Infeasible,
    })
Exemple #3
0
    def __init__(self, *args, **kwds):

        if "wrt" in kwds and "withrespectto" in kwds:
            raise TypeError(
                "Cannot specify both 'wrt' and 'withrespectto keywords")

        wrt = kwds.pop('wrt', None)
        wrt = kwds.pop('withrespectto', wrt)

        if wrt is None:
            # Check to be sure Integral is indexed by single
            # ContinuousSet and take Integral with respect to that
            # ContinuousSet
            if len(args) != 1:
                raise ValueError(
                    "Integral indexed by multiple ContinuousSets. "
                    "The desired ContinuousSet must be specified using the "
                    "keyword argument 'wrt'")
            wrt = args[0]

        if type(wrt) is not ContinuousSet:
            raise ValueError(
                "Cannot take the integral with respect to '%s'. Must take an "
                "integral with respect to a ContinuousSet" % wrt)
        self._wrt = wrt

        loc = None
        for i, s in enumerate(args):
            if s is wrt:
                loc = i

        # Check that the wrt ContinuousSet is in the argument list
        if loc is None:
            raise ValueError(
                "The ContinuousSet '%s' was not found in the indexing sets "
                "of the Integral" % wrt.name)
        self.loc = loc

        # Remove the index that the integral is being expanded over
        arg = args[0:loc] + args[loc + 1:]

        # Check that if bounds are given
        bounds = kwds.pop('bounds', None)
        if bounds is not None:
            raise DAE_Error(
                "Setting bounds on integrals has not yet been implemented. "
                "Integrals may only be taken over an entire ContinuousSet")

        # Create integral expression and pass to the expression initialization
        intexp = kwds.pop('expr', None)
        intexp = kwds.pop('rule', intexp)
        if intexp is None:
            raise ValueError("Must specify an integral expression")

        _is_indexed = bool(len(arg))

        def _trap_rule(rule, m, *a):
            ds = sorted(m.find_component(wrt.local_name))
            return sum(0.5 * (ds[i + 1] - ds[i]) *
                       (rule(m, *(a[0:loc] + (ds[i + 1], ) + a[loc:])) +
                        rule(m, *(a[0:loc] + (ds[i], ) + a[loc:])))
                       for i in range(len(ds) - 1))

        # Note that position_map is mapping arguments (block, *args), so
        # must be 1 more than len(args), and loc has to be offset by one
        kwds['rule'] = rule_wrapper(
            intexp,
            _trap_rule,
            positional_arg_map=(i for i in range(len(args) + 1)
                                if i != loc + 1))
        kwds.setdefault('ctype', Integral)
        Expression.__init__(self, *arg, **kwds)