Skip to content

Commit ddfe753

Browse files
authored
Merge branch 'master' into qqy/siam_ext
2 parents bff7b31 + a5abae8 commit ddfe753

15 files changed

+449
-24
lines changed

Project.toml

Lines changed: 16 additions & 8 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.1.2"
4+
version = "3.2.0"
55

66
[deps]
77
ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
@@ -32,27 +32,31 @@ UnPack = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
3232
[weakdeps]
3333
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
3434
FastLevenbergMarquardt = "7a0df574-e128-4d35-8cbd-3d84502bf7ce"
35+
FixedPointAcceleration = "817d07cb-a79a-5c30-9a31-890123675176"
3536
LeastSquaresOptim = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891"
3637
MINPACK = "4854310b-de5a-5eb6-a2a5-c1dee2bd17f9"
3738
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
3839
SIAMFANLEquations = "084e46ad-d928-497d-ad5e-07fa361a48c4"
40+
SpeedMapping = "f1835b91-879b-4a3f-a438-e4baacf14412"
3941
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
4042
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
4143

4244
[extensions]
4345
NonlinearSolveBandedMatricesExt = "BandedMatrices"
4446
NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt"
47+
NonlinearSolveFixedPointAccelerationExt = "FixedPointAcceleration"
4548
NonlinearSolveLeastSquaresOptimExt = "LeastSquaresOptim"
4649
NonlinearSolveMINPACKExt = "MINPACK"
4750
NonlinearSolveNLsolveExt = "NLsolve"
4851
NonlinearSolveSIAMFANLEquationsExt = "SIAMFANLEquations"
52+
NonlinearSolveSpeedMappingExt = "SpeedMapping"
4953
NonlinearSolveSymbolicsExt = "Symbolics"
5054
NonlinearSolveZygoteExt = "Zygote"
5155

5256
[compat]
5357
ADTypes = "0.2.5"
5458
Aqua = "0.8"
55-
ArrayInterface = "7.6"
59+
ArrayInterface = "7.7"
5660
BandedMatrices = "1.4"
5761
BenchmarkTools = "1.4"
5862
ConcreteStructs = "0.2"
@@ -62,6 +66,7 @@ Enzyme = "0.11.11"
6266
FastBroadcast = "0.2.8"
6367
FastLevenbergMarquardt = "0.1"
6468
FiniteDiff = "2.21"
69+
FixedPointAcceleration = "0.3"
6570
ForwardDiff = "0.10.36"
6671
LazyArrays = "1.8.2"
6772
LeastSquaresOptim = "0.8.5"
@@ -73,20 +78,21 @@ MaybeInplace = "0.1.1"
7378
NLsolve = "4.5"
7479
NaNMath = "1"
7580
NonlinearProblemLibrary = "0.1.1"
76-
OrdinaryDiffEq = "6"
81+
OrdinaryDiffEq = "6.63"
7782
Pkg = "1"
7883
PrecompileTools = "1.2"
79-
Printf = "<0.0.1, 1"
80-
Random = "<0.0.1, 1"
81-
RecursiveArrayTools = "3.0"
84+
Printf = "1.9"
85+
Random = "1.91"
86+
RecursiveArrayTools = "3.2"
8287
Reexport = "1.2"
8388
SafeTestsets = "0.1"
8489
SciMLBase = "2.11"
8590
SciMLOperators = "0.3.7"
8691
SIAMFANLEquations = "1.0.1"
8792
SimpleNonlinearSolve = "1.0.2"
88-
SparseArrays = "<0.0.1, 1"
93+
SparseArrays = "1.9"
8994
SparseDiffTools = "2.14"
95+
SpeedMapping = "0.3"
9096
StableRNGs = "1"
9197
StaticArrays = "1.7"
9298
Symbolics = "5.13"
@@ -102,6 +108,7 @@ BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
102108
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
103109
Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9"
104110
FastLevenbergMarquardt = "7a0df574-e128-4d35-8cbd-3d84502bf7ce"
111+
FixedPointAcceleration = "817d07cb-a79a-5c30-9a31-890123675176"
105112
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
106113
LeastSquaresOptim = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891"
107114
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
@@ -116,11 +123,12 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
116123
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
117124
SIAMFANLEquations = "084e46ad-d928-497d-ad5e-07fa361a48c4"
118125
SparseDiffTools = "47a9eef4-7e08-11e9-0b38-333d64bd3804"
126+
SpeedMapping = "f1835b91-879b-4a3f-a438-e4baacf14412"
119127
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
120128
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
121129
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
122130
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
123131
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
124132

