示例#1
0
    def __init__(self, *args, **kwds):
        super(piecewise_sos2, self).__init__(*args, **kwds)

        # create vars
        y = self.v = variable_tuple(
            variable(lb=0) for i in xrange(len(self.breakpoints)))
        y_tuple = tuple(y)

        # create piecewise constraints
        self.c = constraint_list()

        self.c.append(linear_constraint(
            variables=y_tuple + (self.input,),
            coefficients=self.breakpoints + (-1,),
            rhs=0))

        self.c.append(linear_constraint(
            variables=y_tuple + (self.output,),
            coefficients=self.values + (-1,)))
        if self.bound == 'ub':
            self.c[-1].lb = 0
        elif self.bound == 'lb':
            self.c[-1].ub = 0
        else:
            assert self.bound == 'eq'
            self.c[-1].rhs = 0

        self.c.append(linear_constraint(variables=y_tuple,
                                        coefficients=(1,)*len(y),
                                        rhs=1))

        self.s = sos2(y)
示例#2
0
    def __init__(self, *args, **kwds):
        super(piecewise_convex, self).__init__(*args, **kwds)

        breakpoints = self.breakpoints
        values = self.values
        self.c = constraint_list()
        for i in xrange(len(breakpoints)-1):
            X0 = breakpoints[i]
            F_AT_X0 = values[i]
            dF_AT_X0 = (values[i+1] - F_AT_X0) / \
                       (breakpoints[i+1] - X0)
            const = F_AT_X0 - dF_AT_X0*X0
            con = linear_constraint(
                (self.output, self.input),
                (-1, dF_AT_X0))
            if self.bound == 'ub':
                con.lb = -const
            elif self.bound == 'lb':
                con.ub = -const
            else:
                assert self.bound == 'eq'
                con.rhs = -const
            self.c.append(con)

        # In order to enforce the same behavior as actual
        # piecewise constraints, we need to constrain the
        # input expression to be between first and last
        # breakpoint. This might be duplicating the
        # variable, but its not always the case, and there's
        # no guarantee that the input "variable" is not a
        # more general linear expression.
        self.c.append(linear_constraint(
            terms=[(self.input, 1)],
            lb=self.breakpoints[0],
            ub=self.breakpoints[-1]))
示例#3
0
    def __init__(self, *args, **kwds):
        super(piecewise_dcc, self).__init__(*args, **kwds)

        # create index sets
        polytopes = range(len(self.breakpoints) - 1)
        vertices = range(len(self.breakpoints))

        def polytope_verts(p):
            return xrange(p, p + 2)

        # create vars
        self.v = variable_dict()
        lmbda = self.v['lambda'] = variable_dict(
            ((p, v), variable(lb=0)) for p in polytopes for v in vertices)
        y = self.v['y'] = variable_tuple(
            variable(domain=Binary) for p in polytopes)

        # create piecewise constraints
        self.c = constraint_list()

        self.c.append(linear_constraint(
            variables=tuple(lmbda[p,v]
                            for p in polytopes
                            for v in polytope_verts(p)) + \
                      (self.input,),
            coefficients=tuple(self.breakpoints[v]
                               for p in polytopes
                               for v in polytope_verts(p)) + \
                      (-1,),
            rhs=0))

        self.c.append(linear_constraint(
            variables=tuple(lmbda[p,v]
                            for p in polytopes
                            for v in polytope_verts(p)) + \
                      (self.output,),
            coefficients=tuple(self.values[v]
                               for p in polytopes
                               for v in polytope_verts(p)) + (-1,)))
        if self.bound == 'ub':
            self.c[-1].lb = 0
        elif self.bound == 'lb':
            self.c[-1].ub = 0
        else:
            assert self.bound == 'eq'
            self.c[-1].rhs = 0

        clist = []
        for p in polytopes:
            variables = tuple(lmbda[p, v] for v in polytope_verts(p))
            clist.append(
                linear_constraint(variables=variables + (y[p], ),
                                  coefficients=(1, ) * len(variables) + (-1, ),
                                  rhs=0))
        self.c.append(constraint_tuple(clist))

        self.c.append(
            linear_constraint(variables=tuple(y),
                              coefficients=(1, ) * len(y),
                              rhs=1))
