Пример #1
0
    def make_key_seq(self, keys, name):
        # INTERNAL Takes as input a candidate keys input and returns a valid key sequence
        used_name = name
        check_keys = True
        used_keys = []
        if is_iterable(keys):
            if is_pandas_dataframe(keys):
                used_keys = keys.index.values
            elif has_len(keys):
                used_keys = keys
            elif is_iterator(keys):
                used_keys = list(keys)
            else:
                # TODO: make a test for this case.
                self.fatal(
                    "Cannot handle iterable var keys: {0!s} : no len() and not an iterator",
                    keys)  # pragma: no cover

        elif is_int(keys) and keys >= 0:
            # if name is str and we have a size, disable automatic names
            used_name = None if name is str else name
            used_keys = range(keys)
            check_keys = False
        else:
            self.fatal(
                "Unexpected var keys: {0!s}, expecting iterable or integer",
                keys)  # pragma: no cover

        if check_keys and len(
                used_keys
        ):  # do not check truth value of used_keys: can be a Series!
            self._checker.typecheck_key_seq(used_keys)
        return used_name, used_keys
Пример #2
0
    def _expand_bounds(self, keys, var_bound, default_bound, size, true_if_lb):
        ''' Converts raw bounds data (either LB or UB) to CPLEX-compatible bounds list.
            If lbs is None, this is the default, return [].
            If lbs is [] take the default again.
            If it is a number, build a list of size <size> with this number.
            If it is a list, use it if size ok (check numbers??),
            else try it as a function over keys.
        '''
        if var_bound is None:
            # default lb is zero, default ub is infinity
            return []

        elif is_number(var_bound):
            self._checker.typecheck_num(var_bound, caller='in variable bound')
            if true_if_lb:
                if var_bound == default_bound:
                    return []
                else:
                    return [float(var_bound)] * size
            else:
                # ub
                if var_bound >= default_bound:
                    return []
                else:
                    return [float(var_bound)] * size

        elif is_ordered_sequence(var_bound):
            nb_bounds = len(var_bound)
            if nb_bounds < size:
                # see how we can use defaults for those missing bounds
                self.fatal(
                    "Variable bounds list is too small, expecting: %d, got: %d"
                    % (size, nb_bounds))
            else:
                return self._check_bounds(size, var_bound, default_bound,
                                          true_if_lb)

        elif is_iterator(var_bound):
            # unfold the iterator, as CPLEX needs a list
            return list(var_bound)

        elif isinstance(var_bound, dict):
            dict_bounds = [var_bound.get(k, default_bound) for k in keys]
            return self._check_bounds(size, dict_bounds, default_bound,
                                      true_if_lb)
        else:
            # try a function?
            try:
                fn_bounds = [var_bound(k) for k in keys]
                return self._check_bounds(size, fn_bounds, default_bound,
                                          true_if_lb)

            except TypeError:
                self._bad_bounds_fatal(var_bound)

            except Exception as e:  # pragma: no cover
                self.fatal(
                    "error calling function model bounds: {0!s}, error: {1!s}",
                    var_bound, e)
Пример #3
0
 def __init__(self, model, exprs, name=None):
     _IAdvancedExpr.__init__(self, model, name)
     if is_iterable(exprs) or is_iterator(exprs):
         self._exprs = exprs
     else:
         self._exprs = [model._lfactory._to_linear_operand(exprs)]
     # allocate xvars iff necessary
     self._xvars = [self._allocate_arg_var_if_necessary(e) for e in self._exprs]
 def __init__(self, model, exprs, name=None):
     _FunctionalExpr.__init__(self, model, name)
     if is_iterable(exprs) or is_iterator(exprs):
         self._exprs = exprs
     else:
         self._exprs = [model._lfactory._to_linear_operand(exprs)]
     # allocate xvars iff necessary
     self._xvars = [
         self._allocate_arg_var_if_necessary(expr, pos=e)
         for e, expr in enumerate(self._exprs, start=1)
     ]
Пример #5
0
    def sumsq(self, sum_args):
        if is_iterable(sum_args):
            if is_iterator(sum_args):
                return self._sumsq(sum_args)
            elif isinstance(sum_args, dict):
                return self._sumsq(sum_args.values())
            elif is_numpy_ndarray(sum_args):
                return self._sumsq(sum_args.flat)
            elif is_pandas_series(sum_args):
                return self._sumsq(sum_args.values)

            else:
                return self._sumsq(sum_args)
        elif is_number(sum_args):
            return sum_args ** 2
        else:
            self._model.fatal("Model.sumsq() expects number/iterable/expression, got: {0!s}", sum_args)
Пример #6
0
    def sum(self, sum_args):
        if is_iterator(sum_args):
            return self._sum_with_iter(sum_args)

        elif is_numpy_ndarray(sum_args):
            return self._sum_with_iter(sum_args.flat)
        elif is_pandas_series(sum_args):
            return self.sum(sum_args.values)
        elif isinstance(sum_args, dict):
            # handle dict: sum all values
            return self._sum_with_iter(itervalues(sum_args))
        elif is_iterable(sum_args):
            return self._sum_with_seq(sum_args)

        elif is_number(sum_args):
            return sum_args
        else:
            return self._linear_factory._to_linear_expr(sum_args)
Пример #7
0
 def __init__(self, model, exprs, name=None):
     _FunctionalExpr.__init__(self, model, name)
     assert is_iterable(exprs) or is_iterator(exprs)
     self._exprs = exprs
     # never allocate vars: arguments --are-- binary variables.
     self._xvars = exprs
Пример #8
0
 def check_ordered_sequence(self, arg, caller, accept_iterator=True):
     # in some cases, we need an ordered sequence, if not the code won't crash
     # but may do unexpected things
     if not (is_ordered_sequence(arg) or
             (accept_iterator and is_iterator(arg))):
         self.fatal("{0}, got: {1!s}", caller, type(arg).__name__)
Пример #9
0
 def check_ordered_sequence(self, arg, header):
     # in some cases, we need an ordered sequence, if not the code won't crash
     # but may do unexpected things
     if not is_ordered_sequence(arg) and not is_iterator(arg):
         self.fatal("{0}, got: {1!s}", header, type(arg).__name__)