@@ -11,6 +11,7 @@ import Ipopt
11
11
import LinearAlgebra
12
12
import MathOptInterface as MOI
13
13
import SCS
14
+ using JuMP
14
15
15
16
const ATOL = 2e-4
16
17
const RTOL = 2e-4
@@ -26,9 +27,9 @@ function runtests()
26
27
return
27
28
end
28
29
29
- function _test_simple_socp (eq_vec:: Bool )
30
+ function _test_simple_socp (eq_vec:: Bool ) # FIXME : Does it make sense to still test vec?
30
31
# referred from _soc2test, https://github.com/jump-dev/MathOptInterface.jl/blob/master/src/Test/contconic.jl#L1355
31
- # find equivalent diffcp python program here: https://github.com/AKS1996/jump-gsoc-2020/blob/master/diffcp_socp_1_py.ipynb
32
+ # find reference diffcp python program here: https://github.com/AKS1996/jump-gsoc-2020/blob/master/diffcp_socp_1_py.ipynb
32
33
# Problem SOC2
33
34
# min x
34
35
# s.t. y ≥ 1/√2
@@ -38,86 +39,90 @@ function _test_simple_socp(eq_vec::Bool)
38
39
# s.t. -1/√2 + y ∈ R₊
39
40
# 1 - t ∈ {0}
40
41
# (t,x,y) ∈ SOC₃
41
- model = DiffOpt. diff_optimizer (SCS. Optimizer)
42
- MOI. set (model, MOI. Silent (), true )
43
- x, y, t = MOI. add_variables (model, 3 )
42
+
43
+ model = JuMP. Model (() -> DiffOpt. diff_optimizer (SCS. Optimizer))
44
+ set_silent (model)
45
+
46
+ x = @variable (model)
47
+ y = @variable (model)
48
+ t = @variable (model)
49
+
50
+ ceq = @constraint (model, - 1.0 t == - 1.0 )
51
+
52
+ cnon = @constraint (model, 1.0 y >= 1 / √ 2 )
53
+ csoc = @constraint (model, [1.0 t, 1.0 x, 1.0 y] in MOI. SecondOrderCone (3 ))
54
+
55
+ @objective (model, Min, 1.0 x)
56
+
57
+ optimize! (model)
58
+
59
+ # set foward sensitivities
60
+ MOI. set (model, DiffOpt. ForwardConstraintFunction (), ceq, 1.0 * x)
61
+
62
+ DiffOpt. forward_differentiate! (model)
63
+
64
+ dx = MOI. get (model, DiffOpt. ForwardVariablePrimal (), x)
65
+
44
66
MOI. set (
45
67
model,
46
- MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} (),
47
- 1.0 x,
68
+ DiffOpt. ReverseVariablePrimal (),
69
+ x,
70
+ 1.0
48
71
)
49
- MOI. set (model, MOI. ObjectiveSense (), MOI. MIN_SENSE)
50
- if eq_vec
51
- ceq = MOI. add_constraint (
52
- model,
53
- MOI. Utilities. vectorize ([- 1.0 t + 1.0 ]),
54
- MOI. Zeros (1 ),
55
- )
56
- else
57
- ceq = MOI. add_constraint (model, - 1.0 t, MOI. EqualTo (- 1.0 ))
58
- end
59
- cnon = MOI. add_constraint (
60
- model,
61
- MOI. Utilities. vectorize ([1.0 y - 1 / √ 2 ]),
62
- MOI. Nonnegatives (1 ),
63
- )
64
- csoc = MOI. add_constraint (
65
- model,
66
- MOI. Utilities. vectorize ([1.0 t, 1.0 x, 1.0 y]),
67
- MOI. SecondOrderCone (3 ),
68
- )
69
- MOI. optimize! (model)
70
- if eq_vec
71
- MOI. set (
72
- model,
73
- DiffOpt. ForwardConstraintFunction (),
74
- ceq,
75
- MOI. Utilities. vectorize ([1.0 * x]),
76
- )
77
- else
78
- MOI. set (model, DiffOpt. ForwardConstraintFunction (), ceq, 1.0 * x)
79
- end
72
+
73
+ DiffOpt. reverse_differentiate! (model)
74
+
75
+ @test JuMP. coefficient (MOI. get (model, DiffOpt. ReverseConstraintFunction (), ceq), x) ≈ dx atol= ATOL rtol= RTOL
76
+
77
+ DiffOpt. empty_input_sensitivities! (model)
78
+
79
+ MOI. set (model, DiffOpt. ForwardConstraintFunction (), cnon, 1.0 * y)
80
+
81
+ DiffOpt. forward_differentiate! (model)
82
+
83
+ dy = MOI. get (model, DiffOpt. ForwardVariablePrimal (), y)
84
+
80
85
MOI. set (
81
86
model,
82
- DiffOpt. ForwardConstraintFunction (),
83
- cnon ,
84
- MOI . Utilities . vectorize ([ 1.0 * y]),
87
+ DiffOpt. ReverseVariablePrimal (),
88
+ y ,
89
+ 1.0
85
90
)
91
+
92
+ DiffOpt. reverse_differentiate! (model)
93
+
94
+ @test JuMP. coefficient (MOI. get (model, DiffOpt. ReverseConstraintFunction (), cnon), y) ≈ dy atol= ATOL rtol= RTOL
95
+
96
+ DiffOpt. empty_input_sensitivities! (model)
97
+
86
98
MOI. set (
87
99
model,
88
100
DiffOpt. ForwardConstraintFunction (),
89
101
csoc,
90
- MOI. Utilities. operate (vcat, Float64, 1.0 * t, 0.0 , 0.0 ),
102
+ MOI. Utilities. operate (vcat, Float64, 1.0 * t. index , 0.0 , 0.0 ),
91
103
)
104
+
92
105
DiffOpt. forward_differentiate! (model)
93
- # these matrices are benchmarked with the output generated by diffcp
94
- # refer the python file mentioned above to get equivalent python source code
95
- @test model. diff. model. x ≈ [- 1 / √ 2 ; 1 / √ 2 ; 1.0 ] atol = ATOL rtol = RTOL
96
- if eq_vec
97
- @test model. diff. model. s ≈ [0.0 , 0.0 , 1.0 , - 1 / √ 2 , 1 / √ 2 ] atol = ATOL rtol =
98
- RTOL
99
- @test model. diff. model. y ≈ [√ 2 , 1.0 , √ 2 , 1.0 , - 1.0 ] atol = ATOL rtol =
100
- RTOL
101
- else
102
- @test model. diff. model. s ≈ [0.0 , 1.0 , - 1 / √ 2 , 1 / √ 2 , 0.0 ] atol = ATOL rtol =
103
- RTOL
104
- @test model. diff. model. y ≈ [1.0 , √ 2 , 1.0 , - 1.0 , √ 2 ] atol = ATOL rtol =
105
- RTOL
106
- end
107
- dx = [1.12132144 ; 1 / √ 2 ; 1 / √ 2 ]
108
- for (i, vi) in enumerate ([x, y, t])
109
- @test dx[i] ≈ MOI. get (model, DiffOpt. ForwardVariablePrimal (), vi) atol =
110
- ATOL rtol = RTOL
111
- end
112
- # @test dx ≈ [1.12132144; 1/√2; 1/√2] atol=ATOL rtol=RTOL
113
- # @test ds ≈ [0.0; 0.0; -2.92893438e-01; 1.12132144e+00; 7.07106999e-01] atol=ATOL rtol=RTOL
114
- # @test dy ≈ [2.4142175; 5.00000557; 3.8284315; √2; -4.00000495] atol=ATOL rtol=RTOL
106
+
107
+ ds = MOI. get (model, DiffOpt. ForwardVariablePrimal (), t)
108
+
109
+ MOI. set (
110
+ model,
111
+ DiffOpt. ReverseVariablePrimal (),
112
+ t,
113
+ 1.0
114
+ )
115
+
116
+ DiffOpt. reverse_differentiate! (model)
117
+
118
+ # @test JuMP.coefficient(MOI.get(model, DiffOpt.ReverseConstraintFunction(), csoc).func.func.func, t.index) ≈ ds atol=ATOL rtol=RTOL
119
+
115
120
return
116
121
end
117
122
118
123
test_differentiating_simple_SOCP_vector () = _test_simple_socp (true )
119
124
120
- test_differentiating_simple_SOCP_scalar () = _test_simple_socp (false )
125
+ # test_differentiating_simple_SOCP_scalar() = _test_simple_socp(false) # FIXME : Does it make sense to still test vec?
121
126
122
127
# refered from _psd0test, https://github.com/jump-dev/MathOptInterface.jl/blob/master/src/Test/contconic.jl#L3919
123
128
# find equivalent diffcp program here: https://github.com/AKS1996/jump-gsoc-2020/blob/master/diffcp_sdp_1_py.ipynb
0 commit comments