示例#4
0
    def __init__(self, *args, **kwds):
        super(piecewise_inc, self).__init__(*args, **kwds)

        # create indexers
        polytopes = range(len(self.breakpoints)-1)

        # create vars
        self.v = variable_dict()
        delta = self.v['delta'] = variable_tuple(
            variable() for p in polytopes)
        delta[0].ub = 1
        delta[-1].lb = 0
        delta_tuple = tuple(delta)
        y = self.v['y'] = variable_tuple(
            variable(domain=Binary) for p in polytopes[:-1])

        # create piecewise constraints
        self.c = constraint_list()

        self.c.append(linear_constraint(
            variables=(self.input,) + delta_tuple,
            coefficients=(-1,) + tuple(self.breakpoints[p+1] - \
                                       self.breakpoints[p]
                                       for p in polytopes),
            rhs=-self.breakpoints[0]))

        self.c.append(linear_constraint(
            variables=(self.output,) + delta_tuple,
            coefficients=(-1,) + tuple(self.values[p+1] - \
                                       self.values[p]
                                       for p in polytopes)))
        if self.bound == 'ub':
            self.c[-1].lb = -self.values[0]
        elif self.bound == 'lb':
            self.c[-1].ub = -self.values[0]
        else:
            assert self.bound == 'eq'
            self.c[-1].rhs = -self.values[0]

        clist1 = []
        clist2 = []
        for p in polytopes[:-1]:
            clist1.append(linear_constraint(
                variables=(delta[p+1], y[p]),
                coefficients=(1, -1),
                ub=0))
            clist2.append(linear_constraint(
                variables=(y[p], delta[p]),
                coefficients=(1, -1),
                ub=0))
        self.c.append(constraint_tuple(clist1))
        self.c.append(constraint_tuple(clist2))
示例#5
0
    def __init__(self, *args, **kwds):
        super(piecewise_mc, self).__init__(*args, **kwds)

        # create indexers
        polytopes = range(len(self.breakpoints)-1)

        # create constants (using future division)
        # these might also be expressions if the breakpoints
        # or values lists contain mutable objects
        slopes = tuple((self.values[p+1] - self.values[p]) / \
                       (self.breakpoints[p+1] - self.breakpoints[p])
                       for p in polytopes)
        intercepts = tuple(self.values[p] - \
                           (slopes[p] * self.breakpoints[p])
                           for p in polytopes)

        # create vars
        self.v = variable_dict()
        lmbda = self.v['lambda'] = variable_tuple(
            variable() for p in polytopes)
        lmbda_tuple = tuple(lmbda)
        y = self.v['y'] = variable_tuple(
            variable(domain=Binary) for p in polytopes)
        y_tuple = tuple(y)

        # create piecewise constraints
        self.c = constraint_list()

        self.c.append(linear_constraint(
            variables=lmbda_tuple + (self.input,),
            coefficients=(1,)*len(lmbda) + (-1,),
            rhs=0))

        self.c.append(linear_constraint(
            variables=lmbda_tuple + y_tuple + (self.output,),
            coefficients=slopes + intercepts + (-1,)))
        if self.bound == 'ub':
            self.c[-1].lb = 0
        elif self.bound == 'lb':
            self.c[-1].ub = 0
        else:
            assert self.bound == 'eq'
            self.c[-1].rhs = 0

        clist1 = []
        clist2 = []
        for p in polytopes:
            clist1.append(linear_constraint(
                variables=(y[p], lmbda[p]),
                coefficients=(self.breakpoints[p], -1),
                ub=0))
            clist2.append(linear_constraint(
                variables=(lmbda[p], y[p]),
                coefficients=(1, -self.breakpoints[p+1]),
                ub=0))
        self.c.append(constraint_tuple(clist1))
        self.c.append(constraint_tuple(clist2))

        self.c.append(linear_constraint(
            variables=y_tuple,
            coefficients=(1,)*len(y),
            rhs=1))
示例#6
0
    def __init__(self, *args, **kwds):
        super(piecewise_cc, self).__init__(*args, **kwds)

        # create index sets
        polytopes = range(len(self.breakpoints)-1)
        vertices = range(len(self.breakpoints))
        def vertex_polys(v):
            if v == 0:
                return [v]
            if v == len(self.breakpoints)-1:
                return [v-1]
            else:
                return [v-1,v]

        # create vars
        self.v = variable_dict()
        lmbda = self.v['lambda'] = variable_tuple(
            variable(lb=0) for v in vertices)
        y = self.v['y'] = variable_tuple(
            variable(domain=Binary)
            for p in polytopes)

        lmbda_tuple = tuple(lmbda)

        # create piecewise constraints
        self.c = constraint_list()

        self.c.append(linear_constraint(
            variables=lmbda_tuple + (self.input,),
            coefficients=self.breakpoints + (-1,),
            rhs=0))

        self.c.append(linear_constraint(
            variables=lmbda_tuple + (self.output,),
            coefficients=self.values + (-1,)))
        if self.bound == 'ub':
            self.c[-1].lb = 0
        elif self.bound == 'lb':
            self.c[-1].ub = 0
        else:
            assert self.bound == 'eq'
            self.c[-1].rhs = 0

        self.c.append(linear_constraint(
            variables=lmbda_tuple,
            coefficients=(1,)*len(lmbda),
            rhs=1))

        clist = []
        for v in vertices:
            variables = tuple(y[p] for p in vertex_polys(v))
            clist.append(linear_constraint(
                variables=variables + (lmbda[v],),
                coefficients=(1,)*len(variables) + (-1,),
                lb=0))
        self.c.append(constraint_tuple(clist))

        self.c.append(linear_constraint(
            variables=tuple(y),
            coefficients=(1,)*len(y),
            rhs=1))
