Skip to content

Commit

Permalink
Add PotraPtak3
Browse files Browse the repository at this point in the history
  • Loading branch information
avik-pal committed Feb 13, 2024
1 parent 517f695 commit fb88484
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 6 deletions.
8 changes: 6 additions & 2 deletions src/NonlinearSolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ include("core/spectral_methods.jl")

include("algorithms/raphson.jl")
include("algorithms/pseudo_transient.jl")
include("algorithms/multistep.jl")
include("algorithms/broyden.jl")
include("algorithms/klement.jl")
include("algorithms/lbroyden.jl")
Expand Down Expand Up @@ -131,7 +132,8 @@ include("default.jl")
end

# Core Algorithms
export NewtonRaphson, PseudoTransient, Klement, Broyden, LimitedMemoryBroyden, DFSane
export NewtonRaphson, PseudoTransient, Klement, Broyden, LimitedMemoryBroyden, DFSane,
MultiStepNonlinearSolver
export GaussNewton, LevenbergMarquardt, TrustRegion
export NonlinearSolvePolyAlgorithm,
RobustMultiNewton, FastShortcutNonlinearPolyalg, FastShortcutNLLSPolyalg
Expand All @@ -145,7 +147,9 @@ export GeneralizedFirstOrderAlgorithm, ApproximateJacobianSolveAlgorithm, Genera

# Descent Algorithms
export NewtonDescent, SteepestDescent, Dogleg, DampedNewtonDescent,
GeodesicAcceleration
GeodesicAcceleration, GenericMultiStepDescent
## Multistep Algorithms
export MultiStepSchemes

# Globalization
## Line Search Algorithms
Expand Down
7 changes: 7 additions & 0 deletions src/algorithms/multistep.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function MultiStepNonlinearSolver(; concrete_jac = nothing, linsolve = nothing,

Check warning on line 1 in src/algorithms/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/multistep.jl#L1

Added line #L1 was not covered by tests
scheme = MSS.PotraPtak3, precs = DEFAULT_PRECS, autodiff = nothing)
descent = GenericMultiStepDescent(; scheme, linsolve, precs)

Check warning on line 3 in src/algorithms/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/multistep.jl#L3

