-
-
Notifications
You must be signed in to change notification settings - Fork 77
Expand file tree
/
Copy pathNonlinearSolveFirstOrder.jl
More file actions
158 lines (131 loc) · 5.25 KB
/
Copy pathNonlinearSolveFirstOrder.jl
File metadata and controls
158 lines (131 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
"""
NonlinearSolveFirstOrder
First-order nonlinear and nonlinear least-squares solver algorithms.
This subpackage implements Newton, Gauss-Newton, trust-region, pseudo-transient,
and related algorithms that are re-exported by NonlinearSolve.jl. Users typically
load `NonlinearSolve` and pass these algorithms to `solve`; solver-package authors
may depend on this package directly when they need the first-order implementations.
### Example
```julia
using NonlinearSolveFirstOrder, SciMLBase
prob = NonlinearProblem((u, p) -> u^2 - p, 1.0, 2.0)
sol = solve(prob, NewtonRaphson())
```
"""
module NonlinearSolveFirstOrder
using ConcreteStructs: @concrete
using PrecompileTools: @compile_workload, @setup_workload
using Reexport: @reexport
using Setfield: @set!
using ADTypes: ADTypes
using ArrayInterface: ArrayInterface
using LinearAlgebra: LinearAlgebra, Diagonal, dot, diagind
using LineSearch: BackTracking
using StaticArraysCore: SArray
using CommonSolve: CommonSolve, init
using LinearSolve: LinearSolve # Trigger Linear Solve extension in NonlinearSolveBase
using MaybeInplace: @bb
using NonlinearSolveBase: NonlinearSolveBase, AbstractNonlinearSolveAlgorithm,
AbstractNonlinearSolveCache, AbstractDampingFunction,
AbstractDampingFunctionCache, AbstractTrustRegionMethod,
AbstractTrustRegionMethodCache,
Utils, InternalAPI, get_timer_output, @static_timeit,
update_trace!, L2_NORM, NonlinearSolvePolyAlgorithm,
NewtonDescent, DampedNewtonDescent, GeodesicAcceleration,
Dogleg, NonlinearSolveForwardDiffCache, NonlinearVerbosity, reused_jacobian
using SciMLBase: SciMLBase, AbstractNonlinearProblem, NLStats, ReturnCode,
NonlinearFunction,
NonlinearLeastSquaresProblem, NonlinearProblem, NoSpecialize
using SciMLLogging: @SciMLMessage, None, AbstractVerbosityPreset
using SciMLJacobianOperators: VecJacOperator, JacVecOperator, StatefulJacobianOperator
using FiniteDiff: FiniteDiff # Default Finite Difference Method
using ForwardDiff: ForwardDiff, Dual # Default Forward Mode AD
include("jacobian_reuse.jl")
include("solve.jl")
include("raphson.jl")
include("eisenstat_walker.jl")
include("gauss_newton.jl")
include("levenberg_marquardt.jl")
include("trust_region.jl")
include("pseudo_transient.jl")
include("poly_algs.jl")
include("forward_diff.jl")
@setup_workload begin
nonlinear_functions = (
(NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), 0.1),
(NonlinearFunction{false, NoSpecialize}((u, p) -> u .* u .- p), [0.1]),
(NonlinearFunction{true, NoSpecialize}((du, u, p) -> du .= u .* u .- p), [0.1]),
)
nonlinear_problems = NonlinearProblem[]
for (fn, u0) in nonlinear_functions
push!(nonlinear_problems, NonlinearProblem(fn, u0, 2.0))
end
nonlinear_functions = (
(NonlinearFunction{false, NoSpecialize}((u, p) -> (u .^ 2 .- p)[1:1]), [0.1, 0.0]),
(
NonlinearFunction{false, NoSpecialize}(
(
u, p,
) -> vcat(u .* u .- p, u .* u .- p)
),
[0.1, 0.1],
),
(
NonlinearFunction{true, NoSpecialize}(
(du, u, p) -> du[1] = u[1] * u[1] - p, resid_prototype = zeros(1)
),
[0.1, 0.0],
),
(
NonlinearFunction{true, NoSpecialize}(
(du, u, p) -> du .= vcat(u .* u .- p, u .* u .- p), resid_prototype = zeros(4)
),
[0.1, 0.1],
),
)
nlls_problems = NonlinearLeastSquaresProblem[]
for (fn, u0) in nonlinear_functions
push!(nlls_problems, NonlinearLeastSquaresProblem(fn, u0, 2.0))
end
# AutoDePSpecialize opaque-p path: an isbits `p` packs into an `OpaqueParams`
# and a non-isbits `p` into an `OpaqueRef`. Each container gives a single
# wrapped-residual signature shared across all parameter types of that kind,
# so precompiling one solve per container lets first solves with struct/array
# parameters skip compilation entirely.
push!(
nonlinear_problems, NonlinearProblem(
NonlinearFunction{true, SciMLBase.AutoDePSpecialize}(
(du, u, p) -> (du .= u .* u .- p.a)
), [0.1], (a = 2.0,)
)
)
push!(
nonlinear_problems, NonlinearProblem(
NonlinearFunction{true, SciMLBase.AutoDePSpecialize}(
(du, u, p) -> (du .= u .* u .- p[1])
), [0.1], [2.0]
)
)
nlp_algs = [NewtonRaphson(), TrustRegion(), LevenbergMarquardt()]
nlls_algs = [GaussNewton(), TrustRegion(), LevenbergMarquardt()]
@compile_workload begin
@sync begin
for prob in nonlinear_problems, alg in nlp_algs
Threads.@spawn CommonSolve.solve(prob, alg; abstol = 1.0e-2, verbose = false)
end
for prob in nlls_problems, alg in nlls_algs
Threads.@spawn CommonSolve.solve(prob, alg; abstol = 1.0e-2, verbose = false)
end
end
end
end
@reexport using SciMLBase, NonlinearSolveBase
export NewtonRaphson, PseudoTransient
export GaussNewton, LevenbergMarquardt, TrustRegion
export EisenstatWalkerForcing2
export JacobianReuse
export RadiusUpdateSchemes
export GeneralizedFirstOrderAlgorithm
# Polyalgorithms
export RobustMultiNewton, FastShortcutNLLSPolyalg
end