1
1
"""
2
- GaussNewton(; concrete_jac = nothing, linsolve = nothing,
2
+ GaussNewton(; concrete_jac = nothing, linsolve = nothing, linesearch = LineSearch(),
3
3
precs = DEFAULT_PRECS, adkwargs...)
4
4
5
5
An advanced GaussNewton implementation with support for efficient handling of sparse
@@ -30,6 +30,9 @@ for large-scale and numerically-difficult nonlinear least squares problems.
30
30
preconditioners. For more information on specifying preconditioners for LinearSolve
31
31
algorithms, consult the
32
32
[LinearSolve.jl documentation](https://docs.sciml.ai/LinearSolve/stable/).
33
+ - `linesearch`: the line search algorithm to use. Defaults to [`LineSearch()`](@ref),
34
+ which means that no line search is performed. Algorithms from `LineSearches.jl` can be
35
+ used here directly, and they will be converted to the correct `LineSearch`.
33
36
34
37
!!! warning
35
38
@@ -40,16 +43,18 @@ for large-scale and numerically-difficult nonlinear least squares problems.
40
43
ad:: AD
41
44
linsolve
42
45
precs
46
+ linesearch
43
47
end
44
48
45
49
function set_ad (alg:: GaussNewton{CJ} , ad) where {CJ}
46
- return GaussNewton {CJ} (ad, alg. linsolve, alg. precs)
50
+ return GaussNewton {CJ} (ad, alg. linsolve, alg. precs, alg . linesearch )
47
51
end
48
52
49
53
function GaussNewton (; concrete_jac = nothing , linsolve = nothing ,
50
- precs = DEFAULT_PRECS, adkwargs... )
54
+ linesearch = LineSearch (), precs = DEFAULT_PRECS, adkwargs... )
51
55
ad = default_adargs_to_adtype (; adkwargs... )
52
- return GaussNewton {_unwrap_val(concrete_jac)} (ad, linsolve, precs)
56
+ linesearch = linesearch isa LineSearch ? linesearch : LineSearch (; method = linesearch)
57
+ return GaussNewton {_unwrap_val(concrete_jac)} (ad, linsolve, precs, linesearch)
53
58
end
54
59
55
60
@concrete mutable struct GaussNewtonCache{iip} <: AbstractNonlinearSolveCache{iip}
78
83
stats:: NLStats
79
84
tc_cache_1
80
85
tc_cache_2
86
+ ls_cache
81
87
end
82
88
83
89
function SciMLBase. __init (prob:: NonlinearLeastSquaresProblem{uType, iip} , alg_:: GaussNewton ,
@@ -107,7 +113,8 @@ function SciMLBase.__init(prob::NonlinearLeastSquaresProblem{uType, iip}, alg_::
107
113
108
114
return GaussNewtonCache {iip} (f, alg, u, copy (u), fu1, fu2, zero (fu1), du, p, uf,
109
115
linsolve, J, JᵀJ, Jᵀf, jac_cache, false , maxiters, internalnorm, ReturnCode. Default,
110
- abstol, reltol, prob, NLStats (1 , 0 , 0 , 0 , 0 ), tc_cache_1, tc_cache_2)
116
+ abstol, reltol, prob, NLStats (1 , 0 , 0 , 0 , 0 ), tc_cache_1, tc_cache_2,
117
+ init_linesearch_cache (alg. linesearch, f, u, p, fu1, Val (iip)))
111
118
end
112
119
113
120
function perform_step! (cache:: GaussNewtonCache{true} )
@@ -128,7 +135,8 @@ function perform_step!(cache::GaussNewtonCache{true})
128
135
linu = _vec (du), p, reltol = cache. abstol)
129
136
end
130
137
cache. linsolve = linres. cache
131
- @. u = u - du
138
+ α = perform_linesearch! (cache. ls_cache, u, du)
139
+ _axpy! (- α, du, u)
132
140
f (cache. fu_new, u, p)
133
141
134
142
check_and_update! (cache. tc_cache_1, cache, cache. fu_new, cache. u, cache. u_prev)
@@ -169,7 +177,8 @@ function perform_step!(cache::GaussNewtonCache{false})
169
177
end
170
178
cache. linsolve = linres. cache
171
179
end
172
- cache. u = @. u - cache. du # `u` might not support mutation
180
+ α = perform_linesearch! (cache. ls_cache, u, cache. du)
181
+ cache. u = @. u - α * cache. du # `u` might not support mutation
173
182
cache. fu_new = f (cache. u, p)
174
183
175
184
check_and_update! (cache. tc_cache_1, cache, cache. fu_new, cache. u, cache. u_prev)
0 commit comments