Skip to content

Commit 6f7ef29

Browse files
committed
introduce better variable names (and also ones that are more consistent with the rest of the package)
1 parent 0ba652b commit 6f7ef29

File tree

1 file changed

+50
-45
lines changed

1 file changed

+50
-45
lines changed

src/trustRegion.jl

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,9 @@ end
201201
H
202202
g
203203
shrink_counter::Int
204-
step_size
204+
du
205205
u_tmp
206-
u_c
206+
u_cauchy
207207
fu_new
208208
make_new_J::Bool
209209
r::floatType
@@ -227,13 +227,13 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg::TrustRegion,
227227
loss = get_loss(fu1)
228228
uf, linsolve, J, fu2, jac_cache, du = jacobian_caches(alg, f, u, p, Val(iip);
229229
linsolve_kwargs)
230-
u_c = zero(u)
230+
u_tmp = zero(u)
231+
u_cauchy = zero(u)
231232

232233
loss_new = loss
233234
H = zero(J)
234235
g = _mutable_zero(fu1)
235236
shrink_counter = 0
236-
step_size = zero(u)
237237
fu_new = zero(fu1)
238238
make_new_J = true
239239
r = loss
@@ -242,7 +242,7 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg::TrustRegion,
242242
radius_update_scheme = alg.radius_update_scheme
243243

244244
# set default type for all trust region parameters
245-
trustType = Float64 #typeof(alg.initial_trust_radius)
245+
trustType = eltype(u) #typeof(alg.initial_trust_radius)
246246
max_trust_radius = convert(trustType, alg.max_trust_radius)
247247
if iszero(max_trust_radius)
248248
max_trust_radius = convert(trustType, max(norm(fu1), maximum(u) - minimum(u)))
@@ -314,7 +314,7 @@ function SciMLBase.__init(prob::NonlinearProblem{uType, iip}, alg::TrustRegion,
314314
jac_cache, false, maxiters, internalnorm, ReturnCode.Default, abstol, prob,
315315
radius_update_scheme, initial_trust_radius, max_trust_radius, step_threshold,
316316
shrink_threshold, expand_threshold, shrink_factor, expand_factor, loss, loss_new,
317-
H, g, shrink_counter, step_size, du, u_c, fu_new, make_new_J, r, p1, p2, p3, p4, ϵ,
317+
H, g, shrink_counter, du, u_tmp, u_cauchy, fu_new, make_new_J, r, p1, p2, p3, p4, ϵ,
318318
NLStats(1, 0, 0, 0, 0))
319319
end
320320

@@ -337,7 +337,7 @@ function perform_step!(cache::TrustRegionCache{true})
337337
dogleg!(cache)
338338

339339
# Compute the potentially new u
340-
cache.u_tmp .= u .+ cache.step_size
340+
@. cache.u_tmp = u + cache.du
341341
f(cache.fu_new, cache.u_tmp, p)
342342
trust_region_step!(cache)
343343
cache.stats.nf += 1
@@ -358,11 +358,15 @@ function perform_step!(cache::TrustRegionCache{false})
358358

359359
@unpack g, H = cache
360360
# Compute the Newton step.
361-
cache.u_tmp = -H \ g
361+
cache.u_tmp = -1 .* (H \ g)
362362
dogleg!(cache)
363363

