@@ -29,38 +29,79 @@ function runtests()
2929 return
3030end
3131
32- function test_obj ()
33-
34- for (MODEL, SOLVER) in [
32+ function test_obj_simple ()
33+
34+ for (MODEL, SOLVER) in [
3535 (DiffOpt. diff_model, HiGHS. Optimizer),
36- # (DiffOpt.diff_model, SCS.Optimizer),
37- # (DiffOpt.diff_model, Ipopt.Optimizer),
38- # (DiffOpt.quadratic_diff_model, HiGHS.Optimizer),
39- # (DiffOpt.quadratic_diff_model, SCS.Optimizer),
40- # (DiffOpt.quadratic_diff_model, Ipopt.Optimizer),
41- # (DiffOpt.conic_diff_model, HiGHS.Optimizer),
42- # (DiffOpt.conic_diff_model, SCS.Optimizer),
43- # (DiffOpt.conic_diff_model, Ipopt.Optimizer),
44- # (DiffOpt.nonlinear_diff_model, HiGHS.Optimizer),
45- # (DiffOpt.nonlinear_diff_model, SCS.Optimizer),
46- # (DiffOpt.nonlinear_diff_model, Ipopt.Optimizer),
36+ (DiffOpt. diff_model, SCS. Optimizer),
37+ (DiffOpt. diff_model, Ipopt. Optimizer),
4738 ],
48- # ineq in [true, false ],
49- # _min in [true, false ],
50- # flip in [true, false ],
39+ sign in [+ 1 , - 1 ],
40+ sign_p in [- 1 , + 1 ],
41+ sense in [:Min , :Max ],
5142 with_bridge_type in [Float64, nothing ]
5243
5344 if isnothing (with_bridge_type) && SOLVER === SCS. Optimizer
5445 continue
5546 end
5647
48+ @testset " $(MODEL) with: $(SOLVER) , bridge:$with_bridge_type , sign:$sign , sense: $sense , sign_p: $sign_p " begin
49+ model = MODEL (SOLVER; with_bridge_type)
50+ set_silent (model)
5751
58- MODEL = DiffOpt. diff_model
59- SOLVER = HiGHS. Optimizer
60- with_bridge_type = Float64
61- ineq = false
62- _min = true
63- flip = false
52+ p_val = 4.0
53+ @variable (model, x)
54+ @variable (model, p in Parameter (p_val))
55+ @constraint (model, con, x == 3 * sign_p * p)
56+ @objective (model, Min, 2 * sign * x)
57+ if sense == :Max
58+ @objective (model, Max, 2 * sign * x)
59+ end
60+ optimize! (model)
61+ @test value (x) ≈ sign_p * 3 * p_val atol = ATOL rtol = RTOL
62+
63+ DiffOpt. empty_input_sensitivities! (model)
64+ direction_obj = 2.0
65+ DiffOpt. set_reverse_objective (model, direction_obj)
66+ DiffOpt. reverse_differentiate! (model)
67+ @test DiffOpt. get_reverse_parameter (model, p) ≈ sign_p * sign * 6 * direction_obj atol = ATOL rtol = RTOL
68+
69+ DiffOpt. empty_input_sensitivities! (model)
70+ direction_p = 3.0
71+ DiffOpt. set_forward_parameter (model, p, direction_p)
72+ DiffOpt. forward_differentiate! (model)
73+ @test DiffOpt. get_forward_objective (model) ≈ sign_p * sign * 6 * direction_p atol = ATOL rtol = RTOL
74+
75+ end
76+ end
77+
78+ return
79+ end
80+
81+ function test_obj ()
82+
83+ for (MODEL, SOLVER) in [
84+ (DiffOpt. diff_model, HiGHS. Optimizer),
85+ (DiffOpt. diff_model, SCS. Optimizer),
86+ (DiffOpt. diff_model, Ipopt. Optimizer),
87+ (DiffOpt. quadratic_diff_model, HiGHS. Optimizer),
88+ (DiffOpt. quadratic_diff_model, SCS. Optimizer),
89+ (DiffOpt. quadratic_diff_model, Ipopt. Optimizer),
90+ (DiffOpt. conic_diff_model, HiGHS. Optimizer),
91+ (DiffOpt. conic_diff_model, SCS. Optimizer),
92+ (DiffOpt. conic_diff_model, Ipopt. Optimizer),
93+ (DiffOpt. nonlinear_diff_model, HiGHS. Optimizer),
94+ (DiffOpt. nonlinear_diff_model, SCS. Optimizer),
95+ (DiffOpt. nonlinear_diff_model, Ipopt. Optimizer),
96+ ],
97+ ineq in [true , false ],
98+ _min in [true , false ],
99+ flip in [true , false ],
100+ with_bridge_type in [Float64, nothing ]
101+
102+ if isnothing (with_bridge_type) && SOLVER === SCS. Optimizer
103+ continue
104+ end
64105
65106 @testset " $(MODEL) with: $(SOLVER) , $(ineq ? " ineqs" : " eqs" ) , $(_min ? " Min" : " Max" ) , $(flip ? " geq" : " leq" ) bridge:$with_bridge_type " begin
66107 model = MODEL (SOLVER; with_bridge_type)
@@ -71,24 +112,25 @@ function test_obj()
71112 @variable (model, x)
72113 @variable (model, p in Parameter (p_val))
73114 @variable (model, pc in Parameter (pc_val))
74- # if ineq
75- # if !flip
76- # cons = @constraint(model, con, pc * x >= 3 * p)
77- # else
78- # cons = @constraint(model, con, pc * x <= 3 * p)
79- # end
80- # else
115+ if ineq
116+ if ! flip
117+ cons = @constraint (model, con, pc * x >= 3 * p)
118+ else
119+ cons = @constraint (model, con, pc * x <= 3 * p)
120+ end
121+ else
81122 cons = @constraint (model, con, pc * x == 3 * p)
82- # end
83- # sign = flip ? -1 : 1
84- # if _min
85- # @objective(model, Min, 2x * sign)
86- # else
87- # @objective(model, Max, -2x * sign)
88- # end
123+ end
89124
90- for obj_coef in [- 3 , 2 , 5 ]
91- @objective (model, Min, obj_coef * x)
125+ for obj_coef in [2 , 5 ]
126+
127+ sign = flip ? - 1 : 1
128+ dir = _min ? 1 : - 1
129+ if _min
130+ @objective (model, Min, dir * obj_coef * x * sign)
131+ else
132+ @objective (model, Max, dir * obj_coef * x * sign)
133+ end
92134
93135 optimize! (model)
94136 @test value (x) ≈ 3 * p_val / pc_val atol = ATOL rtol = RTOL
@@ -97,27 +139,24 @@ function test_obj()
97139 direction_obj = 2.0
98140 DiffOpt. set_reverse_objective (model, direction_obj)
99141 DiffOpt. reverse_differentiate! (model)
100- @test DiffOpt. get_reverse_parameter (model, p) ≈ obj_coef * direction_obj * 3 / pc_val atol = ATOL rtol = RTOL
101- @test DiffOpt. get_reverse_parameter (model, pc) ≈ - obj_coef * direction_obj * 3 * p_val / (pc_val^ 2 ) atol = ATOL rtol = RTOL
142+ @test DiffOpt. get_reverse_parameter (model, p) ≈ dir * sign * obj_coef * direction_obj * 3 / pc_val atol = ATOL rtol = RTOL
143+ @test DiffOpt. get_reverse_parameter (model, pc) ≈ - dir * sign * obj_coef * direction_obj * 3 * p_val / (pc_val^ 2 ) atol = ATOL rtol = RTOL
102144
103145 DiffOpt. empty_input_sensitivities! (model)
104146 direction_p = 3.0
105147 DiffOpt. set_forward_parameter (model, p, direction_p)
106148 DiffOpt. forward_differentiate! (model)
107- @test DiffOpt. get_forward_objective (model) ≈ obj_coef * direction_p * 3 / pc_val atol = ATOL rtol = RTOL
149+ @test DiffOpt. get_forward_objective (model) ≈ dir * sign * obj_coef * direction_p * 3 / pc_val atol = ATOL rtol = RTOL
108150
109- # stop differentiating with respect to p
151+ # stop differentiating with respect to p
110152 DiffOpt. empty_input_sensitivities! (model)
111153 # differentiate w.r.t. pc
112154 direction_pc = 10.0
113155 DiffOpt. set_forward_parameter (model, pc, direction_pc)
114156 DiffOpt. forward_differentiate! (model)
115157 @test DiffOpt. get_forward_objective (model) ≈
116- - obj_coef * direction_pc * 3 * p_val / pc_val^ 2 atol = ATOL rtol = RTOL
117-
158+ - dir * sign * obj_coef * direction_pc * 3 * p_val / pc_val^ 2 atol = ATOL rtol = RTOL
118159 end
119-
120-
121160 end
122161 end
123162
0 commit comments