Skip to content

Commit f2f5035

Browse files
committed
Add a result type for Descent Algorithms
1 parent b389d0e commit f2f5035

11 files changed

+51
-27
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "NonlinearSolve"
22
uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec"
33
authors = ["SciML"]
4-
version = "3.10.1"
4+
version = "3.11.0"
55

66
[deps]
77
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
@@ -76,7 +76,7 @@ LazyArrays = "1.8.2"
7676
LeastSquaresOptim = "0.8.5"
7777
LineSearches = "7.2"
7878
LinearAlgebra = "1.10"
79-
LinearSolve = "2.21"
79+
LinearSolve = "2.29"
8080
MINPACK = "1.2"
8181
MaybeInplace = "0.1.1"
8282
NLSolvers = "0.5"

src/NonlinearSolve.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ include("adtypes.jl")
5050
include("timer_outputs.jl")
5151
include("internal/helpers.jl")
5252

53+
include("descent/common.jl")
5354
include("descent/newton.jl")
5455
include("descent/steepest.jl")
5556
include("descent/dogleg.jl")

src/abstract_types.jl

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Abstract Type for all Descent Caches.
6666
### `__internal_solve!` specification
6767
6868
```julia
69-
δu, success, intermediates = __internal_solve!(
69+
descent_result = __internal_solve!(
7070
cache::AbstractDescentCache, J, fu, u, idx::Val; skip_solve::Bool = false, kwargs...)
7171
```
7272
@@ -81,12 +81,7 @@ Abstract Type for all Descent Caches.
8181
8282
#### Returned values
8383
84-
- `δu`: the descent direction.
85-
- `success`: Certain Descent Algorithms can reject a descent direction for example
86-
`GeodesicAcceleration`.
87-
- `intermediates`: A named tuple containing intermediates computed during the solve.
88-
For example, `GeodesicAcceleration` returns `NamedTuple{(:v, :a)}` containing the
89-
"velocity" and "acceleration" terms.
84+
- `descent_result`: Result in a [`DescentResult`](@ref).
9085
9186
### Interface Functions
9287

