def __init__(self, *args, **kwds): super(piecewise_dlog, 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) assert 2**L == len(breakpoints) - 1 B_LEFT, B_RIGHT = self._branching_scheme(L) # create indexers polytopes = range(len(breakpoints) - 1) vertices = range(len(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 polytope_verts(p)) y = self.v['y'] = variable_tuple( variable(domain=Binary) for i in range(L)) # create piecewise constraints self.c = constraint_list() self.c.append( linear_constraint( variables=(self.input, ) + tuple(lmbda[p, v] for p in polytopes for v in polytope_verts(p)), coefficients=(-1, ) + tuple(breakpoints[v] for p in polytopes for v in polytope_verts(p)), rhs=0)) self.c.append( linear_constraint( variables=(self.output, ) + tuple(lmbda[p, v] for p in polytopes for v in polytope_verts(p)), coefficients=(-1, ) + tuple(values[v] for p in polytopes for v in polytope_verts(p)))) 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.values()), coefficients=(1, ) * len(lmbda), rhs=1)) clist = [] for i in range(L): variables = tuple(lmbda[p, v] for p in B_LEFT[i] for v in polytope_verts(p)) clist.append( linear_constraint(variables=variables + (y[i], ), coefficients=(1, ) * len(variables) + (-1, ), ub=0)) self.c.append(constraint_tuple(clist)) del clist clist = [] for i in range(L): variables = tuple(lmbda[p, v] for p in B_RIGHT[i] for v in polytope_verts(p)) clist.append( linear_constraint(variables=variables + (y[i], ), coefficients=(1, ) * len(variables) + (1, ), ub=1)) self.c.append(constraint_tuple(clist))
def test_is_positive_power_of_two(self): self.assertEqual(util.is_positive_power_of_two(-8), False) self.assertEqual(util.is_positive_power_of_two(-4), False) self.assertEqual(util.is_positive_power_of_two(-3), False) self.assertEqual(util.is_positive_power_of_two(-2), False) self.assertEqual(util.is_positive_power_of_two(-1), False) self.assertEqual(util.is_positive_power_of_two(0), False) self.assertEqual(util.is_positive_power_of_two(1), True) self.assertEqual(util.is_positive_power_of_two(2), True) self.assertEqual(util.is_positive_power_of_two(3), False) self.assertEqual(util.is_positive_power_of_two(4), True) self.assertEqual(util.is_positive_power_of_two(5), False) self.assertEqual(util.is_positive_power_of_two(6), False) self.assertEqual(util.is_positive_power_of_two(7), False) self.assertEqual(util.is_positive_power_of_two(8), True) self.assertEqual(util.is_positive_power_of_two(15), False) self.assertEqual(util.is_positive_power_of_two(16), True) self.assertEqual(util.is_positive_power_of_two(31), False) self.assertEqual(util.is_positive_power_of_two(32), True)