@@ -4,29 +4,51 @@ mutable struct ZeroOrderGPSurrogate <: Function
4
4
f:: Function
5
5
gps:: Vector{<:GP}
6
6
X:: Vector{Vector{Float64}}
7
- y:: Union{Vector{Vector{Float64}}, Vector{Float64}}
7
+ y:: Union{Vector{Vector{Float64}},Vector{Float64}}
8
8
noise:: Float64
9
9
std_multiple:: Float64
10
10
mode:: Symbol
11
11
N:: Int
12
12
every:: Int
13
13
skip:: Int
14
- last:: Union{Symbol, Int}
14
+ last:: Union{Symbol,Int}
15
15
fit_prior:: Bool
16
16
fit_noise:: Bool
17
17
counter:: Int
18
18
end
19
19
function ZeroOrderGPSurrogate (
20
- f, x; kernel = SqExponentialKernel (), X = [x], y = [f (x)], noise = 1e-8 ,
21
- std_multiple = 3.0 , mode = :interval , every = 5 , skip = 10 , last = :all ,
22
- fit_prior = true , fit_noise = false ,
20
+ f,
21
+ x;
22
+ kernel = SqExponentialKernel (),
23
+ X = [x],
24
+ y = [f (x)],
25
+ noise = 1e-8 ,
26
+ std_multiple = 3.0 ,
27
+ mode = :interval ,
28
+ every = 5 ,
29
+ skip = 10 ,
30
+ last = :all ,
31
+ fit_prior = true ,
32
+ fit_noise = false ,
23
33
)
24
34
@assert noise > 0
25
- gps = [GP (AbstractGPs. ConstMean (0.0 ), kernel) for _ in 1 : length (y[1 ])]
35
+ gps = [GP (AbstractGPs. ConstMean (0.0 ), kernel) for _ = 1 : length (y[1 ])]
26
36
N = length (y[1 ])
27
37
return ZeroOrderGPSurrogate (
28
- f, gps, X, y, noise, std_multiple, mode, N, every, skip, last,
29
- fit_prior, fit_noise, 0 ,
38
+ f,
39
+ gps,
40
+ X,
41
+ y,
42
+ noise,
43
+ std_multiple,
44
+ mode,
45
+ N,
46
+ every,
47
+ skip,
48
+ last,
49
+ fit_prior,
50
+ fit_noise,
51
+ 0 ,
30
52
)
31
53
end
32
54
@@ -66,25 +88,27 @@ function fit_mle!(s, gps, X, y, noise, last, fit_noise)
66
88
_X = X
67
89
_y = y
68
90
else
69
- _X = X[max (end - last+ 1 , 1 ): end ]
70
- _y = y[max (end - last+ 1 , 1 ): end ]
91
+ _X = X[max (end - last + 1 , 1 ): end ]
92
+ _y = y[max (end - last + 1 , 1 ): end ]
71
93
end
72
94
obj (θ) = begin
73
95
if _y isa Vector{<: Vector }
74
96
offset = 0
75
- return - sum (map (1 : length (_y[1 ])) do i
76
- l1 = length (xs_uns_1[i][1 ])
77
- un1 = xs_uns_1[i][2 ]
78
- l2 = length (xs_lbs_ubs_uns_2[i][1 ])
79
- un2 = xs_lbs_ubs_uns_2[i][4 ]
80
- _gp = GP (un1 (θ[offset+ 1 : offset+ l1]), un2 (θ[offset+ l1+ 1 : offset+ l1+ l2]))
81
- offset += l1 + l2
82
- if fit_noise
83
- return logpdf (_gp (_X, θ[end ]), getindex .(_y, i))
84
- else
85
- return logpdf (_gp (_X, noise), getindex .(_y, i))
86
- end
87
- end )
97
+ return - sum (
98
+ map (1 : length (_y[1 ])) do i
99
+ l1 = length (xs_uns_1[i][1 ])
100
+ un1 = xs_uns_1[i][2 ]
101
+ l2 = length (xs_lbs_ubs_uns_2[i][1 ])
102
+ un2 = xs_lbs_ubs_uns_2[i][4 ]
103
+ _gp = GP (un1 (θ[offset+ 1 : offset+ l1]), un2 (θ[offset+ l1+ 1 : offset+ l1+ l2]))
104
+ offset += l1 + l2
105
+ if fit_noise
106
+ return logpdf (_gp (_X, θ[end ]), getindex .(_y, i))
107
+ else
108
+ return logpdf (_gp (_X, noise), getindex .(_y, i))
109
+ end
110
+ end ,
111
+ )
88
112
else
89
113
l1 = length (xs_uns_1[1 ][1 ])
90
114
un1 = xs_uns_1[1 ][2 ]
@@ -112,13 +136,15 @@ function fit_mle!(s, gps, X, y, noise, last, fit_noise)
112
136
out = GP (un1 (x[offset+ 1 : offset+ l1]), un2 (x[offset+ l1+ 1 : offset+ l1+ l2]))
113
137
offset += l1 + l2
114
138
return out
115
- end , fit_noise ? x[end ] : noise
139
+ end ,
140
+ fit_noise ? x[end ] : noise
116
141
s. gps = gps
117
142
s. noise = noise
118
143
return s
119
144
end
120
145
function ChainRulesCore. rrule (:: typeof (fit_mle!), s, gp, X, y, noise, last, fit_noise)
121
- return fit_mle! (s, gp, X, y, noise, last, fit_noise), _ -> begin
146
+ return fit_mle! (s, gp, X, y, noise, last, fit_noise),
147
+ _ -> begin
122
148
return ntuple (_ -> NoTangent (), Val (8 ))
123
149
end
124
150
end
@@ -132,20 +158,21 @@ function (s::ZeroOrderGPSurrogate)(x)
132
158
if s. fit_prior && s. counter > s. skip * s. every && (s. counter % s. every) == 0
133
159
fit_mle! (s, s. gps, s. X, s. y, s. noise, s. last, s. fit_noise)
134
160
end
135
- return Interval .(y, y)
161
+ return Interval .(y, y)
136
162
else
137
163
if eltype (s. y) <: Real
138
164
return _call_gp (s. gps[1 ], x, s. X, s. y, s. noise, s. std_multiple)
139
165
else
140
- return map (i -> _call_gp (s. gps[i], x, s. X, getindex .(s. y, i), s. noise, s. std_multiple), 1 : length (s. gps))
166
+ return map (
167
+ i -> _call_gp (s. gps[i], x, s. X, getindex .(s. y, i), s. noise, s. std_multiple),
168
+ 1 : s. N,
169
+ )
141
170
end
142
171
end
143
172
end
144
173
145
174
function _call_gp (gp, x, X, y, noise, std_multiple)
146
- _m, _v = mean_and_var (posterior (
147
- gp (X, noise), y,
148
- ), [x])
175
+ _m, _v = mean_and_var (posterior (gp (X, noise), y), [x])
149
176
m, v = _m[1 ], _v[1 ]
150
177
r = std_multiple * sqrt (v)
151
178
return Interval (m - r, m + r)
@@ -163,7 +190,7 @@ get_lo(x::AbstractVector) = map(get_lo, x)
163
190
_lower_f (s) = get_lo ∘ s
164
191
_equality_f (s) = x -> begin
165
192
t = s (x)
166
- return [getproperty .(t, :lo ); .- getproperty (t, :hi )]
193
+ return [getproperty .(t, :lo ); .- getproperty (t, :hi )]
167
194
end
168
195
169
196
function surrogate_model (vecmodel:: VecModel ; kwargs... )
@@ -172,11 +199,7 @@ function surrogate_model(vecmodel::VecModel; kwargs...)
172
199
if :expensive in vecmodel. objective. flags
173
200
s = surrogate (vecmodel. objective. f, copy (x0); kwargs... )
174
201
push! (surrogates, s)
175
- obj = Objective (
176
- _lower_f (s),
177
- vecmodel. objective. multiple,
178
- vecmodel. objective. flags,
179
- )
202
+ obj = Objective (_lower_f (s), vecmodel. objective. multiple, vecmodel. objective. flags)
180
203
else
181
204
obj = vecmodel. objective
182
205
end
@@ -188,32 +211,41 @@ function surrogate_model(vecmodel::VecModel; kwargs...)
188
211
! (:expensive in c. flags)
189
212
end
190
213
eq_constraints = VectorOfFunctions (cheap_eq_constraints)
191
- ineq_constraints1 = Tuple (mapreduce (vcat, expensive_eq_constraints; init = Union{}[]) do c
192
- @assert c isa EqConstraint
193
- s = surrogate (c, copy (x0); kwargs... )
194
- push! (surrogates, s)
195
- return IneqConstraint (
196
- _equality_f (s), [zero .(c. rhs); zero .(c. rhs)], c. dim * 2 , c. flags,
197
- )
198
- end )
214
+ ineq_constraints1 = Tuple (
215
+ mapreduce (vcat, expensive_eq_constraints; init = Union{}[]) do c
216
+ @assert c isa EqConstraint
217
+ s = surrogate (c, copy (x0); kwargs... )
218
+ push! (surrogates, s)
219
+ return IneqConstraint (
220
+ _equality_f (s),
221
+ [zero .(c. rhs); zero .(c. rhs)],
222
+ c. dim * 2 ,
223
+ c. flags,
224
+ )
225
+ end ,
226
+ )
199
227
ineq_constraints2 = map (vecmodel. ineq_constraints. fs) do c
200
228
@assert c isa IneqConstraint
201
229
if :expensive in c. flags
202
230
s = surrogate (c, copy (x0); kwargs... )
203
231
push! (surrogates, s)
204
- return IneqConstraint (
205
- _lower_f (s), zero .(c. rhs), c. dim, c. flags,
206
- )
232
+ return IneqConstraint (_lower_f (s), zero .(c. rhs), c. dim, c. flags)
207
233
else
208
234
return c
209
235
end
210
236
end
211
- ineq_constraints = VectorOfFunctions (
212
- (ineq_constraints1... , ineq_constraints2... ),
213
- )
237
+ ineq_constraints = VectorOfFunctions ((ineq_constraints1... , ineq_constraints2... ),)
214
238
return VecModel (
215
- obj, eq_constraints, ineq_constraints, vecmodel. sd_constraints, vecmodel. box_min, vecmodel. box_max, vecmodel. init, vecmodel. integer,
216
- ), Tuple (surrogates)
239
+ obj,
240
+ eq_constraints,
241
+ ineq_constraints,
242
+ vecmodel. sd_constraints,
243
+ vecmodel. box_min,
244
+ vecmodel. box_max,
245
+ vecmodel. init,
246
+ vecmodel. integer,
247
+ ),
248
+ Tuple (surrogates)
217
249
end
218
250
219
251
function update_surrogates! (model, surrogates, x)
@@ -229,7 +261,7 @@ function update_surrogates!(model, surrogates, x)
229
261
return o, i, e
230
262
end
231
263
232
- struct BayesOptOptions{S, N <: NamedTuple }
264
+ struct BayesOptOptions{S,N <: NamedTuple }
233
265
sub_options:: S
234
266
maxiter:: Int
235
267
initialize:: Bool
@@ -277,15 +309,21 @@ function BayesOptOptions(;
277
309
)
278
310
end
279
311
280
- mutable struct BayesOptWorkspace{M <: VecModel , S1, X <: AbstractVector , O <: BayesOptOptions , S2 <: Union{Tuple, AbstractVector} } <: Workspace
312
+ mutable struct BayesOptWorkspace{
313
+ M<: VecModel ,
314
+ S1,
315
+ X<: AbstractVector ,
316
+ O<: BayesOptOptions ,
317
+ S2<: Union{Tuple,AbstractVector} ,
318
+ } <: Workspace
281
319
model:: M
282
320
sub_workspace:: S1
283
321
x0:: X
284
322
options:: O
285
323
surrogates:: S2
286
324
end
287
325
288
- struct BayesOptResult{M1, M2, S1 <: AbstractResult , S2} <: AbstractResult
326
+ struct BayesOptResult{M1,M2,S1 <: AbstractResult ,S2} <: AbstractResult
289
327
minimizer:: M1
290
328
minimum:: M2
291
329
niters:: Int
@@ -308,8 +346,12 @@ Returns an iterator over `N` elements of a Sobol sequence between `lowerbounds`
308
346
and `upperbounds`. The first `N` elements of the Sobol sequence are skipped for
309
347
better uniformity (see https://github.com/stevengj/Sobol.jl)
310
348
"""
311
- function ScaledSobolIterator (lowerbounds, upperbounds, N;
312
- seq = SobolSeq (length (lowerbounds)))
349
+ function ScaledSobolIterator (
350
+ lowerbounds,
351
+ upperbounds,
352
+ N;
353
+ seq = SobolSeq (length (lowerbounds)),
354
+ )
313
355
N > 0 && skip (seq, N)
314
356
ScaledSobolIterator (lowerbounds, upperbounds, N, seq)
315
357
end
@@ -389,33 +431,27 @@ function optimize!(workspace::BayesOptWorkspace)
389
431
s. mode = :interval
390
432
end
391
433
end
392
- return BayesOptResult (
393
- minimizer, minval, iter, r, surrogates,
394
- )
434
+ return BayesOptResult (minimizer, minval, iter, r, surrogates)
395
435
end
396
436
397
437
struct BayesOptAlg{A} <: AbstractOptimizer
398
438
sub_alg:: A
399
439
end
400
440
401
441
function Workspace (
402
- model:: VecModel , optimizer:: BayesOptAlg , x0:: AbstractVector ;
403
- options:: BayesOptOptions , surrogates = nothing , kwargs... ,
442
+ model:: VecModel ,
443
+ optimizer:: BayesOptAlg ,
444
+ x0:: AbstractVector ;
445
+ options:: BayesOptOptions ,
446
+ surrogates = nothing ,
447
+ kwargs... ,
404
448
)
405
449
if surrogates != = nothing
406
450
smodel = model
407
451
else
408
452
smodel, surrogates = surrogate_model (model; options. nt... )
409
453
end
410
- sub_workspace = Workspace (
411
- smodel, optimizer. sub_alg, x0;
412
- options = options. sub_options, kwargs... ,
413
- )
414
- return BayesOptWorkspace (
415
- model,
416
- sub_workspace,
417
- x0,
418
- options,
419
- surrogates,
420
- )
454
+ sub_workspace =
455
+ Workspace (smodel, optimizer. sub_alg, x0; options = options. sub_options, kwargs... )
456
+ return BayesOptWorkspace (model, sub_workspace, x0, options, surrogates)
421
457
end
0 commit comments