src/core/approximate_jacobian.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,16 +282,17 @@ function __step!(cache::ApproximateJacobianSolveCache{INV, GB, iip};
282282
@static_timeit cache.timer "descent" begin
283283
if cache.trustregion_cache !== nothing &&
284284
hasfield(typeof(cache.trustregion_cache), :trust_region)
285-
δu, descent_success, descent_intermediates = __internal_solve!(
285+
descent_result = __internal_solve!(
286286
cache.descent_cache, J, cache.fu, cache.u; new_jacobian,
287287
trust_region = cache.trustregion_cache.trust_region)
288288
else
289-
δu, descent_success, descent_intermediates = __internal_solve!(
289+
descent_result = __internal_solve!(
290290
cache.descent_cache, J, cache.fu, cache.u; new_jacobian)
291291
end
292292
end
293+
δu, descent_intermediates = descent_result.δu, descent_result.extras
293294

294-
if descent_success
295+
if descent_result.success
295296
if GB === :LineSearch
296297
@static_timeit cache.timer "linesearch" begin
297298
needs_reset, α = __internal_solve!(cache.linesearch_cache, cache.u, δu)

src/core/generalized_first_order.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,16 +221,17 @@ function __step!(cache::GeneralizedFirstOrderAlgorithmCache{iip, GB};
221221
@static_timeit cache.timer "descent" begin
222222
if cache.trustregion_cache !== nothing &&
223223
hasfield(typeof(cache.trustregion_cache), :trust_region)
224-
δu, descent_success, descent_intermediates = __internal_solve!(
224+
descent_result = __internal_solve!(
225225
cache.descent_cache, J, cache.fu, cache.u; new_jacobian,
226226
trust_region = cache.trustregion_cache.trust_region)
227227
else
228-
δu, descent_success, descent_intermediates = __internal_solve!(
228+
descent_result = __internal_solve!(
229229
cache.descent_cache, J, cache.fu, cache.u; new_jacobian)
230230
end
231231
end
232+
δu, descent_intermediates = descent_result.δu, descent_result.extras
232233

233-
if descent_success
234+
if descent_result.success
234235
cache.make_new_jacobian = true
235236
if GB === :LineSearch
236237
@static_timeit cache.timer "linesearch" begin

src/descent/common.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
DescentResult(; δu = missing, u = missing, success::Bool = true, extras = (;))
3+
4+
Construct a `DescentResult` object.
5+
6+
### Keyword Arguments
7+
8+
- `δu`: The descent direction.
9+
- `u`: The new iterate. This is provided only for multi-step methods currently.
10+
- `success`: Certain Descent Algorithms can reject a descent direction for example
11+
[`GeodesicAcceleration`](@ref).
12+
- `extras`: A named tuple containing intermediates computed during the solve.
13+
For example, [`GeodesicAcceleration`](@ref) returns `NamedTuple{(:v, :a)}` containing
14+
the "velocity" and "acceleration" terms.
15+
"""
16+
@concrete struct DescentResult
17+
δu
18+
u
19+
success::Bool
20+
extras
21+
end
22+
23+
function DescentResult(; δu = missing, u = missing, success::Bool = true, extras = (;))
24+
@assert δu !== missing || u !== missing
25+
return DescentResult(δu, u, success, extras)
26+
end

src/descent/damped_newton.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ function __internal_solve!(cache::DampedNewtonDescentCache{INV, mode}, J, fu,
135135
u, idx::Val{N} = Val(1); skip_solve::Bool = false,
136136
new_jacobian::Bool = true, kwargs...) where {INV, N, mode}
137137
δu = get_du(cache, idx)
138-
skip_solve && return δu, true, (;)
138+
skip_solve && return DescentResult(; δu)
139139

140140
recompute_A = idx === Val(1)
141141

@@ -208,7 +208,7 @@ function __internal_solve!(cache::DampedNewtonDescentCache{INV, mode}, J, fu,
208208

209209
@bb @. δu *= -1
210210
set_du!(cache, δu, idx)
211-
return δu, true, (;)
211+
return DescentResult(; δu)
212212
end
213213

214214
# Define special concatenation for certain Array combinations

src/descent/dogleg.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function __internal_solve!(cache::DoglegCache{INV, NF}, J, fu, u, idx::Val{N} =
8888
if cache.internalnorm(δu_newton) trust_region
8989
@bb copyto!(δu, δu_newton)
9090
set_du!(cache, δu, idx)
91-
return δu, true, (; δuJᵀJδu = T(NaN))
91+
return DescentResult(; δu, extras = (; δuJᵀJδu = T(NaN)))
9292
end
9393

9494
# Take intersection of steepest descent direction and trust region if Cauchy point lies
@@ -115,7 +115,7 @@ function __internal_solve!(cache::DoglegCache{INV, NF}, J, fu, u, idx::Val{N} =
115115
λ = trust_region / l_grad
116116
@bb @. δu = λ * δu_cauchy
117117
set_du!(cache, δu, idx)
118-
return δu, true, (; δuJᵀJδu = λ^2 * δuJᵀJδu)
118+
return DescentResult(; δu, extras = (; δuJᵀJδu = λ^2 * δuJᵀJδu))
119119
end
120120

121121
# FIXME: For anything other than 2-norm a quadratic root will give incorrect results
@@ -133,5 +133,5 @@ function __internal_solve!(cache::DoglegCache{INV, NF}, J, fu, u, idx::Val{N} =
133133

134134
@bb @. δu = cache.δu_cache_1 + τ * cache.δu_cache_2
135135
set_du!(cache, δu, idx)
136-
return δu, true, (; δuJᵀJδu = T(NaN))
136+
return DescentResult(; δu, extras = (; δuJᵀJδu = T(NaN)))
137137
end

src/descent/geodesic_acceleration.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ end
105105
function __internal_solve!(cache::GeodesicAccelerationCache, J, fu, u, idx::Val{N} = Val(1);
106106
skip_solve::Bool = false, kwargs...) where {N}
107107
a, v, δu = get_acceleration(cache, idx), get_velocity(cache, idx), get_du(cache, idx)
108-
skip_solve && return δu, true, (; a, v)
108+
skip_solve && return DescentResult(; δu, extras = (; a, v))
109109
v, _, _ = __internal_solve!(
110110
cache.descent_cache, J, fu, u, Val(2N - 1); skip_solve, kwargs...)
111111

@@ -130,5 +130,5 @@ function __internal_solve!(cache::GeodesicAccelerationCache, J, fu, u, idx::Val{
130130
cache.last_step_accepted = false
131131
end
132132

133-
return δu, cache.last_step_accepted, (; a, v)
133+
return DescentResult(; δu, success = cache.last_step_accepted, extras = (; a, v))
134134
end

src/descent/newton.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function __internal_solve!(
7575
cache::NewtonDescentCache{INV, false}, J, fu, u, idx::Val = Val(1);
7676
skip_solve::Bool = false, new_jacobian::Bool = true, kwargs...) where {INV}
7777
δu = get_du(cache, idx)
78-
skip_solve && return δu, true, (;)
78+
skip_solve && return DescentResult(; δu)
7979
if INV
8080
@assert J!==nothing "`J` must be provided when `pre_inverted = Val(true)`."
8181
@bb δu = J × vec(fu)
@@ -89,14 +89,14 @@ function __internal_solve!(
8989
end
9090
@bb @. δu *= -1
9191
set_du!(cache, δu, idx)
92-
return δu, true, (;)
92+
return DescentResult(; δu)
9393
end
9494

9595
function __internal_solve!(
9696
cache::NewtonDescentCache{false, true}, J, fu, u, idx::Val = Val(1);
9797
skip_solve::Bool = false, new_jacobian::Bool = true, kwargs...)
9898
δu = get_du(cache, idx)
99-
skip_solve && return δu, true, (;)
99+
skip_solve && return DescentResult(; δu)
100100
if idx === Val(1)
101101
@bb cache.JᵀJ_cache = transpose(J) × J
102102
end
@@ -109,5 +109,5 @@ function __internal_solve!(
109109
end
110110
@bb @. δu *= -1
111111
set_du!(cache, δu, idx)
112-
return δu, true, (;)
112+
return DescentResult(; δu)
113113
end

0 commit comments

Comments
 (0)