-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhybrid.jl
60 lines (48 loc) · 1.81 KB
/
hybrid.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
@kernel function simplebfgs_run!(nlprob, x0s, result, opt, maxiters, abstol, reltol)
i = @index(Global, Linear)
nlcache = remake(nlprob; u0 = x0s[i])
sol = solve(nlcache, opt; maxiters, abstol, reltol)
result[i] = sol.u
end
function SciMLBase.solve!(
cache::HybridPSOCache, opt::HybridPSO{Backend, LocalOpt}, args...;
abstol = nothing,
reltol = nothing,
maxiters = 100, local_maxiters = 10, kwargs...) where {
Backend, LocalOpt <: Union{LBFGS, BFGS}}
pso_cache = cache.pso_cache
sol_pso = solve!(pso_cache)
x0s = sol_pso.original
backend = opt.backend
prob = remake(cache.prob, lb = nothing, ub = nothing)
f = Base.Fix2(prob.f.f, prob.p)
∇f = instantiate_gradient(f, prob.f.adtype)
kernel = simplebfgs_run!(backend)
result = cache.start_points
copyto!(result, x0s)
nlprob = NonlinearProblem{false}(∇f, prob.u0)
nlalg = LocalOpt isa LBFGS ?
SimpleLimitedMemoryBroyden(;
threshold = local_opt.threshold,
linesearch = Val(true)) : SimpleBroyden(; linesearch = Val(true))
t0 = time()
kernel(nlprob,
x0s,
result,
nlalg,
local_maxiters,
abstol,
reltol;
ndrange = length(x0s))
sol_bfgs = (x -> prob.f(x, prob.p)).(result)
sol_bfgs = (x -> isnan(x) ? convert(eltype(prob.u0), Inf) : x).(sol_bfgs)
minobj, ind = findmin(sol_bfgs)
sol_u, sol_obj = minobj > sol_pso.objective ? (sol_pso.u, sol_pso.objective) :
(view(result, ind), minobj)
t1 = time()
# @show sol_pso.stats.time
solve_time = (t1 - t0) + sol_pso.stats.time
SciMLBase.build_solution(SciMLBase.DefaultOptimizationCache(prob.f, prob.p), opt,
sol_u, sol_obj,
stats = Optimization.OptimizationStats(; time = solve_time))
end