@@ -67,6 +67,29 @@ def test_problem_jacobian_lowlevel():
6767 assert np .allclose (jac .toarray (), expected_jac )
6868
6969
70+ def test_problem_constraint_forward_lowlevel ():
71+ """Test problem_constraint_forward for constraint values only (low-level)."""
72+ n_vars = 2
73+ x = diffengine .make_variable (n_vars , 1 , 0 , n_vars )
74+
75+ log_obj = diffengine .make_log (x )
76+ objective = diffengine .make_sum (log_obj , - 1 )
77+
78+ log_c = diffengine .make_log (x )
79+ exp_c = diffengine .make_exp (x )
80+ constraints = [log_c , exp_c ]
81+
82+ prob = diffengine .make_problem (objective , constraints )
83+ u = np .array ([2.0 , 4.0 ])
84+ diffengine .problem_allocate (prob , u )
85+
86+ constraint_vals = diffengine .problem_constraint_forward (prob , u )
87+
88+ # Expected: [log(2), log(4), exp(2), exp(4)]
89+ expected = np .concatenate ([np .log (u ), np .exp (u )])
90+ assert np .allclose (constraint_vals , expected )
91+
92+
7093def test_problem_no_constraints_lowlevel ():
7194 """Test Problem with no constraints (low-level)."""
7295 n_vars = 3
@@ -320,11 +343,37 @@ def test_problem_repeated_evaluations():
320343 assert np .allclose (grad2 , 1.0 / u2 )
321344
322345
346+ def test_problem_constraint_forward ():
347+ """Test Problem.constraint_forward for constraint values only."""
348+ x = cp .Variable (2 )
349+ obj = cp .sum (cp .log (x ))
350+ constraints = [
351+ cp .log (x ),
352+ cp .exp (x ),
353+ ]
354+
355+ cvxpy_prob = cp .Problem (cp .Minimize (obj ), constraints )
356+ prob = Problem (cvxpy_prob )
357+
358+ u = np .array ([2.0 , 4.0 ])
359+ prob .allocate (u )
360+
361+ # Test constraint_forward
362+ constraint_vals = prob .constraint_forward (u )
363+ expected = np .concatenate ([np .log (u ), np .exp (u )])
364+ assert np .allclose (constraint_vals , expected )
365+
366+ # Verify it gives same result as forward's constraint values
367+ _ , forward_constraint_vals = prob .forward (u )
368+ assert np .allclose (constraint_vals , forward_constraint_vals )
369+
370+
323371if __name__ == "__main__" :
324372 # Low-level tests
325373 test_problem_forward_lowlevel ()
326374 test_problem_gradient_lowlevel ()
327375 test_problem_jacobian_lowlevel ()
376+ test_problem_constraint_forward_lowlevel ()
328377 test_problem_no_constraints_lowlevel ()
329378 # Problem class tests
330379 test_problem_single_constraint ()
@@ -334,4 +383,5 @@ def test_problem_repeated_evaluations():
334383 test_problem_no_constraints_convert ()
335384 test_problem_larger_scale ()
336385 test_problem_repeated_evaluations ()
386+ test_problem_constraint_forward ()
337387 print ("All problem tests passed!" )
0 commit comments