예제 #1
0
    def test_bb_lower_bound(self, optimization_variables_avg):
        l, Q, A = optimization_variables_avg
        m = 2e-3
        m1 = 4e-3
        f = 1e-2
        max_active = 2
        state = optimization_methods.bb_state([1], [2], [3, 0, 4])
        x, val = optimization_methods._bb_lower_bound(np.atleast_2d(l), Q, f,
                                                      m1, m, max_active, state)

        s = np.ones(len(l)) / m
        s[state.active] = 0
        select = state.active + state.unassigned
        l_ = l[select]
        Q_ = Q[np.ix_(select, select)]
        A_ = A[select]
        s_ = np.diag(s[select])

        ob = lambda x: .5 * x.dot(Q_.dot(x))
        x0 = np.zeros(Q_.shape[0])
        jac = lambda x: x.dot(Q_)
        #hess = lambda x: Q
        m_constraint = {}
        m_constraint['type'] = 'eq'
        m_constraint['fun'] = lambda x: l_.dot(x) - f
        m_constraint['jac'] = lambda x: l_

        e_constraint = {}
        e_constraint['type'] = 'eq'
        e_constraint['fun'] = lambda x: A_.dot(x)
        e_constraint['jac'] = lambda x: A_

        bounds = scipy.optimize.Bounds(-m, m)

        iq_constraint = {}
        iq_constraint['type'] = 'ineq'
        iq_constraint['fun'] = lambda x: 2 * m1 - np.linalg.norm(x, 1)

        r_constraint = {}
        r_constraint['type'] = 'ineq'
        r_constraint['fun'] = lambda x: 1 - np.linalg.norm(s_ * x, 1)

        constraints = (m_constraint, e_constraint, iq_constraint, r_constraint)
        res = scipy.optimize.minimize(ob,
                                      x0,
                                      jac=jac,
                                      bounds=bounds,
                                      constraints=constraints)
        x_sp = np.zeros(len(l))
        x_sp[select] = res.x

        assert np.linalg.norm(x, 1) <= 2 * m1 + 1e-4
        assert np.all(np.abs(x) <= m + 1e-4)
        assert np.isclose(np.sum(x), 0)
        assert np.isclose(x[state.inactive], 0)
        assert np.isclose(l.dot(x), f)
        assert np.allclose(x.dot(Q.dot(x)),
                           x_sp.dot(Q.dot(x_sp)),
                           rtol=1e-4,
                           atol=1e-5)
예제 #2
0
    def test_bb_algorithm(self):
        # Function with gives out the bounds as well as the new sets to split
        def bounds_func(s):
            a = np.array([4, 0, 1, 3, 2, 6, 7, 8, 9, 5]) * .1

            if len(s.active) > 4:
                return np.inf, np.inf, None, None

            to_consider = s.active + s.unassigned
            v_in_consideration = a[to_consider]
            ub = np.sum(v_in_consideration)
            lb = np.sum(np.sort(v_in_consideration)[:4])
            for i in np.argsort(v_in_consideration):
                el = to_consider[i]
                if el in s.unassigned:
                    split1 = s.inactivate(el)
                    split2 = s.activate(el)
                    break
            if len(s.unassigned) == 0:
                split1 = None
                split2 = None

            return ub, lb, split1, split2

        init = optimization_methods.bb_state([], [], list(range(10)))
        eps = 1e-1
        final_state = optimization_methods._branch_and_bound(
            init, bounds_func, eps, 100)
        assert np.all(final_state.active == [1, 2, 4, 3])
