Skip to content

Commit 021901e

Browse files
Merge pull request #304 from avik-pal/ap/fix_docs
Fix storing the trace
2 parents 5b14b20 + 4d605b9 commit 021901e

File tree

7 files changed

+64
-61
lines changed

7 files changed

+64
-61
lines changed

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ SciMLOperators = "0.3"
7575
SimpleNonlinearSolve = "0.1.23"
7676
SparseArrays = "<0.0.1, 1"
7777
SparseDiffTools = "2.14"
78+
StableRNGs = "1"
7879
StaticArrays = "1"
7980
Symbolics = "5"
8081
Test = "1"
@@ -98,11 +99,12 @@ NonlinearProblemLibrary = "b7050fa9-e91f-4b37-bcee-a89a063da141"
9899
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
99100
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
100101
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
102+
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
101103
SparseDiffTools = "47a9eef4-7e08-11e9-0b38-333d64bd3804"
102104
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
103105
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
104106
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
105107
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
106108

107109
[targets]
108-
test = ["Aqua", "Enzyme", "BenchmarkTools", "SafeTestsets", "Pkg", "Test", "ForwardDiff", "StaticArrays", "Symbolics", "LinearSolve", "Random", "LinearAlgebra", "Zygote", "SparseDiffTools", "NonlinearProblemLibrary", "LeastSquaresOptim", "FastLevenbergMarquardt", "NaNMath", "BandedMatrices", "DiffEqBase"]
110+
test = ["Aqua", "Enzyme", "BenchmarkTools", "SafeTestsets", "Pkg", "Test", "ForwardDiff", "StaticArrays", "Symbolics", "LinearSolve", "Random", "LinearAlgebra", "Zygote", "SparseDiffTools", "NonlinearProblemLibrary", "LeastSquaresOptim", "FastLevenbergMarquardt", "NaNMath", "BandedMatrices", "DiffEqBase", "StableRNGs"]

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ NonlinearSolve = "1, 2"
3030
NonlinearSolveMINPACK = "0.1"
3131
SciMLBase = "2.4"
3232
SciMLNLSolve = "0.1"
33-
SimpleNonlinearSolve = "0.1.5"
33+
SimpleNonlinearSolve = "0.1.5, 1"
3434
StaticArrays = "1"
3535
SteadyStateDiffEq = "1.10, 2"
3636
Sundials = "4.11"

