Esempio n. 1
0
 def test_rel_entr(self) -> None:
     """Test domain for rel_entr.
     """
     b = Variable()
     dom = cp.rel_entr(self.a, b).domain
     Problem(Minimize(self.a + b), dom).solve()
     self.assertAlmostEqual(self.a.value, 0)
     self.assertAlmostEqual(b.value, 0)
Esempio n. 2
0
    def test_rel_entr(self) -> None:
        """Test domain for rel_entr.
        """
        b = Variable()
        expr = cp.rel_entr(self.a, b)
        self.a.value = 2
        b.value = 4
        self.assertAlmostEqual(expr.grad[self.a], np.log(2 / 4) + 1)
        self.assertAlmostEqual(expr.grad[b], -(2 / 4))

        self.a.value = 3
        b.value = 0
        self.assertAlmostEqual(expr.grad[self.a], None)
        self.assertAlmostEqual(expr.grad[b], None)

        self.a.value = -1
        b.value = 2
        self.assertAlmostEqual(expr.grad[self.a], None)
        self.assertAlmostEqual(expr.grad[b], None)

        y = Variable(2)
        expr = cp.rel_entr(self.x, y)
        self.x.value = [3, 4]
        y.value = [5, 8]
        val = np.zeros((2, 2)) + np.diag(np.log([3, 4]) - np.log([5, 8]) + 1)
        self.assertItemsAlmostEqual(expr.grad[self.x].toarray(), val)
        val = np.zeros((2, 2)) + np.diag([-3 / 5, -4 / 8])
        self.assertItemsAlmostEqual(expr.grad[y].toarray(), val)

        expr = cp.rel_entr(self.x, y)
        self.x.value = [-1e-9, 4]
        y.value = [1, 2]
        self.assertAlmostEqual(expr.grad[self.x], None)
        self.assertAlmostEqual(expr.grad[y], None)

        expr = cp.rel_entr(self.A, self.B)
        self.A.value = [[1, 2], [3, 4]]
        self.B.value = [[5, 1], [3.5, 2.3]]
        div = (self.A.value / self.B.value).ravel(order='F')
        val = np.zeros((4, 4)) + np.diag(np.log(div) + 1)
        self.assertItemsAlmostEqual(expr.grad[self.A].toarray(), val)
        val = np.zeros((4, 4)) + np.diag(-div)
        self.assertItemsAlmostEqual(expr.grad[self.B].toarray(), val)
Esempio n. 3
0
    def test_difference_kl_div_rel_entr(self) -> None:
        """A test showing the difference between kl_div and rel_entr
        """
        x = cvx.Variable()
        y = cvx.Variable()

        kl_div_prob = cvx.Problem(cvx.Minimize(cvx.kl_div(x, y)),
                                  constraints=[x + y <= 1])
        kl_div_prob.solve(solver=cvx.ECOS)
        self.assertItemsAlmostEqual(x.value, y.value)
        self.assertItemsAlmostEqual(kl_div_prob.value, 0)

        rel_entr_prob = cvx.Problem(cvx.Minimize(cvx.rel_entr(x, y)),
                                    constraints=[x + y <= 1])
        rel_entr_prob.solve(solver=cvx.ECOS)
        """
        Reference solution computed by passing the following command to Wolfram Alpha:
        minimize x*log(x/y) subject to {x + y <= 1, 0 <= x, 0 <= y}
        """
        self.assertItemsAlmostEqual(x.value, 0.2178117, places=4)
        self.assertItemsAlmostEqual(y.value, 0.7821882, places=4)
        self.assertItemsAlmostEqual(rel_entr_prob.value, -0.278464)
Esempio n. 4
0
    def test_rel_entr(self) -> None:
        """Test a problem with rel_entr.
        """
        kK = 50
        kSeed = 10

        prng = np.random.RandomState(kSeed)
        # Generate a random reference distribution
        npSPriors = prng.uniform(0.0, 1.0, kK)
        npSPriors = npSPriors / sum(npSPriors)

        # Reference distribution
        p_refProb = cvx.Parameter(kK, nonneg=True)
        # Distribution to be estimated
        v_prob = cvx.Variable(kK)
        obj_rel_entr = cvx.sum(cvx.rel_entr(v_prob, p_refProb))

        constrs = [cvx.sum(v_prob) == 1]
        rel_entr_prob = cvx.Problem(cvx.Minimize(obj_rel_entr), constrs)
        p_refProb.value = npSPriors
        rel_entr_prob.solve(solver=cvx.SCS, verbose=True)
        self.assertItemsAlmostEqual(v_prob.value, npSPriors, places=3)
        rel_entr_prob.solve(solver=cvx.ECOS, verbose=True)
        self.assertItemsAlmostEqual(v_prob.value, npSPriors)