示例#7
0
    def __init__(self, *args, **kwds):
        super(piecewise_log, self).__init__(*args, **kwds)

        breakpoints = self.breakpoints
        values = self.values

        if not is_positive_power_of_two(len(breakpoints)-1):
            raise ValueError("The list of breakpoints must be "
                             "of length (2^n)+1 for some positive "
                             "integer n. Invalid length: %s"
                             % (len(breakpoints)))

        # create branching schemes
        L = log2floor(len(breakpoints)-1)
        S,B_LEFT,B_RIGHT = self._branching_scheme(L)

        # create indexers
        polytopes = range(len(breakpoints) - 1)
        vertices = range(len(breakpoints))

        # create vars
        self.v = variable_dict()
        lmbda = self.v['lambda'] = variable_tuple(
            variable(lb=0) for v in vertices)
        y = self.v['y'] = variable_list(
            variable(domain=Binary) for s in S)

        # create piecewise constraints
        self.c = constraint_list()

        self.c.append(linear_constraint(
            variables=(self.input,) + tuple(lmbda),
            coefficients=(-1,) + breakpoints,
            rhs=0))

        self.c.append(linear_constraint(
            variables=(self.output,) + tuple(lmbda),
            coefficients=(-1,) + values))
        if self.bound == 'ub':
            self.c[-1].lb = 0
        elif self.bound == 'lb':
            self.c[-1].ub = 0
        else:
            assert self.bound == 'eq'
            self.c[-1].rhs = 0

        self.c.append(linear_constraint(
            variables=tuple(lmbda),
            coefficients=(1,)*len(lmbda),
            rhs=1))

        clist = []
        for s in S:
            variables=tuple(lmbda[v] for v in B_LEFT[s])
            clist.append(linear_constraint(
                variables=variables + (y[s],),
                coefficients=(1,)*len(variables) + (-1,),
                ub=0))
        self.c.append(constraint_tuple(clist))
        del clist

        clist = []
        for s in S:
            variables=tuple(lmbda[v] for v in B_RIGHT[s])
            clist.append(linear_constraint(
                variables=variables + (y[s],),
                coefficients=(1,)*len(variables) + (1,),
                ub=1))
        self.c.append(constraint_tuple(clist))
示例#8
0
    def __init__(self, *args, **kwds):
        super(piecewise_nd_cc, self).__init__(*args, **kwds)

        ndim = len(self.input)
        nsimplices = len(self.triangulation.simplices)
        npoints = len(self.triangulation.points)
        pointsT = list(zip(*self.triangulation.points))

        # create index objects
        dimensions = range(ndim)
        simplices = range(nsimplices)
        vertices = range(npoints)

        # create vars
        self.v = variable_dict()
        lmbda = self.v['lambda'] = variable_tuple(
            variable(lb=0) for v in vertices)
        y = self.v['y'] = variable_tuple(
            variable(domain=Binary) for s in simplices)
        lmbda_tuple = tuple(lmbda)

        # create constraints
        self.c = constraint_list()

        clist = []
        for d in dimensions:
            clist.append(
                linear_constraint(variables=lmbda_tuple + (self.input[d], ),
                                  coefficients=tuple(pointsT[d]) + (-1, ),
                                  rhs=0))
        self.c.append(constraint_tuple(clist))
        del clist

        self.c.append(
            linear_constraint(variables=lmbda_tuple + (self.output, ),
                              coefficients=tuple(self.values) + (-1, )))
        if self.bound == 'ub':
            self.c[-1].lb = 0
        elif self.bound == 'lb':
            self.c[-1].ub = 0
        else:
            assert self.bound == 'eq'
            self.c[-1].rhs = 0

        self.c.append(
            linear_constraint(variables=lmbda_tuple,
                              coefficients=(1, ) * len(lmbda_tuple),
                              rhs=1))

        # generate a map from vertex index to simplex index,
        # which avoids an n^2 lookup when generating the
        # constraint
        vertex_to_simplex = [[] for v in vertices]
        for s, simplex in enumerate(self.triangulation.simplices):
            for v in simplex:
                vertex_to_simplex[v].append(s)

        clist = []
        for v in vertices:
            variables = tuple(y[s] for s in vertex_to_simplex[v])
            clist.append(
                linear_constraint(variables=variables + (lmbda[v], ),
                                  coefficients=(1, ) * len(variables) + (-1, ),
                                  lb=0))
        self.c.append(constraint_tuple(clist))
        del clist

        self.c.append(
            linear_constraint(variables=y, coefficients=(1, ) * len(y), rhs=1))