10
10
enable_hessian_vector_product::Bool = false,
11
11
)
12
12
13
- An AbstractNLPEvaluator for the problem:
14
- ```
15
- min x1 * x4 * (x1 + x2 + x3) + x3
16
- st x1 * x2 * x3 * x4 >= 25
17
- x1^2 + x2^2 + x3^2 + x4^2 = 40
18
- 1 <= x1, x2, x3, x4 <= 5
13
+ An [`MOI.AbstractNLPEvaluator`](@ref) for the problem:
14
+
15
+ ```math
16
+ \\ begin{aligned}
17
+ \\ text{min} \\ & x_1 * x_4 * (x_1 + x_2 + x_3) + x_3 \\\\
18
+ \\ text{subject to}\\ & x_1 * x_2 * x_3 * x_4 \\ ge 25 \\\\
19
+ & x_1^2 + x_2^2 + x_3^2 + x_4^2 = 40 \\\\
20
+ & 1 \\ le x_1, x_2, x_3, x_4 \\ le 5
21
+ \\ end{aligned}
19
22
```
20
- Start at (1,5,5,1)
21
- End at ( 1.000... , 4.743... , 3.821... , 1.379...)
23
+
24
+ The optimal solution is `[ 1.000, 4.743, 3.821, 1.379]`.
22
25
"""
23
26
struct HS071 <: MOI.AbstractNLPEvaluator
24
27
enable_hessian:: Bool
@@ -35,13 +38,13 @@ function MOI.initialize(d::HS071, requested_features::Vector{Symbol})
35
38
for feat in requested_features
36
39
if ! (feat in MOI. features_available (d))
37
40
error (" Unsupported feature $feat " )
38
- # TODO : implement Jac-vec products for solvers that need them
39
41
end
40
42
end
43
+ return
41
44
end
42
45
43
46
function MOI. features_available (d:: HS071 )
44
- features = [:Grad , :Jac , :ExprGraph ]
47
+ features = [:Grad , :Jac , :JacVec , : ExprGraph ]
45
48
if d. enable_hessian
46
49
push! (features, :Hess )
47
50
end
@@ -99,6 +102,26 @@ function MOI.eval_objective_gradient(::HS071, grad_f, x)
99
102
return
100
103
end
101
104
105
+ function MOI. constraint_gradient_structure (:: HS071 , :: Int )
106
+ return [1 , 2 , 3 , 4 ]
107
+ end
108
+
109
+ function MOI. eval_constraint_gradient (:: HS071 , ∇g, x, i)
110
+ @assert 1 <= i <= 2
111
+ if i == 1
112
+ ∇g[1 ] = x[2 ] * x[3 ] * x[4 ] # 1,1
113
+ ∇g[2 ] = x[1 ] * x[3 ] * x[4 ] # 1,2
114
+ ∇g[3 ] = x[1 ] * x[2 ] * x[4 ] # 1,3
115
+ ∇g[4 ] = x[1 ] * x[2 ] * x[3 ] # 1,4
116
+ else
117
+ ∇g[1 ] = 2 * x[1 ] # 2,1
118
+ ∇g[2 ] = 2 * x[2 ] # 2,2
119
+ ∇g[3 ] = 2 * x[3 ] # 2,3
120
+ ∇g[4 ] = 2 * x[4 ] # 2,4
121
+ end
122
+ return
123
+ end
124
+
102
125
function MOI. jacobian_structure (:: HS071 )
103
126
return Tuple{Int64,Int64}[
104
127
(1 , 1 ),
@@ -112,22 +135,6 @@ function MOI.jacobian_structure(::HS071)
112
135
]
113
136
end
114
137
115
- function MOI. hessian_lagrangian_structure (d:: HS071 )
116
- @assert d. enable_hessian
117
- return Tuple{Int64,Int64}[
118
- (1 , 1 ),
119
- (2 , 1 ),
120
- (2 , 2 ),
121
- (3 , 1 ),
122
- (3 , 2 ),
123
- (3 , 3 ),
124
- (4 , 1 ),
125
- (4 , 2 ),
126
- (4 , 3 ),
127
- (4 , 4 ),
128
- ]
129
- end
130
-
131
138
function MOI. eval_constraint_jacobian (:: HS071 , J, x)
132
139
# Constraint (row) 1
133
140
J[1 ] = x[2 ] * x[3 ] * x[4 ] # 1,1
@@ -142,6 +149,17 @@ function MOI.eval_constraint_jacobian(::HS071, J, x)
142
149
return
143
150
end
144
151
152
+ function MOI. eval_constraint_jacobian_product (d:: HS071 , y, x, w)
153
+ y .= zero (eltype (y))
154
+ indices = MOI. jacobian_structure (d)
155
+ J = zeros (length (indices))
156
+ MOI. eval_constraint_jacobian (d, J, x)
157
+ for ((i, j), val) in zip (indices, J)
158
+ y[i] += val * w[j]
159
+ end
160
+ return
161
+ end
162
+
145
163
function MOI. eval_constraint_jacobian_transpose_product (:: HS071 , y, x, w)
146
164
y[1 ] = (x[2 ] * x[3 ] * x[4 ]) * w[1 ] + (2 * x[1 ]) * w[2 ]
147
165
y[2 ] = (x[1 ] * x[3 ] * x[4 ]) * w[1 ] + (2 * x[2 ]) * w[2 ]
@@ -150,6 +168,64 @@ function MOI.eval_constraint_jacobian_transpose_product(::HS071, y, x, w)
150
168
return
151
169
end
152
170
171
+ function MOI. hessian_objective_structure (d:: HS071 )
172
+ return [(1 , 1 ), (2 , 1 ), (3 , 1 ), (4 , 1 ), (4 , 2 ), (4 , 3 )]
173
+ end
174
+
175
+ function MOI. eval_hessian_objective (d:: HS071 , H, x)
176
+ @assert d. enable_hessian
177
+ H[1 ] = 2 * x[4 ] # 1,1
178
+ H[2 ] = x[4 ] # 2,1
179
+ H[3 ] = x[4 ] # 3,1
180
+ H[4 ] = 2 * x[1 ] + x[2 ] + x[3 ] # 4,1
181
+ H[5 ] = x[1 ] # 4,2
182
+ H[6 ] = x[1 ] # 4,3
183
+ return
184
+ end
185
+
186
+ function MOI. hessian_constraint_structure (d:: HS071 , i:: Int )
187
+ @assert 1 <= i <= 2
188
+ if i == 1
189
+ return [(2 , 1 ), (3 , 1 ), (3 , 2 ), (4 , 1 ), (4 , 2 ), (4 , 3 )]
190
+ else
191
+ return [(1 , 1 ), (2 , 2 ), (3 , 3 ), (4 , 4 )]
192
+ end
193
+ end
194
+
195
+ function MOI. eval_hessian_constraint (d:: HS071 , H, x, i)
196
+ @assert d. enable_hessian
197
+ if i == 1
198
+ H[1 ] = x[3 ] * x[4 ] # 2,1
199
+ H[2 ] = x[2 ] * x[4 ] # 3,1
200
+ H[3 ] = x[1 ] * x[4 ] # 3,2
201
+ H[4 ] = x[2 ] * x[3 ] # 4,1
202
+ H[5 ] = x[1 ] * x[3 ] # 4,2
203
+ H[6 ] = x[1 ] * x[2 ] # 4,3
204
+ else
205
+ H[1 ] = 2.0 # 1,1
206
+ H[2 ] = 2.0 # 2,2
207
+ H[3 ] = 2.0 # 3,3
208
+ H[4 ] = 2.0 # 4,4
209
+ end
210
+ return
211
+ end
212
+
213
+ function MOI. hessian_lagrangian_structure (d:: HS071 )
214
+ @assert d. enable_hessian
215
+ return Tuple{Int64,Int64}[
216
+ (1 , 1 ),
217
+ (2 , 1 ),
218
+ (2 , 2 ),
219
+ (3 , 1 ),
220
+ (3 , 2 ),
221
+ (3 , 3 ),
222
+ (4 , 1 ),
223
+ (4 , 2 ),
224
+ (4 , 3 ),
225
+ (4 , 4 ),
226
+ ]
227
+ end
228
+
153
229
function MOI. eval_hessian_lagrangian (d:: HS071 , H, x, σ, μ)
154
230
@assert d. enable_hessian
155
231
# Again, only lower left triangle
@@ -175,7 +251,7 @@ function MOI.eval_hessian_lagrangian(d::HS071, H, x, σ, μ)
175
251
H[1 ] += μ[2 ] * 2 # 1,1
176
252
H[3 ] += μ[2 ] * 2 # 2,2
177
253
H[6 ] += μ[2 ] * 2 # 3,3
178
- H[10 ] += μ[2 ] * 2
254
+ H[10 ] += μ[2 ] * 2 # 4,4
179
255
return
180
256
end
181
257
0 commit comments