364364
# Compute the potentially new u
365-
cache.u_tmp = u .+ cache.step_size
365+
if u isa Number
366+
cache.u_tmp = u + cache.du
367+
else
368+
@. cache.u_tmp = u + cache.du
369+
end
366370
cache.fu_new = f(cache.u_tmp, p)
367371
trust_region_step!(cache)
368372
cache.stats.nf += 1
@@ -382,18 +386,18 @@ function retrospective_step!(cache::TrustRegionCache)
382386
mul!(cache.g, J', fu)
383387
end
384388
cache.stats.njacs += 1
385-
@unpack H, g, step_size = cache
389+
@unpack H, g, du = cache
386390

387391
return -(get_loss(fu_prev) - get_loss(fu)) /
388-
(dot(step_size, g) + dot(step_size, H, step_size) / 2)
392+
(dot(du, g) + dot(du, H, du) / 2)
389393
end
390394

391395
function trust_region_step!(cache::TrustRegionCache)
392-
@unpack fu_new, step_size, g, H, loss, max_trust_r, radius_update_scheme = cache
396+
@unpack fu_new, du, g, H, loss, max_trust_r, radius_update_scheme = cache
393397
cache.loss_new = get_loss(fu_new)
394398

395399
# Compute the ratio of the actual reduction to the predicted reduction.
396-
cache.r = -(loss - cache.loss_new) / (dot(step_size, g) + dot(step_size, H, step_size) / 2)
400+
cache.r = -(loss - cache.loss_new) / (dot(du, g) + dot(du, H, du) / 2)
397401
@unpack r = cache
398402

399403
if radius_update_scheme === RadiusUpdateSchemes.Simple
@@ -437,9 +441,9 @@ function trust_region_step!(cache::TrustRegionCache)
437441
if r < cache.shrink_threshold # default 1 // 10
438442
cache.trust_r *= cache.shrink_factor # default 1 // 2
439443
elseif r >= cache.expand_threshold # default 9 // 10
440-
cache.trust_r = cache.expand_factor * norm(cache.step_size) # default 2
444+
cache.trust_r = cache.expand_factor * norm(cache.du) # default 2
441445
elseif r >= cache.p1 # default 1 // 2
442-
cache.trust_r = max(cache.trust_r, cache.expand_factor * norm(cache.step_size))
446+
cache.trust_r = max(cache.trust_r, cache.expand_factor * norm(cache.du))
443447
end
444448

445449
# convergence test
@@ -458,8 +462,8 @@ function trust_region_step!(cache::TrustRegionCache)
458462
end
459463

460464
if r < 1 // 4
461-
cache.trust_r = (1 // 4) * norm(cache.step_size)
462-
elseif (r > (3 // 4)) && abs(norm(cache.step_size) - cache.trust_r)/cache.trust_r < 1e-6
465+
cache.trust_r = (1 // 4) * norm(cache.du)
466+
elseif (r > (3 // 4)) && abs(norm(cache.du) - cache.trust_r)/cache.trust_r < 1e-6
463467
cache.trust_r = min(2*cache.trust_r, cache.max_trust_r)
464468
end
465469

@@ -473,14 +477,14 @@ function trust_region_step!(cache::TrustRegionCache)
473477
end
474478
# Hei's radius update scheme
475479
@unpack shrink_threshold, p1, p2, p3, p4 = cache
476-
if rfunc(r, shrink_threshold, p1, p3, p4, p2) * cache.internalnorm(step_size) <
480+
if rfunc(r, shrink_threshold, p1, p3, p4, p2) * cache.internalnorm(du) <
477481
cache.trust_r
478482
cache.shrink_counter += 1
479483
else
480484
cache.shrink_counter = 0
481485
end
482486
cache.trust_r = rfunc(r, shrink_threshold, p1, p3, p4, p2) *
483-
cache.internalnorm(step_size)
487+
cache.internalnorm(du)
484488

485489
if iszero(cache.fu) || cache.internalnorm(cache.fu) < cache.abstol ||
486490
cache.internalnorm(g) < cache.ϵ
@@ -492,7 +496,7 @@ function trust_region_step!(cache::TrustRegionCache)
492496
cache.p1 = cache.p2 * cache.p1
493497
cache.shrink_counter += 1
494498
elseif r >= cache.expand_threshold &&
495-
cache.internalnorm(step_size) > cache.trust_r / 2
499+
cache.internalnorm(du) > cache.trust_r / 2
496500
cache.p1 = cache.p3 * cache.p1
497501
cache.shrink_counter = 0
498502
end
@@ -541,7 +545,7 @@ function trust_region_step!(cache::TrustRegionCache)
541545
cache.loss = cache.loss_new
542546
cache.make_new_J = true
543547
if retrospective_step!(cache) >= cache.expand_threshold
544-
cache.trust_r = max(cache.p1 * cache.internalnorm(step_size), cache.trust_r)
548+
cache.trust_r = max(cache.p1 * cache.internalnorm(du), cache.trust_r)
545549
end
546550

547551
else
@@ -556,61 +560,62 @@ function trust_region_step!(cache::TrustRegionCache)
556560
end
557561

558562
function dogleg!(cache::TrustRegionCache{true})
559-
@unpack u_tmp, u_c, trust_r = cache
563+
@unpack u_tmp, u_cauchy, trust_r = cache
560564

561-
# Test if the full step is within the trust region.
565+
# Take the full Gauss-Newton step if lies within the trust region.
562566
if norm(u_tmp) trust_r
563-
cache.step_size .= u_tmp
567+
cache.du .= u_tmp
564568
return
565569
end
566570

567-
# Calcualte Cauchy point, optimum along the steepest descent direction.
568-
l_grad = norm(cache.g)
571+
# Take intersection of steepest descent direction and trust region if Cauchy point lies outside of trust region
572+
l_grad = norm(cache.g) # length of the gradient
569573
d_cauchy = l_grad^3 / dot(cache.g, cache.H, cache.g) # distance of the cauchy point from the current iterate
570-
if d_cauchy > trust_r # cauchy point lies outside of trust region
571-
@. cache.step_size = - (trust_r/l_grad) * cache.g # step to the end of the trust region
574+
if d_cauchy > trust_r
575+
@. cache.du = - (trust_r/l_grad) * cache.g # step to the end of the trust region
572576
return
573577
end
574578

575-
# cauchy point lies inside the trust region
576-
@. u_c = - (d_cauchy/l_grad) * cache.g
577-
578-
# Find the intersection point on the boundary.
579-
@. u_tmp -= u_c # calf of the dogleg, use u_tmp to avoid allocation
580-
θ = dot(u_tmp, u_c) # ~ cos(∠(calf,thigh))
581-
l_calf = dot(u_tmp,u_tmp) # length of the calf of the dogleg
582-
aux = max^2 + l_calf*(trust_r^2 - d_cauchy^2), 0) # technically guaranteed to be non-negative but hedging against floating point issues
583-
τ = ( - θ + sqrt( aux ) ) / l_calf # stepsize along dogleg
584-
@. cache.step_size = u_c + τ * u_tmp
579+
# Take the intersection of dogled with trust region if Cauchy point lies inside the trust region
580+
@. u_cauchy = - (d_cauchy/l_grad) * cache.g # compute Cauchy point
581+
@. u_tmp -= u_cauchy # calf of the dogleg -- use u_tmp to avoid allocation
582+
a = dot(u_tmp, u_tmp)
583+
b = 2*dot(u_cauchy, u_tmp)
584+
c = d_cauchy^2 - trust_r^2
585+
aux = max(b^2 - 4*a*c, 0.0) # technically guaranteed to be non-negative but hedging against floating point issues
586+
τ = (-b + sqrt(aux)) / (2*a) # stepsize along dogleg to trust region boundary
587+
588+
@. cache.du = u_cauchy + τ * u_tmp
585589
end
586590

591+
587592
function dogleg!(cache::TrustRegionCache{false})
588-
@unpack u_tmp, u_c, trust_r = cache
593+
@unpack u_tmp, u_cauchy, trust_r = cache
589594

590595
# Test if the full step is within the trust region.
591596
if norm(u_tmp) trust_r
592-
cache.step_size = deepcopy(u_tmp)
597+
cache.du = deepcopy(u_tmp)
593598
return
594599
end
595600

596601
# Calcualte Cauchy point, optimum along the steepest descent direction.
597602
l_grad = norm(cache.g)
598603
d_cauchy = l_grad^3 / dot(cache.g, cache.H, cache.g) # distance of the cauchy point from the current iterate
599604
if d_cauchy > trust_r # cauchy point lies outside of trust region
600-
cache.step_size = - (trust_r/l_grad) * cache.g # step to the end of the trust region
605+
cache.du = - (trust_r/l_grad) * cache.g # step to the end of the trust region
601606
return
602607
end
603608

604609
# cauchy point lies inside the trust region
605-
u_c = - (d_cauchy/l_grad) * cache.g
610+
u_cauchy = - (d_cauchy/l_grad) * cache.g
606611

607612
# Find the intersection point on the boundary.
608-
u_tmp -= u_c # calf of the dogleg, use u_tmp to avoid allocation
609-
θ = dot(u_tmp, u_c) # ~ cos(∠(calf,thigh))
613+
u_tmp -= u_cauchy # calf of the dogleg, use u_tmp to avoid allocation
614+
θ = dot(u_tmp, u_cauchy) # ~ cos(∠(calf,thigh))
610615
l_calf = dot(u_tmp,u_tmp) # length of the calf of the dogleg
611616
aux = max^2 + l_calf*(trust_r^2 - d_cauchy^2), 0) # technically guaranteed to be non-negative but hedging against floating point issues
612617
τ = ( - θ + sqrt( aux ) ) / l_calf # stepsize along dogleg
613-
cache.step_size = u_c + τ * u_tmp
618+
cache.du = u_cauchy + τ * u_tmp
614619
end
615620

616621
function take_step!(cache::TrustRegionCache{true})

0 commit comments

Comments
 (0)