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)
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]))
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))
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))
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))
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))
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))
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))