125133
[targets]
126-
test = ["Aqua", "Enzyme", "BenchmarkTools", "SafeTestsets", "Pkg", "Test", "ForwardDiff", "StaticArrays", "Symbolics", "LinearSolve", "Random", "LinearAlgebra", "Zygote", "SparseDiffTools", "NonlinearProblemLibrary", "LeastSquaresOptim", "FastLevenbergMarquardt", "NaNMath", "BandedMatrices", "DiffEqBase", "StableRNGs", "MINPACK", "NLsolve", "OrdinaryDiffEq", "SIAMFANLEquations"]
134+
test = ["Aqua", "Enzyme", "BenchmarkTools", "SafeTestsets", "Pkg", "Test", "ForwardDiff", "StaticArrays", "Symbolics", "LinearSolve", "Random", "LinearAlgebra", "Zygote", "SparseDiffTools", "NonlinearProblemLibrary", "LeastSquaresOptim", "FastLevenbergMarquardt", "NaNMath", "BandedMatrices", "DiffEqBase", "StableRNGs", "MINPACK", "NLsolve", "OrdinaryDiffEq", "SpeedMapping", "FixedPointAcceleration", "SIAMFANLEquations"]

docs/pages.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pages = ["index.md",
2020
"solvers/BracketingSolvers.md",
2121
"solvers/SteadyStateSolvers.md",
2222
"solvers/NonlinearLeastSquaresSolvers.md",
23+
"solvers/FixedPointSolvers.md",
2324
"solvers/LineSearch.md"],
2425
"Detailed Solver APIs" => Any["api/nonlinearsolve.md",
2526
"api/simplenonlinearsolve.md",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# FixedPointAcceleration.jl
2+
3+
This is a extension for importing solvers from FixedPointAcceleration.jl into the SciML
4+
interface. Note that these solvers do not come by default, and thus one needs to install
5+
the package before using these solvers:
6+
7+
```julia
8+
using Pkg
9+
Pkg.add("FixedPointAcceleration")
10+
using FixedPointAcceleration, NonlinearSolve
11+
```
12+
13+
## Solver API
14+
15+
```@docs
16+
FixedPointAccelerationJL
17+
```

docs/src/api/speedmapping.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SpeedMapping.jl
2+
3+
This is a extension for importing solvers from SpeedMapping.jl into the SciML
4+
interface. Note that these solvers do not come by default, and thus one needs to install
5+
the package before using these solvers:
6+
7+
```julia
8+
using Pkg
9+
Pkg.add("SpeedMapping")
10+
using SpeedMapping, NonlinearSolve
11+
```
12+
13+
## Solver API
14+
15+
```@docs
16+
SpeedMappingJL
17+
```

docs/src/solvers/FixedPointSolvers.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Fixed Point Solvers
2+
3+
Currently we don't have an API to directly specify Fixed Point Solvers. However, a Fixed
4+
Point Problem can be trivially converted to a Root Finding Problem. Say we want to solve:
5+
6+
```math
7+
f(u) = u
8+
```
9+
10+
This can be written as:
11+
12+
```math
13+
g(u) = f(u) - u = 0
14+
```
15+
16+
``g(u) = 0`` is a root finding problem. Note that we can use any root finding
17+
algorithm to solve this problem. However, this is often not the most efficient way to
18+
solve a fixed point problem. We provide a few algorithms available via extensions that
19+
are more efficient for fixed point problems.
20+
21+
Note that even if you use one of the Fixed Point Solvers mentioned here, you must still
22+
use the `NonlinearProblem` API to specify the problem, i.e., ``g(u) = 0``.
23+
24+
## Recommended Methods
25+
26+
Using [native NonlinearSolve.jl methods](@ref nonlinearsystemsolvers) is the recommended
27+
approach. For systems where constructing Jacobian Matrices are expensive, we recommend
28+
using a Krylov Method with one of those solvers.
29+
30+
## Full List of Methods
31+
32+
We are only listing the methods that natively solve fixed point problems.
33+
34+
### SpeedMapping.jl
35+
36+
- `SpeedMappingJL()`: accelerates the convergence of a mapping to a fixed point by the
37+
Alternating cyclic extrapolation algorithm (ACX).
38+
39+
### FixedPointAcceleration.jl
40+
41+
- `FixedPointAccelerationJL()`: accelerates the convergence of a mapping to a fixed point
42+
by the Anderson acceleration algorithm and a few other methods.

docs/src/solvers/NonlinearSystemSolvers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# [Nonlinear System Solvers](@id nonlinearsystemsolvers)
22

3-
`solve(prob::NonlinearProblem,alg;kwargs)`
3+
`solve(prob::NonlinearProblem, alg; kwargs)`
44

55
Solves for ``f(u)=0`` in the problem defined by `prob` using the algorithm
66
`alg`. If no algorithm is given, a default algorithm will be chosen.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module NonlinearSolveFixedPointAccelerationExt
2+
3+
using NonlinearSolve, FixedPointAcceleration, DiffEqBase, SciMLBase
4+
5+
function SciMLBase.__solve(prob::NonlinearProblem, alg::FixedPointAccelerationJL, args...;
6+
abstol = nothing, maxiters = 1000, alias_u0::Bool = false,
7+
show_trace::Val{PrintReports} = Val(false), termination_condition = nothing,
8+
kwargs...) where {PrintReports}
9+
@assert (termination_condition ===
10+
nothing)||(termination_condition isa AbsNormTerminationMode) "SpeedMappingJL does not support termination conditions!"
11+
12+
u0 = NonlinearSolve.__maybe_unaliased(prob.u0, alias_u0)
13+
u_size = size(u0)
14+
T = eltype(u0)
15+
iip = isinplace(prob)
16+
p = prob.p
17+
18+
if !iip && prob.u0 isa Number
19+
# FixedPointAcceleration makes the scalar problem into a vector problem
20+
f = (u) -> [prob.f(u[1], p) .+ u[1]]
21+
elseif !iip && prob.u0 isa AbstractVector
22+
f = (u) -> (prob.f(u, p) .+ u)
23+
elseif !iip && prob.u0 isa AbstractArray
24+
f = (u) -> vec(prob.f(reshape(u, u_size), p) .+ u)
25+
elseif iip && prob.u0 isa AbstractVector
26+
du = similar(u0)
27+
f = (u) -> (prob.f(du, u, p); du .+ u)
28+
else
29+
du = similar(u0)
30+
f = (u) -> (prob.f(du, reshape(u, u_size), p); vec(du) .+ u)
31+
end
32+
33+
tol = abstol === nothing ? real(oneunit(T)) * (eps(real(one(T))))^(4 // 5) : abstol
34+
35+
sol = fixed_point(f, NonlinearSolve._vec(u0); Algorithm = alg.algorithm,
36+
ConvergenceMetricThreshold = tol, MaxIter = maxiters, MaxM = alg.m,
37+
ExtrapolationPeriod = alg.extrapolation_period, Dampening = alg.dampening,
38+
PrintReports, ReplaceInvalids = alg.replace_invalids,
39+
ConditionNumberThreshold = alg.condition_number_threshold, quiet_errors = true)
40+
41+
res = prob.u0 isa Number ? first(sol.FixedPoint_) : sol.FixedPoint_
42+
if res === missing
43+
resid = NonlinearSolve.evaluate_f(prob, u0)
44+
res = u0
45+
converged = false
46+
else
47+
resid = NonlinearSolve.evaluate_f(prob, res)
48+
converged = maximum(abs, resid) tol
49+
end
50+
return SciMLBase.build_solution(prob, alg, res, resid;
51+
retcode = converged ? ReturnCode.Success : ReturnCode.Failure,
52+
stats = SciMLBase.NLStats(sol.Iterations_, 0, 0, 0, sol.Iterations_),
53+
original = sol)
54+
end
55+
56+
end

ext/NonlinearSolveMINPACKExt.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using MINPACK
55

66
function SciMLBase.__solve(prob::Union{NonlinearProblem{uType, iip},
77
NonlinearLeastSquaresProblem{uType, iip}}, alg::CMINPACK, args...;
8-
abstol = 1e-6, maxiters = 100000, alias_u0::Bool = false,
8+
abstol = nothing, maxiters = 100000, alias_u0::Bool = false,
99
termination_condition = nothing, kwargs...) where {uType, iip}
1010
@assert (termination_condition ===
1111
nothing)||(termination_condition isa AbsNormTerminationMode) "CMINPACK does not support termination conditions!"
@@ -16,6 +16,7 @@ function SciMLBase.__solve(prob::Union{NonlinearProblem{uType, iip},
1616
u0 = NonlinearSolve.__maybe_unaliased(prob.u0, alias_u0)
1717
end
1818

19+
T = eltype(u0)
1920
sizeu = size(prob.u0)
2021
p = prob.p
2122

@@ -25,11 +26,11 @@ function SciMLBase.__solve(prob::Union{NonlinearProblem{uType, iip},
2526

2627
if !iip && prob.u0 isa Number
2728
f! = (du, u) -> (du .= prob.f(first(u), p); Cint(0))
28-
elseif !iip && prob.u0 isa Vector{Float64}
29+
elseif !iip && prob.u0 isa AbstractVector
2930
f! = (du, u) -> (du .= prob.f(u, p); Cint(0))
3031
elseif !iip && prob.u0 isa AbstractArray
3132
f! = (du, u) -> (du .= vec(prob.f(reshape(u, sizeu), p)); Cint(0))
32-
elseif prob.u0 isa Vector{Float64}
33+
elseif prob.u0 isa AbstractVector
3334
f! = (du, u) -> prob.f(du, u, p)
3435
else # Then it's an in-place function on an abstract array
3536
f! = (du, u) -> (prob.f(reshape(du, sizeu), reshape(u, sizeu), p); du = vec(du); 0)
@@ -43,14 +44,16 @@ function SciMLBase.__solve(prob::Union{NonlinearProblem{uType, iip},
4344
method = ifelse(alg.method === :auto,
4445
ifelse(prob isa NonlinearLeastSquaresProblem, :lm, :hybr), alg.method)
4546

47+
abstol = abstol === nothing ? real(oneunit(T)) * (eps(real(one(T))))^(4 // 5) : abstol
48+
4649
if SciMLBase.has_jac(prob.f)
4750
if !iip && prob.u0 isa Number
4851
g! = (du, u) -> (du .= prob.f.jac(first(u), p); Cint(0))
49-
elseif !iip && prob.u0 isa Vector{Float64}
52+
elseif !iip && prob.u0 isa AbstractVector
5053
g! = (du, u) -> (du .= prob.f.jac(u, p); Cint(0))
5154
elseif !iip && prob.u0 isa AbstractArray
5255
g! = (du, u) -> (du .= vec(prob.f.jac(reshape(u, sizeu), p)); Cint(0))
53-
elseif prob.u0 isa Vector{Float64}
56+
elseif prob.u0 isa AbstractVector
5457
g! = (du, u) -> prob.f.jac(du, u, p)
5558
else # Then it's an in-place function on an abstract array
5659
g! = function (du, u)

ext/NonlinearSolveNLsolveExt.jl

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ module NonlinearSolveNLsolveExt
33
using NonlinearSolve, NLsolve, DiffEqBase, SciMLBase
44
import UnPack: @unpack
55

6-
function SciMLBase.__solve(prob::NonlinearProblem, alg::NLsolveJL, args...; abstol = 1e-6,
7-
maxiters = 1000, alias_u0::Bool = false, termination_condition = nothing, kwargs...)
6+
function SciMLBase.__solve(prob::NonlinearProblem, alg::NLsolveJL, args...;
7+
abstol = nothing, maxiters = 1000, alias_u0::Bool = false,
8+
termination_condition = nothing, kwargs...)
89
@assert (termination_condition ===
910
nothing)||(termination_condition isa AbsNormTerminationMode) "NLsolveJL does not support termination conditions!"
1011

@@ -14,6 +15,7 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::NLsolveJL, args...; abst
1415
u0 = NonlinearSolve.__maybe_unaliased(prob.u0, alias_u0)
1516
end
1617

18+
T = eltype(u0)
1719
iip = isinplace(prob)
1820

1921
sizeu = size(prob.u0)
@@ -25,11 +27,11 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::NLsolveJL, args...; abst
2527

2628
if !iip && prob.u0 isa Number
2729
f! = (du, u) -> (du .= prob.f(first(u), p); Cint(0))
28-
elseif !iip && prob.u0 isa Vector{Float64}
30+
elseif !iip && prob.u0 isa AbstractVector
2931
f! = (du, u) -> (du .= prob.f(u, p); Cint(0))
3032
elseif !iip && prob.u0 isa AbstractArray
3133
f! = (du, u) -> (du .= vec(prob.f(reshape(u, sizeu), p)); Cint(0))
32-
elseif prob.u0 isa Vector{Float64}
34+
elseif prob.u0 isa AbstractVector
3335
f! = (du, u) -> prob.f(du, u, p)
3436
else # Then it's an in-place function on an abstract array
3537
f! = (du, u) -> (prob.f(reshape(du, sizeu), reshape(u, sizeu), p); du = vec(du); 0)
@@ -46,11 +48,11 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::NLsolveJL, args...; abst
4648
if SciMLBase.has_jac(prob.f)
4749
if !iip && prob.u0 isa Number
4850
g! = (du, u) -> (du .= prob.f.jac(first(u), p); Cint(0))
49-
elseif !iip && prob.u0 isa Vector{Float64}
51+
elseif !iip && prob.u0 isa AbstractVector
5052
g! = (du, u) -> (du .= prob.f.jac(u, p); Cint(0))
5153
elseif !iip && prob.u0 isa AbstractArray
5254
g! = (du, u) -> (du .= vec(prob.f.jac(reshape(u, sizeu), p)); Cint(0))
53-
elseif prob.u0 isa Vector{Float64}
55+
elseif prob.u0 isa AbstractVector
5456
g! = (du, u) -> prob.f.jac(du, u, p)
5557
else # Then it's an in-place function on an abstract array
5658
g! = function (du, u)
@@ -68,6 +70,8 @@ function SciMLBase.__solve(prob::NonlinearProblem, alg::NLsolveJL, args...; abst
6870
df = OnceDifferentiable(f!, vec(u0), vec(resid); autodiff)
6971
end
7072

73+
abstol = abstol === nothing ? real(oneunit(T)) * (eps(real(one(T))))^(4 // 5) : abstol
74+
7175
original = nlsolve(df, vec(u0); ftol = abstol, iterations = maxiters, method,
7276
store_trace, extended_trace, linesearch, linsolve, factor, autoscale, m, beta,
7377
show_trace)

0 commit comments

Comments
 (0)