'Test grad for partial minimization/maximization problems.'

def test_partial_problem(self):

    for obj in [Minimize((self.a ** (-1))), Maximize(entr(self.a))]:
        prob = Problem(obj, [((self.x + self.a) >= [5, 8])])
        expr = cvxpy.partial_optimize(prob, dont_opt_vars=[self.x, self.a])
        self.a.value = None
        self.x.value = None
        grad = expr.grad
        self.assertAlmostEqual(grad[self.a], None)
        self.assertAlmostEqual(grad[self.x], None)
        self.a.value = 1.0
        self.x.value = [5, 5]
        grad = expr.grad
        self.assertAlmostEqual(grad[self.a], None)
        self.assertAlmostEqual(grad[self.x], None)
        self.a.value = 1
        self.x.value = [10, 10]
        grad = expr.grad
        self.assertAlmostEqual(grad[self.a], obj.args[0].grad[self.a])
        self.assertItemsAlmostEqual(grad[self.x].todense(), [0, 0, 0, 0])
        expr = cvxpy.partial_optimize(prob, opt_vars=[self.x])
        self.a.value = 1
        grad = expr.grad
        self.assertAlmostEqual(grad[self.a], (obj.args[0].grad[self.a] + 0))
        fix_prob = Problem(obj, [((self.x + self.a) >= [5, 8]), (self.x == 0)])
        fix_prob.solve()
        dual_val = fix_prob.constraints[0].dual_variable.value
        expr = cvxpy.partial_optimize(prob, opt_vars=[self.a])
        self.x.value = [0, 0]
        grad = expr.grad
        self.assertItemsAlmostEqual(grad[self.x].todense(), dual_val)
        expr = cvxpy.partial_optimize(prob, opt_vars=[self.x, self.a])
        grad = expr.grad
        self.assertAlmostEqual(grad, {})
