@@ -505,21 +505,23 @@ function dogleg!(cache::TrustRegionCache)
505
505
end
506
506
507
507
# Calcualte Cauchy point, optimum along the steepest descent direction.
508
- δsd = - cache. g
509
- norm_δsd = norm (δsd)
510
- if norm_δsd ≥ trust_r
511
- cache. step_size = δsd .* trust_r / norm_δsd
508
+ l_grad = norm ( cache. g)
509
+ d_cauchy = l_grad ^ 3 / dot (cache . g, cache . H, cache . g) # distance of the cauchy point from the current iterate
510
+ if d_cauchy > trust_r # cauchy point lies outside of trust region
511
+ cache. step_size = - (trust_r / l_grad) * cache . g # step to the end of the trust region
512
512
return
513
513
end
514
+
515
+ # cauchy point lies inside the trust region
516
+ u_c = - (d_cauchy/ l_grad) * cache. g
514
517
515
518
# Find the intersection point on the boundary.
516
- N_sd = u_tmp - δsd
517
- dot_N_sd = dot (N_sd, N_sd)
518
- dot_sd_N_sd = dot (δsd, N_sd)
519
- dot_sd = dot (δsd, δsd)
520
- fact = dot_sd_N_sd^ 2 - dot_N_sd * (dot_sd - trust_r^ 2 )
521
- τ = (- dot_sd_N_sd + sqrt (fact)) / dot_N_sd
522
- cache. step_size = δsd + τ * N_sd
519
+ Δ = u_tmp - u_c # calf of the dogleg
520
+ θ = dot (Δ, u_c) # ~ cos(∠(calf,thigh))
521
+ l_calf = dot (Δ,Δ) # length of the calf of the dogleg
522
+ aux = max (θ^ 2 + l_calf* (trust_r^ 2 - d_cauchy^ 2 ), 0 ) # technically guaranteed to be non-negative but hedging against floating point issues
523
+ τ = ( - θ + sqrt ( aux ) ) / l_calf # stepsize along dogleg
524
+ cache. step_size = u_c + τ * Δ
523
525
end
524
526
525
527
function take_step! (cache:: TrustRegionCache{true} )
0 commit comments