Skip to content

Commit 82f19ee

Browse files
Merge pull request #101 from mkg33/master
Add output struct
2 parents aeca45f + 17bed8c commit 82f19ee

File tree

1 file changed

+117
-173
lines changed

1 file changed

+117
-173
lines changed

src/solve.jl

Lines changed: 117 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
abstract type AbstractOptimizationSolution end #experimental; comments welcome
2+
mutable struct OptimizationSolution{O, Tx, Tf, Tls, Tsb} <: AbstractOptimizationSolution
3+
method::O
4+
initial_x::Tx
5+
minimizer::Tx
6+
minimum::Tf
7+
iterations::Int
8+
iteration_converged::Bool
9+
ls_success::Tls
10+
time_run::Float64
11+
stopped_by::Tsb
12+
end
13+
14+
function Base.show(io::IO, r::AbstractOptimizationSolution)
15+
take = Iterators.take
16+
failure_string = "failure"
17+
if isa(r.ls_success, Bool) && !r.ls_success
18+
failure_string *= " (line search failed)"
19+
end
20+
21+
@printf io " * Status: %s\n\n" r.iteration_converged ? "success" : failure_string
22+
@printf io " * Candidate solution\n"
23+
@printf io " Final objective value: %e\n" r.minimum
24+
@printf io "\n"
25+
@printf io " * Found with\n"
26+
@printf io " Algorithm: %s\n" r.method
27+
return
28+
end
29+
130
struct NullData end
231
const DEFAULT_DATA = Iterators.cycle((NullData(),))
332
Base.iterate(::NullData, i=1) = nothing
@@ -124,34 +153,15 @@ function __solve(prob::OptimizationProblem, opt, data = DEFAULT_DATA;
124153

125154
_time = time()
126155

127-
Optim.MultivariateOptimizationResults(opt,
128-
prob.u0,# initial_x,
129-
θ, #pick_best_x(f_incr_pick, state),
130-
save_best ? first(min_err) : first(x), # pick_best_f(f_incr_pick, state, d),
131-
maxiters, #iteration,
132-
maxiters >= maxiters, #iteration == options.iterations,
133-
true, # x_converged,
134-
0.0,#T(options.x_tol),
135-
0.0,#T(options.x_tol),
136-
NaN,# x_abschange(state),
137-
NaN,# x_abschange(state),
138-
true,# f_converged,
139-
0.0,#T(options.f_tol),
140-
0.0,#T(options.f_tol),
141-
NaN,#f_abschange(d, state),
142-
NaN,#f_abschange(d, state),
143-
true,#g_converged,
144-
0.0,#T(options.g_tol),
145-
NaN,#g_residual(d),
146-
false, #f_increased,
147-
nothing,
148-
maxiters,
149-
maxiters,
150-
0,
151-
true,
152-
NaN,
153-
_time-t0,
154-
NamedTuple())
156+
OptimizationSolution(opt,
157+
prob.u0,# initial_x,
158+
θ, #pick_best_x(f_incr_pick, state),
159+
save_best ? first(min_err) : first(x), # pick_best_f(f_incr_pick, state, d),
160+
maxiters, #iteration,
161+
maxiters >= maxiters, #iteration == options.iterations,
162+
true,
163+
_time-t0,
164+
NamedTuple())
155165
end
156166

157167

@@ -384,34 +394,16 @@ function __init__()
384394
bboptre = !(isnothing(maxiters)) ? BlackBoxOptim.bboptimize(_loss;Method = opt.method, SearchRange = [(prob.lb[i], prob.ub[i]) for i in 1:length(prob.lb)], MaxSteps = maxiters, CallbackFunction = _cb, CallbackInterval = 0.0, kwargs...) : BlackBoxOptim.bboptimize(_loss;Method = opt.method, SearchRange = [(prob.lb[i], prob.ub[i]) for i in 1:length(prob.lb)], CallbackFunction = _cb, CallbackInterval = 0.0, kwargs...)
385395

386396

387-
Optim.MultivariateOptimizationResults(opt.method,
388-
[NaN],# initial_x,
389-
BlackBoxOptim.best_candidate(bboptre), #pick_best_x(f_incr_pick, state),
390-
BlackBoxOptim.best_fitness(bboptre), # pick_best_f(f_incr_pick, state, d),
391-
bboptre.iterations, #iteration,
392-
!(isnothing(maxiters)) ? bboptre.iterations >= maxiters : true, #iteration == options.iterations,
393-
false, # x_converged,
394-
0.0,#T(options.x_tol),
395-
0.0,#T(options.x_tol),
396-
NaN,# x_abschange(state),
397-
NaN,# x_abschange(state),
398-
false,# f_converged,
399-
0.0,#T(options.f_tol),
400-
0.0,#T(options.f_tol),
401-
NaN,#f_abschange(d, state),
402-
NaN,#f_abschange(d, state),
403-
false,#g_converged,
404-
0.0,#T(options.g_tol),
405-
NaN,#g_residual(d),
406-
false, #f_increased,
407-
nothing,
408-
bboptre.f_calls,
409-
0,
410-
0,
411-
true,
412-
NaN,
413-
bboptre.elapsed_time,
414-
NamedTuple())
397+
OptimizationSolution(opt.method,
398+
[NaN],# initial_x,
399+
BlackBoxOptim.best_candidate(bboptre), #pick_best_x(f_incr_pick, state),
400+
BlackBoxOptim.best_fitness(bboptre), # pick_best_f(f_incr_pick, state, d),
401+
bboptre.iterations, #iteration,
402+
!(isnothing(maxiters)) ? bboptre.iterations >= maxiters : true, #iteration == options.iterations,
403+
true,
404+
bboptre.elapsed_time,
405+
NamedTuple())
406+
415407
end
416408
end
417409

@@ -461,38 +453,19 @@ function __init__()
461453
end
462454
end
463455

464-
t0= time()
456+
t0 = time()
465457
(minf,minx,ret) = NLopt.optimize(opt, prob.u0)
466458
_time = time()
467459

468-
Optim.MultivariateOptimizationResults(opt,
469-
prob.u0,# initial_x,
470-
minx, #pick_best_x(f_incr_pick, state),
471-
minf, # pick_best_f(f_incr_pick, state, d),
472-
Int(opt.numevals), #iteration,
473-
!(isnothing(maxiters)) ? opt.numevals >= maxiters : true, #iteration == options.iterations,
474-
false, # x_converged,
475-
0.0,#T(options.x_tol),
476-
0.0,#T(options.x_tol),
477-
NaN,# x_abschange(state),
478-
NaN,# x_abschange(state),
479-
false,# f_converged,
480-
0.0,#T(options.f_tol),
481-
0.0,#T(options.f_tol),
482-
NaN,#f_abschange(d, state),
483-
NaN,#f_abschange(d, state),
484-
false,#g_converged,
485-
0.0,#T(options.g_tol),
486-
NaN,#g_residual(d),
487-
false, #f_increased,
488-
nothing,
489-
Int(opt.numevals),
490-
0,
491-
0,
492-
ret,
493-
NaN,
494-
_time-t0,
495-
NamedTuple())
460+
OptimizationSolution(opt.algorithm,
461+
prob.u0,# initial_x,
462+
minx, #pick_best_x(f_incr_pick, state),
463+
minf, # pick_best_f(f_incr_pick, state, d),
464+
Int(opt.numevals), #iteration,
465+
!(isnothing(maxiters)) ? opt.numevals >= maxiters : true, #iteration == options.iterations,
466+
ret,
467+
_time-t0,
468+
NamedTuple())
496469
end
497470
end
498471

@@ -526,34 +499,15 @@ function __init__()
526499

527500
t1 = time()
528501

529-
Optim.MultivariateOptimizationResults(opt,
530-
[NaN],# initial_x,
531-
p.location, #pick_best_x(f_incr_pick, state),
532-
p.value, # pick_best_f(f_incr_pick, state, d),
533-
0, #iteration,
534-
false, #iteration == options.iterations,
535-
false, # x_converged,
536-
0.0,#T(options.x_tol),
537-
0.0,#T(options.x_tol),
538-
NaN,# x_abschange(state),
539-
NaN,# x_abschange(state),
540-
false,# f_converged,
541-
0.0,#T(options.f_tol),
542-
0.0,#T(options.f_tol),
543-
NaN,#f_abschange(d, state),
544-
NaN,#f_abschange(d, state),
545-
false,#g_converged,
546-
0.0,#T(options.g_tol),
547-
NaN,#g_residual(d),
548-
false, #f_increased,
549-
nothing,
550-
0,
551-
0,
552-
0,
553-
true,
554-
NaN,
555-
t1 - t0,
556-
NamedTuple())
502+
OptimizationSolution(opt,
503+
[NaN],# initial_x,
504+
p.location, #pick_best_x(f_incr_pick, state),
505+
p.value, # pick_best_f(f_incr_pick, state, d),
506+
local_maxiters,
507+
local_maxiters>=opt.maxeval, #not sure if that's correct
508+
true,
509+
t1 - t0,
510+
NamedTuple())
557511
end
558512
end
559513

@@ -588,34 +542,15 @@ function __init__()
588542
box = minimum(root)
589543
t1 = time()
590544

591-
Optim.MultivariateOptimizationResults(opt,
592-
[NaN],# initial_x,
593-
QuadDIRECT.position(box, x0), #pick_best_x(f_incr_pick, state),
594-
QuadDIRECT.value(box), # pick_best_f(f_incr_pick, state, d),
595-
0, #iteration,
596-
false, #iteration == options.iterations,
597-
false, # x_converged,
598-
0.0,#T(options.x_tol),
599-
0.0,#T(options.x_tol),
600-
NaN,# x_abschange(state),
601-
NaN,# x_abschange(state),
602-
false,# f_converged,
603-
0.0,#T(options.f_tol),
604-
0.0,#T(options.f_tol),
605-
NaN,#f_abschange(d, state),
606-
NaN,#f_abschange(d, state),
607-
false,#g_converged,
608-
0.0,#T(options.g_tol),
609-
NaN,#g_residual(d),
610-
false, #f_increased,
611-
nothing,
612-
0,
613-
0,
614-
0,
615-
true,
616-
NaN,
617-
t1 - t0,
618-
NamedTuple())
545+
OptimizationSolution(opt,
546+
[NaN],# initial_x,
547+
QuadDIRECT.position(box, x0), #pick_best_x(f_incr_pick, state),
548+
QuadDIRECT.value(box), # pick_best_f(f_incr_pick, state, d),
549+
!(isnothing(maxiters)) ? maxiters : 0,
550+
box.qnconverged, #not sure if that's correct
551+
true,
552+
t1 - t0,
553+
NamedTuple())
619554
end
620555
end
621556

@@ -657,16 +592,29 @@ function __init__()
657592
return first(x)
658593
end
659594

660-
Evolutionary.optimize(_loss, prob.u0, opt, !isnothing(maxiters) ? Evolutionary.Options(;iterations = maxiters, callback = _cb, kwargs...)
595+
t0 = time()
596+
597+
result = Evolutionary.optimize(_loss, prob.u0, opt, !isnothing(maxiters) ? Evolutionary.Options(;iterations = maxiters, callback = _cb, kwargs...)
661598
: Evolutionary.Options(;callback = _cb, kwargs...))
599+
t1 = time()
600+
601+
OptimizationSolution(summary(result),
602+
prob.u0, #initial_x
603+
Evolutionary.minimizer(result), #pick_best_x
604+
minimum(result), #pick_best_f
605+
Evolutionary.iterations(result), #iteration
606+
Evolutionary.converged(result), #convergence status
607+
true,
608+
t1 - t0,
609+
NamedTuple())
662610
end
663611
end
664612
@require CMAEvolutionStrategy="8d3b24bd-414e-49e0-94fb-163cc3a3e411" begin
665613

666614
struct CMAEvolutionStrategyOpt end
667615

668616
function __solve(prob::OptimizationProblem, opt::CMAEvolutionStrategyOpt, data = DEFAULT_DATA;
669-
cb = (args...) -> (false),
617+
cb = (args...) -> (false), maxiters = nothing,
670618
progress = false, kwargs...)
671619
local x, cur, state
672620

@@ -690,36 +638,32 @@ function __init__()
690638
return first(x)
691639
end
692640

693-
result = CMAEvolutionStrategy.minimize(_loss, prob.u0, 0.1; lower = prob.lb, upper = prob.ub, kwargs...)
694-
695-
Optim.MultivariateOptimizationResults(opt,
696-
prob.u0,# initial_x,
697-
result.logger.xbest[end], #pick_best_x(f_incr_pick, state),
698-
result.logger.fbest[end], # pick_best_f(f_incr_pick, state, d),
699-
0, #iteration,
700-
false, #iteration == options.iterations,
701-
false, # x_converged,
702-
0.0,#T(options.x_tol),
703-
0.0,#T(options.x_tol),
704-
NaN,# x_abschange(state),
705-
NaN,# x_abschange(state),
706-
false,# f_converged,
707-
0.0,#T(options.f_tol),
708-
0.0,#T(options.f_tol),
709-
NaN,#f_abschange(d, state),
710-
NaN,#f_abschange(d, state),
711-
false,#g_converged,
712-
0.0,#T(options.g_tol),
713-
NaN,#g_residual(d),
714-
false, #f_increased,
715-
nothing,
716-
0,
717-
0,
718-
0,
719-
true,
720-
NaN,
721-
result.logger.times[end] - result.logger.times[1],
722-
NamedTuple())
641+
642+
if !(isnothing(maxiters)) && maxiters <= 0.0
643+
error("The number of maxiters has to be a non-negative and non-zero number.")
644+
elseif !(isnothing(maxiters))
645+
maxiters = convert(Int, maxiters)
646+
end
647+
648+
result = CMAEvolutionStrategy.minimize(_loss, prob.u0, 0.1; lower = prob.lb, upper = prob.ub, maxiter = maxiters, kwargs...)
649+
CMAEvolutionStrategy.print_header(result)
650+
CMAEvolutionStrategy.print_result(result)
651+
println("\n")
652+
criterion = true
653+
654+
if (result.stop.reason === :maxtime) #this is an arbitrary choice of convergence (based on the stop.reason values)
655+
criterion = false
656+
end
657+
658+
OptimizationSolution(opt,
659+
prob.u0,# initial_x,
660+
result.logger.xbest[end], #pick_best_x(f_incr_pick, state),
661+
result.logger.fbest[end], # pick_best_f(f_incr_pick, state, d),
662+
length(result.logger.fbest),
663+
criterion,
664+
true,
665+
result.logger.times[end] - result.logger.times[1],
666+
NamedTuple())
723667
end
724668
end
725669
end

0 commit comments

Comments
 (0)