예제 #3
0
    def test_bb_node(self):
        # Function with gives out the bounds as well as the new sets to split
        def bounds_func(s):
            a = np.array([0, 4, 1, 3, 2, 6, 7, 8, 9, 5])
            if len(s.active) > 4:
                return np.inf
            to_consider = s.active + s.unassigned
            ub = np.sum(a[to_consider])
            lb = np.sum(np.sort(a[to_consider])[:4])
            for i in np.argsort(a[to_consider]):
                el = to_consider[i]
                if el in s.unassigned:
                    split1 = s.inactivate(el)
                    split2 = s.activate(el)
                    break
            if len(s.unassigned) == 0:
                split1 = None
                split2 = None
            return ub, lb, split1, split2

        init = optimization_methods.bb_state([], [], list(range(10)))
        bb_node = optimization_methods.bb_node(init, bounds_func)
        assert bb_node.lb_val == 0 + 1 + 2 + 3
        assert bb_node.ub_val == sum(range(10))
        assert np.all(bb_node.child1.active == [])
        assert np.all(bb_node.child1.inactive == [0])
        assert np.all(bb_node.child2.active == [0])
        assert np.all(bb_node.child2.inactive == [])
        c1, c2 = bb_node.split()
        assert c1.lb_val == 1 + 2 + 3 + 4
        assert c1.ub_val == sum(range(1, 10))

        assert c2.lb_val == 0 + 1 + 2 + 3
        assert c2.ub_val == sum(range(0, 10))
    def test_bb_bounds_tes_problem(self):
        state = optimization_methods.bb_state([1], [0], [2, 3, 4]) # 1 active, 0 inactive
        linear = [np.arange(5)[None, :]]
        quadratic = [np.diag(np.arange(5))]
        max_l0 = 3
        max_el_current = 4

        mock_fun = mock.Mock(
            side_effect=[
                (np.array([4, 3, 2, 1]), 2), # First call (lower bound)
                (np.array([4, 3, 2, 1]), None), # second call (preparation upper bound)
                (np.array([4, 3, 2]), 4), # Third call (calculation upper bound)
            ]
        )
        ub, lb, child1, child2 = optimization_methods._bb_bounds_tes_problem(
            state, max_l0, linear, quadratic,
            max_el_current, mock_fun,
        )
        assert ub == 4
        assert lb == 2
        assert child2.inactive == [0, 2]
        assert child1.active == [1, 2]
        # Assertions realted to first call
        assert np.allclose(mock_fun.call_args_list[0][0][0][0], np.arange(1, 5))
        assert np.allclose(mock_fun.call_args_list[0][0][1][0], np.diag(np.arange(1, 5)))
        assert np.allclose(mock_fun.call_args_list[0][1]['extra_ineq'][0],
                           np.tile(np.array([0., 0.25, 0.25, 0.25]), 2))
        assert np.allclose(mock_fun.call_args_list[0][1]['extra_ineq'][1], 2)
        # Second call
        assert np.allclose(mock_fun.call_args_list[1][0][0][0], np.arange(1, 5))
        assert np.allclose(mock_fun.call_args_list[1][0][1][0], np.diag(np.arange(1, 5)))
        # Third call
        assert np.allclose(mock_fun.call_args_list[2][0][0][0], np.arange(1, 4))
        assert np.allclose(mock_fun.call_args_list[2][0][1][0], np.diag(np.arange(1, 4)))
예제 #5
0
 def test_bb_split(self):
     state = optimization_methods.bb_state([1], [2], [3, 0, 4])
     x = np.array([4, 3, 0, 1, -5])
     child1, child2 = optimization_methods._bb_split(x, state)
     assert child1.active == [1, 4]
     assert child1.inactive == [2]
     assert child2.active == [1]
     assert child2.inactive == [2, 4]
예제 #6
0
    def test_bb_upper_bound(self, optimization_variables_avg):
        l, Q, A = optimization_variables_avg
        m = 2e-3
        m1 = 4e-3
        f = 1e-3
        max_active = 2
        state = optimization_methods.bb_state([1], [2], [3, 0, 4])
        x_ub, ub = optimization_methods._bb_upper_bound(
            np.atleast_2d(l), Q, f, m1, m, max_active, state)

        assert np.linalg.norm(x_ub, 1) <= 2 * m1 + 1e-4
        assert np.all(np.abs(x_ub) <= m + 1e-4)
        assert np.isclose(np.sum(x_ub), 0)
        assert np.isclose(x_ub[state.inactive], 0)
        assert np.isclose(l.dot(x_ub), f)
예제 #7
0
 def test_bb_full(self, optimization_variables_avg):
     l, Q, A = optimization_variables_avg
     m = 2e-3
     m1 = 4e-3
     f = 1e-2
     max_active = 2
     init = optimization_methods.bb_state([], [], list(range(len(l))))
     bf = functools.partial(optimization_methods._bb_bounds_function,
                            np.atleast_2d(l), Q, f, m1, m, max_active)
     final_state = optimization_methods._branch_and_bound(
         init, bf, 1e-2, 100)
     x = final_state.x_lb
     assert np.linalg.norm(x, 1) <= 2 * m1 + 1e-4
     assert np.linalg.norm(x, 0) <= max_active
     assert np.all(np.abs(x) <= m + 1e-4)
     assert np.isclose(np.sum(x), 0)
     assert np.isclose(l.dot(x), f)