src/dfsane.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
77
A low-overhead and allocation-free implementation of the df-sane method for solving large-scale nonlinear
88
systems of equations. For in depth information about all the parameters and the algorithm,
9-
see the paper: [W LaCruz, JM Martinez, and M Raydan (2006), Spectral Residual Method without
10-
Gradient Information for Solving Large-Scale Nonlinear Systems of Equations, Mathematics of
11-
Computation, 75, 1429-1448.](https://www.researchgate.net/publication/220576479_Spectral_Residual_Method_without_Gradient_Information_for_Solving_Large-Scale_Nonlinear_Systems_of_Equations)
9+
see the paper [1].
1210
1311
### Keyword Arguments
1412
@@ -40,6 +38,12 @@ Computation, 75, 1429-1448.](https://www.researchgate.net/publication/220576479_
4038
``fn_1 / n^2``.
4139
- `max_inner_iterations`: the maximum number of iterations allowed for the inner loop of the
4240
algorithm. Defaults to `100`.
41+
42+
### References
43+
44+
[1] W LaCruz, JM Martinez, and M Raydan (2006), Spectral Residual Method without Gradient
45+
Information for Solving Large-Scale Nonlinear Systems of Equations, Mathematics of
46+
Computation, 75, 1429-1448.
4347
"""
4448
@kwdef @concrete struct DFSane <: AbstractNonlinearSolveAlgorithm
4549
σ_min = 1e-10

src/trace.jl

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ function __init_trace_history(::Val{show_trace}, trace_level, ::Val{store_trace}
184184
!store_trace && !show_trace && return nothing
185185
entry = __trace_entry(trace_level, 0, u, fu, J, δu)
186186
show_trace && show(entry)
187-
store_trace && return [entry]
187+
store_trace && return NonlinearSolveTraceEntry[entry]
188188
return nothing
189189
end
190190

@@ -218,29 +218,6 @@ function update_trace!(trace::NonlinearSolveTrace{ShT, StT}, iter, u, fu, J, δu
218218
return trace
219219
end
220220

221-
# Needed for Algorithms which directly use `inv(J)` instead of `J`
222-
function update_trace_with_invJ!(trace::NonlinearSolveTrace{ShT, StT}, iter, u, fu, J, δu,
223-
α = 1; last::Val{L} = Val(false)) where {ShT, StT, L}
224-
!StT && !ShT && return nothing
225-
226-
if L
227-
entry = NonlinearSolveTraceEntry(-1, norm(fu, Inf), NaN32, nothing, nothing,
228-
nothing, nothing, nothing)
229-
show(entry)
230-
return trace
231-
end
232-
233-
show_now = ShT && (mod1(iter, trace.trace_level.print_frequency) == 1)
234-
store_now = StT && (mod1(iter, trace.trace_level.store_frequency) == 1)
235-
if show_now || store_now
236-
J_ = trace.trace_level isa TraceMinimal ? J : inv(J)
237-
entry = __trace_entry(trace.trace_level, iter, u, fu, J_, δu, α)
238-
end
239-
store_now && push!(trace.history, entry)
240-
show_now && show(entry)
241-
return trace
242-
end
243-
244221
function update_trace!(cache::AbstractNonlinearSolveCache, α = true)
245222
trace = __getproperty(cache, Val(:trace))
246223
trace === nothing && return nothing
@@ -252,8 +229,8 @@ function update_trace!(cache::AbstractNonlinearSolveCache, α = true)
252229
update_trace!(trace, cache.stats.nsteps + 1, get_u(cache), get_fu(cache),
253230
nothing, cache.du, α)
254231
else
255-
update_trace_with_invJ!(trace, cache.stats.nsteps + 1, get_u(cache),
256-
get_fu(cache), J_inv, cache.du, α)
232+
update_trace!(trace, cache.stats.nsteps + 1, get_u(cache), get_fu(cache),
233+
ApplyArray(inv, J_inv), cache.du, α)
257234
end
258235
else
259236
update_trace!(trace, cache.stats.nsteps + 1, get_u(cache), get_fu(cache), J,

src/trustRegion.jl

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
11
"""
22
RadiusUpdateSchemes
33
4-
`RadiusUpdateSchemes` is the standard enum interface for different types of radius update schemes
5-
implemented in the Trust Region method. These schemes specify how the radius of the so-called trust region
6-
is updated after each iteration of the algorithm. The specific role and caveats associated with each
7-
scheme are provided below.
4+
`RadiusUpdateSchemes` is the standard enum interface for different types of radius update
5+
schemes implemented in the Trust Region method. These schemes specify how the radius of the
6+
so-called trust region is updated after each iteration of the algorithm. The specific role
7+
and caveats associated with each scheme are provided below.
88
99
## Using `RadiusUpdateSchemes`
1010
11-
`RadiusUpdateSchemes` uses the standard EnumX interface (https://github.com/fredrikekre/EnumX.jl),
12-
and hence inherits all properties of being an EnumX, including the type of each constituent enum
13-
states as `RadiusUpdateSchemes.T`. Simply put the desired scheme as follows:
11+
`RadiusUpdateSchemes` uses the standard
12+
[EnumX Interface](https://github.com/fredrikekre/EnumX.jl), and hence inherits all
13+
properties of being an EnumX, including the type of each constituent enum states as
14+
`RadiusUpdateSchemes.T`. Simply put the desired scheme as follows:
1415
`TrustRegion(radius_update_scheme = your desired update scheme)`. For example,
1516
`sol = solve(prob, alg=TrustRegion(radius_update_scheme = RadiusUpdateSchemes.Hei))`.
1617
"""
1718
@enumx RadiusUpdateSchemes begin
1819
"""
1920
RadiusUpdateSchemes.Simple
2021
21-
The simple or conventional radius update scheme. This scheme is chosen by default
22-
and follows the conventional approach to update the trust region radius, i.e. if the
23-
trial step is accepted it increases the radius by a fixed factor (bounded by a maximum radius)
22+
The simple or conventional radius update scheme. This scheme is chosen by default and
23+
follows the conventional approach to update the trust region radius, i.e. if the trial
24+
step is accepted it increases the radius by a fixed factor (bounded by a maximum radius)
2425
and if the trial step is rejected, it shrinks the radius by a fixed factor.
2526
"""
2627
Simple
2728

2829
"""
2930
RadiusUpdateSchemes.NLsolve
3031
31-
The same updating scheme as in NLsolve's (https://github.com/JuliaNLSolvers/NLsolve.jl) trust region dogleg implementation.
32+
The same updating scheme as in NLsolve's (https://github.com/JuliaNLSolvers/NLsolve.jl)
33+
trust region dogleg implementation.
3234
"""
3335
NLsolve
3436

@@ -42,40 +44,57 @@ states as `RadiusUpdateSchemes.T`. Simply put the desired scheme as follows:
4244
"""
4345
RadiusUpdateSchemes.Hei
4446
45-
This scheme is proposed by [Hei, L.] (https://www.jstor.org/stable/43693061). The trust region radius
46-
depends on the size (norm) of the current step size. The hypothesis is to let the radius converge to zero
47-
as the iterations progress, which is more reliable and robust for ill-conditioned as well as degenerate
48-
problems.
47+
This scheme is proposed by Hei, L. [1]. The trust region radius depends on the size
48+
(norm) of the current step size. The hypothesis is to let the radius converge to zero as
49+
the iterations progress, which is more reliable and robust for ill-conditioned as well
50+
as degenerate problems.
51+
52+
[1] Hei, Long. "A self-adaptive trust region algorithm." Journal of Computational
53+
Mathematics (2003): 229-236.
4954
"""
5055
Hei
5156

5257
"""
5358
RadiusUpdateSchemes.Yuan
5459
55-
This scheme is proposed by [Yuan, Y.] (https://www.researchgate.net/publication/249011466_A_new_trust_region_algorithm_with_trust_region_radius_converging_to_zero).
56-
Similar to Hei's scheme, the trust region is updated in a way so that it converges to zero, however here,
57-
the radius depends on the size (norm) of the current gradient of the objective (merit) function. The hypothesis
58-
is that the step size is bounded by the gradient size, so it makes sense to let the radius depend on the gradient.
60+
This scheme is proposed by Yuan, Y [1]. Similar to Hei's scheme, the trust region is
61+
updated in a way so that it converges to zero, however here, the radius depends on the
62+
size (norm) of the current gradient of the objective (merit) function. The hypothesis is
63+
that the step size is bounded by the gradient size, so it makes sense to let the radius
64+
depend on the gradient.
65+
66+
[1] Fan, Jinyan, Jianyu Pan, and Hongyan Song. "A retrospective trust region algorithm
67+
with trust region converging to zero." Journal of Computational Mathematics 34.4 (2016):
68+
421-436.
5969
"""
6070
Yuan
6171

6272
"""
6373
RadiusUpdateSchemes.Bastin
6474
65-
This scheme is proposed by [Bastin, et al.] (https://www.researchgate.net/publication/225100660_A_retrospective_trust-region_method_for_unconstrained_optimization).
66-
The scheme is called a retrospective update scheme as it uses the model function at the current
67-
iteration to compute the ratio of the actual reduction and the predicted reduction in the previous
68-
trial step, and use this ratio to update the trust region radius. The hypothesis is to exploit the information
69-
made available during the optimization process in order to vary the accuracy of the objective function computation.
75+
This scheme is proposed by Bastin, et al. [1]. The scheme is called a retrospective
76+
update scheme as it uses the model function at the current iteration to compute the
77+
ratio of the actual reduction and the predicted reduction in the previous trial step,
78+
and use this ratio to update the trust region radius. The hypothesis is to exploit the
79+
information made available during the optimization process in order to vary the accuracy
80+
of the objective function computation.
81+
82+
[1] Bastin, Fabian, et al. "A retrospective trust-region method for unconstrained
83+
optimization." Mathematical programming 123 (2010): 395-418.
7084
"""
7185
Bastin
7286

7387
"""
7488
RadiusUpdateSchemes.Fan
7589
76-
This scheme is proposed by [Fan, J.] (https://link.springer.com/article/10.1007/s10589-005-3078-8). It is very much similar to
77-
Hei's and Yuan's schemes as it lets the trust region radius depend on the current size (norm) of the objective (merit)
78-
function itself. These new update schemes are known to improve local convergence.
90+
This scheme is proposed by Fan, J. [1]. It is very much similar to Hei's and Yuan's
91+
schemes as it lets the trust region radius depend on the current size (norm) of the
92+
objective (merit) function itself. These new update schemes are known to improve local
93+
convergence.
94+
95+
[1] Fan, Jinyan. "Convergence rate of the trust region method for nonlinear equations
96+
under local error bound condition." Computational Optimization and Applications 34.2
97+
(2006): 215-227.
7998
"""
8099
Fan
81100
end

test/nonlinear_least_squares.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using NonlinearSolve, LinearSolve, LinearAlgebra, Test, Random, ForwardDiff, Zygote
1+
using NonlinearSolve,
2+
LinearSolve, LinearAlgebra, Test, StableRNGs, Random, ForwardDiff, Zygote
23
import FastLevenbergMarquardt, LeastSquaresOptim
34

45
true_function(x, θ) = @. θ[1] * exp(θ[2] * x) * cos(θ[3] * x + θ[4])
@@ -21,7 +22,7 @@ function loss_function(resid, θ, p)
2122
return resid
2223
end
2324

24-
θ_init = θ_true .+ randn!(similar(θ_true)) * 0.1
25+
θ_init = θ_true .+ randn!(StableRNG(0), similar(θ_true)) * 0.1
2526
prob_oop = NonlinearLeastSquaresProblem{false}(loss_function, θ_init, x)
2627
prob_iip = NonlinearLeastSquaresProblem(NonlinearFunction(loss_function;
2728
resid_prototype = zero(y_target)), θ_init, x)

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ end
1414
@time begin
1515
if GROUP == "All" || GROUP == "Core"
1616
@time @safetestset "Quality Assurance" include("qa.jl")
17+
@time @safetestset "Nonlinear Least Squares" include("nonlinear_least_squares.jl")
1718
@time @safetestset "Basic Tests + Some AD" include("basictests.jl")
1819
@time @safetestset "Sparsity Tests" include("sparse.jl")
1920
@time @safetestset "Polyalgs" include("polyalgs.jl")
2021
@time @safetestset "Matrix Resizing" include("matrix_resizing.jl")
21-
@time @safetestset "Nonlinear Least Squares" include("nonlinear_least_squares.jl")
2222
@time @safetestset "Infeasible Problems" include("infeasible.jl")
2323
end
2424

0 commit comments

Comments
 (0)