예제 #1
0
 def test_log2floor(self):
     self.assertEqual(util.log2floor(1), 0)
     self.assertEqual(util.log2floor(2), 1)
     self.assertEqual(util.log2floor(3), 1)
     self.assertEqual(util.log2floor(4), 2)
     self.assertEqual(util.log2floor(5), 2)
     self.assertEqual(util.log2floor(6), 2)
     self.assertEqual(util.log2floor(7), 2)
     self.assertEqual(util.log2floor(8), 3)
     self.assertEqual(util.log2floor(9), 3)
     self.assertEqual(util.log2floor(2**10), 10)
     self.assertEqual(util.log2floor(2**10 + 1), 10)
     self.assertEqual(util.log2floor(2**20), 20)
     self.assertEqual(util.log2floor(2**20 + 1), 20)
     self.assertEqual(util.log2floor(2**30), 30)
     self.assertEqual(util.log2floor(2**30 + 1), 30)
     self.assertEqual(util.log2floor(2**40), 40)
     self.assertEqual(util.log2floor(2**40 + 1), 40)
예제 #2
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))