Added line #L3 was not covered by tests
# TODO: Use the scheme as the name
return GeneralizedFirstOrderAlgorithm(; concrete_jac, name = :MultiStepNonlinearSolver,

Check warning on line 5 in src/algorithms/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/multistep.jl#L5

Added line #L5 was not covered by tests
descent, jacobian_ad = autodiff)
end
8 changes: 4 additions & 4 deletions src/descent/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ Construct a `DescentResult` object.
### Keyword Arguments
* `δu`: The descent direction.
* `u`: The new iterate. This is provided only for multi-step methods currently.
* `success`: Certain Descent Algorithms can reject a descent direction for example
- `δu`: The descent direction.
- `u`: The new iterate. This is provided only for multi-step methods currently.
- `success`: Certain Descent Algorithms can reject a descent direction for example
[`GeodesicAcceleration`](@ref).
* `extras`: A named tuple containing intermediates computed during the solve.
- `extras`: A named tuple containing intermediates computed during the solve.
For example, [`GeodesicAcceleration`](@ref) returns `NamedTuple{(:v, :a)}` containing
the "velocity" and "acceleration" terms.
"""
Expand Down
134 changes: 134 additions & 0 deletions src/descent/multistep.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
"""
MultiStepSchemes
This module defines the multistep schemes used in the multistep descent algorithms. The
naming convention follows <name of method><order of convergence>. The name of method is
typically the last names of the authors of the paper that introduced the method.
"""
module MultiStepSchemes

abstract type AbstractMultiStepScheme end

function Base.show(io::IO, mss::AbstractMultiStepScheme)
print(io, "MultiStepSchemes.$(string(nameof(typeof(mss)))[3:end])")

Check warning on line 13 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L12-L13

Added lines #L12 - L13 were not covered by tests
end

struct __PotraPtak3 <: AbstractMultiStepScheme end
const PotraPtak3 = __PotraPtak3()

alg_steps(::__PotraPtak3) = 1

Check warning on line 19 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L19

Added line #L19 was not covered by tests

struct __SinghSharma4 <: AbstractMultiStepScheme end
const SinghSharma4 = __SinghSharma4()

alg_steps(::__SinghSharma4) = 3

Check warning on line 24 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L24

Added line #L24 was not covered by tests

struct __SinghSharma5 <: AbstractMultiStepScheme end
const SinghSharma5 = __SinghSharma5()

alg_steps(::__SinghSharma5) = 3

Check warning on line 29 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L29

Added line #L29 was not covered by tests

struct __SinghSharma7 <: AbstractMultiStepScheme end
const SinghSharma7 = __SinghSharma7()

alg_steps(::__SinghSharma7) = 4

Check warning on line 34 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L34

Added line #L34 was not covered by tests

end

const MSS = MultiStepSchemes

@kwdef @concrete struct GenericMultiStepDescent <: AbstractDescentAlgorithm
scheme
linsolve = nothing
precs = DEFAULT_PRECS
end

supports_line_search(::GenericMultiStepDescent) = false
supports_trust_region(::GenericMultiStepDescent) = false

Check warning on line 47 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L46-L47

Added lines #L46 - L47 were not covered by tests

@concrete mutable struct GenericMultiStepDescentCache{S, INV} <: AbstractDescentCache
f
p
δu
δus
scheme::S
lincache
timer
nf::Int
end

@internal_caches GenericMultiStepDescentCache :lincache

function __reinit_internal!(cache::GenericMultiStepDescentCache, args...; p = cache.p,

Check warning on line 62 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L62

Added line #L62 was not covered by tests
kwargs...)
cache.nf = 0
cache.p = p

Check warning on line 65 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L64-L65

Added lines #L64 - L65 were not covered by tests
end

function __δu_caches(scheme::MSS.__PotraPtak3, fu, u, ::Val{N}) where {N}
caches = ntuple(N) do i
@bb δu = similar(u)
@bb y = similar(u)
@bb fy = similar(fu)
@bb δy = similar(u)
@bb u_new = similar(u)
(δu, δy, fy, y, u_new)

Check warning on line 75 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L68-L75

Added lines #L68 - L75 were not covered by tests
end
return first(caches), (N 1 ? nothing : caches[2:end])

Check warning on line 77 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L77

Added line #L77 was not covered by tests
end

function __internal_init(prob::NonlinearProblem, alg::GenericMultiStepDescent, J, fu, u;

Check warning on line 80 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L80

Added line #L80 was not covered by tests
shared::Val{N} = Val(1), pre_inverted::Val{INV} = False, linsolve_kwargs = (;),
abstol = nothing, reltol = nothing, timer = get_timer_output(),
kwargs...) where {INV, N}
δu, δus = __δu_caches(alg.scheme, fu, u, shared)
INV && return GenericMultiStepDescentCache{true}(prob.f, prob.p, δu, δus,

Check warning on line 85 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L84-L85

Added lines #L84 - L85 were not covered by tests
alg.scheme, nothing, timer, 0)
lincache = LinearSolverCache(alg, alg.linsolve, J, _vec(fu), _vec(u); abstol, reltol,

Check warning on line 87 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L87

Added line #L87 was not covered by tests
linsolve_kwargs...)
return GenericMultiStepDescentCache{false}(prob.f, prob.p, δu, δus, alg.scheme,

Check warning on line 89 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L89

Added line #L89 was not covered by tests
lincache, timer, 0)
end

function __internal_init(prob::NonlinearLeastSquaresProblem, alg::GenericMultiStepDescent,

Check warning on line 93 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L93

Added line #L93 was not covered by tests
J, fu, u; kwargs...)
error("Multi-Step Descent Algorithms for NLLS are not implemented yet.")

Check warning on line 95 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L95

Added line #L95 was not covered by tests
end

function __internal_solve!(cache::GenericMultiStepDescentCache{MSS.__PotraPtak3, INV}, J,

Check warning on line 98 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L98

Added line #L98 was not covered by tests
fu, u, idx::Val = Val(1); skip_solve::Bool = false, new_jacobian::Bool = true,
kwargs...) where {INV}
(u_new, δy, fy, y, δu) = get_du(cache, idx)
skip_solve && return DescentResult(; u = u_new)

Check warning on line 102 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L101-L102

Added lines #L101 - L102 were not covered by tests

@static_timeit cache.timer "linear solve" begin
@static_timeit cache.timer "solve and step 1" begin
if INV
J !== nothing && @bb(δu=J × _vec(fu))

Check warning on line 107 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L104-L107

Added lines #L104 - L107 were not covered by tests
else
δu = cache.lincache(; A = J, b = _vec(fu), kwargs..., linu = _vec(δu),

Check warning on line 109 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L109

Added line #L109 was not covered by tests
du = _vec(δu),
reuse_A_if_factorization = !new_jacobian || (idx !== Val(1)))
δu = _restructure(u, δu)

Check warning on line 112 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L112

Added line #L112 was not covered by tests
end
@bb @. y = u - δu

Check warning on line 114 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L114

Added line #L114 was not covered by tests
end

fy = evaluate_f!!(cache.f, fy, y, cache.p)
cache.nf += 1

Check warning on line 118 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L117-L118

Added lines #L117 - L118 were not covered by tests

@static_timeit cache.timer "solve and step 2" begin
if INV
J !== nothing && @bb(δy=J × _vec(fy))

Check warning on line 122 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L120-L122

Added lines #L120 - L122 were not covered by tests
else
δy = cache.lincache(; A = J, b = _vec(fy), kwargs..., linu = _vec(δy),

Check warning on line 124 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L124

Added line #L124 was not covered by tests
du = _vec(δy), reuse_A_if_factorization = true)
δy = _restructure(u, δy)

Check warning on line 126 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L126

Added line #L126 was not covered by tests
end
@bb @. u_new = y - δy

Check warning on line 128 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L128

Added line #L128 was not covered by tests
end
end

set_du!(cache, (u_new, δy, fy, y, δu), idx)
return DescentResult(; u = u_new)

Check warning on line 133 in src/descent/multistep.jl

View check run for this annotation

Codecov / codecov/patch

src/descent/multistep.jl#L132-L133

Added lines #L132 - L133 were not covered by tests
end
1 change: 1 addition & 0 deletions src/internal/tracing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ function update_trace!(cache::AbstractNonlinearSolveCache, α = true)
trace === nothing && return nothing

J = __getproperty(cache, Val(:J))
# TODO: fix tracing for multi-step methods where du is not aliased properly
if J === nothing
update_trace!(trace, get_nsteps(cache) + 1, get_u(cache), get_fu(cache),
nothing, cache.du, α)
Expand Down

0 comments on commit fb88484

Please sign in to comment.