1- update_g! (d, state, method) = nothing
2- function update_g! (d, state, method:: FirstOrderOptimizer )
3- # Update the function value and gradient
4- value_gradient! (d, state. x)
5- project_tangent! (method. manifold, gradient (d), state. x)
1+ function update_fg! (d, state, :: ZerothOrderOptimizer )
2+ f_x = value! (d, state. x)
3+ state. f_x = f_x
4+ return nothing
65end
7- function update_g! (d, state, method:: Newton )
8- # Update the function value and gradient
9- value_gradient! (d, state. x)
10- end
11- update_fg! (d, state, method) = nothing
12- update_fg! (d, state, method:: ZerothOrderOptimizer ) = value! (d, state. x)
13- function update_fg! (d, state, method:: FirstOrderOptimizer )
14- value_gradient! (d, state. x)
15- project_tangent! (method. manifold, gradient (d), state. x)
16- end
17- function update_fg! (d, state, method:: Newton )
18- value_gradient! (d, state. x)
6+ function update_fg! (d, state, method)
7+ f_x, g_x = value_gradient! (d, state. x)
8+ if hasproperty (method, :manifold )
9+ project_tangent! (method. manifold, g_x, state. x)
10+ end
11+ state. f_x = f_x
12+ copyto! (state. g_x, g_x)
13+ return nothing
1914end
2015
2116# Update the Hessian
22- update_h! (d, state, method) = nothing
23- update_h! (d, state, method:: SecondOrderOptimizer ) = hessian! (d, state. x)
17+ update_h! (d, state, :: Union{ZerothOrderOptimizer,FirstOrderOptimizer} ) = nothing
18+ function update_h! (d, state, :: SecondOrderOptimizer )
19+ H_x = hessian! (d, state. x)
20+ copyto! (state. H_x, H_x)
21+ return nothing
22+ end
2423
2524after_while! (d, state, method, options) = nothing
2625
27- function initial_convergence (d, state, method:: AbstractOptimizer , initial_x, options)
28- gradient! (d, initial_x)
29- stopped = ! isfinite (value (d)) || any (! isfinite, gradient (d))
30- g_residual (d, state) <= options. g_abstol, stopped
26+ function initial_convergence (state:: AbstractOptimizerState , options:: Options )
27+ stopped = ! isfinite (state. f_x) || any (! isfinite, state. g_x)
28+ return g_residual (state) <= options. g_abstol, stopped
3129end
32- function initial_convergence (d, state, method :: ZerothOrderOptimizer , initial_x, options )
30+ function initial_convergence (:: ZerothOrderState , :: Options )
3331 false , false
3432end
33+
3534function optimize (
3635 d:: D ,
3736 initial_x:: Tx ,
@@ -41,7 +40,7 @@ function optimize(
4140) where {D<: AbstractObjective ,M<: AbstractOptimizer ,Tx<: AbstractArray ,T,TCallback}
4241
4342 t0 = time () # Initial time stamp used to control early stopping by options.time_limit
44- tr = OptimizationTrace {typeof(value(d) ),typeof(method)} ()
43+ tr = OptimizationTrace {typeof(state.f_x ),typeof(method)} ()
4544 tracing =
4645 options. store_trace ||
4746 options. show_trace ||
@@ -51,7 +50,7 @@ function optimize(
5150 f_limit_reached, g_limit_reached, h_limit_reached = false , false , false
5251 x_converged, f_converged, f_increased, counter_f_tol = false , false , false , 0
5352
54- g_converged, stopped = initial_convergence (d, state, method, initial_x , options)
53+ g_converged, stopped = initial_convergence (state, options)
5554 converged = g_converged || stopped
5655 # prepare iteration counter (used to make "initial state" trace entry)
5756 iteration = 0
@@ -66,9 +65,7 @@ function optimize(
6665 if ! ls_success
6766 break # it returns true if it's forced by something in update! to stop (eg dx_dg == 0.0 in BFGS, or linesearch errors)
6867 end
69- if ! (method isa NewtonTrustRegion)
70- update_g! (d, state, method) # TODO : Should this be `update_fg!`?
71- end
68+ update_fg! (d, state, method)
7269 x_converged, f_converged, g_converged, f_increased =
7370 assess_convergence (state, d, options)
7471 # For some problems it may be useful to require `f_converged` to be hit multiple times
@@ -113,11 +110,11 @@ function optimize(
113110 end
114111 end
115112
116- if g_calls (d) > 0 && ! all (isfinite, gradient (d) )
113+ if hasproperty (state, :g_x ) && ! all (isfinite, state . g_x )
117114 options. show_warnings && @warn " Terminated early due to NaN in gradient."
118115 break
119116 end
120- if h_calls (d) > 0 && ! (d isa TwiceDifferentiableHV ) && ! all (isfinite, hessian (d) )
117+ if hasproperty (state, :H_x ) && ! all (isfinite, state . H_x )
121118 options. show_warnings && @warn " Terminated early due to NaN in Hessian."
122119 break
123120 end
@@ -127,7 +124,7 @@ function optimize(
127124
128125 # we can just check minimum, as we've earlier enforced same types/eltypes
129126 # in variables besides the option settings
130- Tf = typeof (value (d) )
127+ Tf = typeof (state . f_x )
131128 f_incr_pick = f_increased && ! options. allow_f_increases
132129 stopped_by = (x_converged, f_converged, g_converged,
133130 f_limit_reached = f_limit_reached,
@@ -141,7 +138,7 @@ function optimize(
141138 )
142139
143140 termination_code =
144- _termination_code (d, g_residual (d, state), state, stopped_by, options)
141+ _termination_code (d, g_residual (state), state, stopped_by, options)
145142
146143 return MultivariateOptimizationResults{
147144 typeof (method),
@@ -154,18 +151,18 @@ function optimize(
154151 method,
155152 initial_x,
156153 pick_best_x (f_incr_pick, state),
157- pick_best_f (f_incr_pick, state, d ),
154+ pick_best_f (f_incr_pick, state),
158155 iteration,
159156 Tf (options. x_abstol),
160157 Tf (options. x_reltol),
161158 x_abschange (state),
162159 x_relchange (state),
163160 Tf (options. f_abstol),
164161 Tf (options. f_reltol),
165- f_abschange (d, state),
166- f_relchange (d, state),
162+ f_abschange (state),
163+ f_relchange (state),
167164 Tf (options. g_abstol),
168- g_residual (d, state),
165+ g_residual (state),
169166 tr,
170167 f_calls (d),
171168 g_calls (d),
@@ -186,13 +183,13 @@ function _termination_code(d, gres, state, stopped_by, options)
186183 elseif (iszero (options. x_abstol) && x_abschange (state) <= options. x_abstol) ||
187184 (iszero (options. x_reltol) && x_relchange (state) <= options. x_reltol)
188185 TerminationCode. NoXChange
189- elseif (iszero (options. f_abstol) && f_abschange (d, state) <= options. f_abstol) ||
190- (iszero (options. f_reltol) && f_relchange (d, state) <= options. f_reltol)
186+ elseif (iszero (options. f_abstol) && f_abschange (state) <= options. f_abstol) ||
187+ (iszero (options. f_reltol) && f_relchange (state) <= options. f_reltol)
191188 TerminationCode. NoObjectiveChange
192189 elseif x_abschange (state) <= options. x_abstol || x_relchange (state) <= options. x_reltol
193190 TerminationCode. SmallXChange
194- elseif f_abschange (d, state) <= options. f_abstol ||
195- f_relchange (d, state) <= options. f_reltol
191+ elseif f_abschange (state) <= options. f_abstol ||
192+ f_relchange (state) <= options. f_reltol
196193 TerminationCode. SmallObjectiveChange
197194 elseif stopped_by. ls_failed
198195 TerminationCode. FailedLinesearch
@@ -210,11 +207,11 @@ function _termination_code(d, gres, state, stopped_by, options)
210207 TerminationCode. HessianCalls
211208 elseif stopped_by. f_increased
212209 TerminationCode. ObjectiveIncreased
213- elseif f_calls (d) > 0 && ! isfinite (value (d) )
214- TerminationCode. GradientNotFinite
215- elseif g_calls (d) > 0 && ! all (isfinite, gradient (d) )
210+ elseif ! isfinite (state . f_x )
211+ TerminationCode. ObjectiveNotFinite
212+ elseif hasproperty (state, :g_x ) && ! all (isfinite, state . g_x )
216213 TerminationCode. GradientNotFinite
217- elseif h_calls (d) > 0 && ! (d isa TwiceDifferentiableHV ) && ! all (isfinite, hessian (d) )
214+ elseif hasproperty (state, :H_x ) && ! all (isfinite, state . H_x )
218215 TerminationCode. HessianNotFinite
219216 else
220217 TerminationCode. NotImplemented
0 commit comments