'Test domain for kl_div.'

def test_kl_div(self):

    b = Variable()
    expr = kl_div(self.a, b)
    self.a.value = 2
    b.value = 4
    self.assertAlmostEqual(expr.grad[self.a], np.log((2 / 4)))
    self.assertAlmostEqual(expr.grad[b], (1 - (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 = kl_div(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]))))
    self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val)
    val = (np.zeros((2, 2)) + np.diag([(1 - (3 / 5)), (1 - (4 / 8))]))
    self.assertItemsAlmostEqual(expr.grad[y].todense(), val)
    expr = kl_div(self.x, y)
    self.x.value = [(-1e-09), 4]
    y.value = [1, 2]
    self.assertAlmostEqual(expr.grad[self.x], None)
    self.assertAlmostEqual(expr.grad[y], None)
    expr = kl_div(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).A.ravel(order='F')
    val = (np.zeros((4, 4)) + np.diag(np.log(div)))
    self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val)
    val = (np.zeros((4, 4)) + np.diag((1 - div)))
    self.assertItemsAlmostEqual(expr.grad[self.B].todense(), val)
