From 8d0578a055735d6a3a797f25f498d26e2260f25b Mon Sep 17 00:00:00 2001 From: Avik Pal Date: Tue, 13 Feb 2024 17:38:12 -0500 Subject: [PATCH] Run Formatter --- docs/make.jl | 2 +- docs/pages.jl | 2 +- docs/src/basics/faq.md | 12 ++++-- docs/src/basics/sparsity_detection.md | 9 +++-- docs/src/tutorials/large_systems.md | 12 ++++-- docs/src/tutorials/modelingtoolkit.md | 6 +-- ext/NonlinearSolveMINPACKExt.jl | 3 +- src/NonlinearSolve.jl | 47 ++++++++++++++--------- src/abstract_types.jl | 6 ++- src/algorithms/broyden.jl | 3 +- src/algorithms/dfsane.jl | 3 +- src/algorithms/extension_algs.jl | 43 ++++++++++++--------- src/algorithms/klement.jl | 5 ++- src/algorithms/lbroyden.jl | 3 +- src/algorithms/levenberg_marquardt.jl | 6 ++- src/core/approximate_jacobian.jl | 6 ++- src/core/generalized_first_order.jl | 6 ++- src/core/spectral_methods.jl | 3 +- src/default.jl | 12 +++--- src/descent/damped_newton.jl | 6 ++- src/descent/geodesic_acceleration.jl | 6 ++- src/globalization/line_search.jl | 6 ++- src/globalization/trust_region.jl | 3 +- src/internal/forward_diff.jl | 11 ++++-- src/internal/helpers.jl | 27 ++++++++----- src/internal/jacobian.jl | 3 +- src/internal/operators.jl | 7 ++-- test/core/nlls_tests.jl | 21 ++++++---- test/core/rootfind_tests.jl | 55 ++++++++++++++++++--------- test/wrappers/nlls_tests.jl | 36 ++++++++++++------ 30 files changed, 235 insertions(+), 135 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 0826acd60..c42e05004 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,6 +1,6 @@ using Documenter, DocumenterCitations using NonlinearSolve, - SimpleNonlinearSolve, Sundials, SteadyStateDiffEq, SciMLBase, DiffEqBase + SimpleNonlinearSolve, Sundials, SteadyStateDiffEq, SciMLBase, DiffEqBase cp(joinpath(@__DIR__, "Manifest.toml"), joinpath(@__DIR__, "src/assets/Manifest.toml"), force = true) diff --git a/docs/pages.jl b/docs/pages.jl index 5c77d7f2c..52791bc45 100644 --- a/docs/pages.jl +++ b/docs/pages.jl @@ -43,5 +43,5 @@ pages = [ "devdocs/operators.md", "devdocs/algorithm_helpers.md"], "Release Notes" => "release_notes.md", - "References" => "references.md", + "References" => "references.md" ] diff --git a/docs/src/basics/faq.md b/docs/src/basics/faq.md index b3eff3d75..e40b57b33 100644 --- a/docs/src/basics/faq.md +++ b/docs/src/basics/faq.md @@ -15,15 +15,19 @@ myfun(x, lv) = x * sin(x) - lv function f(out, levels, u0) for i in 1:N - out[i] = solve(IntervalNonlinearProblem{false}(IntervalNonlinearFunction{false}(myfun), - u0, levels[i]), Falsi()).u + out[i] = solve( + IntervalNonlinearProblem{false}(IntervalNonlinearFunction{false}(myfun), + u0, levels[i]), + Falsi()).u end end function f2(out, levels, u0) for i in 1:N - out[i] = solve(NonlinearProblem{false}(NonlinearFunction{false}(myfun), - u0, levels[i]), SimpleNewtonRaphson()).u + out[i] = solve( + NonlinearProblem{false}(NonlinearFunction{false}(myfun), + u0, levels[i]), + SimpleNewtonRaphson()).u end end diff --git a/docs/src/basics/sparsity_detection.md b/docs/src/basics/sparsity_detection.md index fd1621164..222aebe19 100644 --- a/docs/src/basics/sparsity_detection.md +++ b/docs/src/basics/sparsity_detection.md @@ -22,10 +22,12 @@ NonlinearSolve will automatically perform matrix coloring and use sparse differe Now you can help the solver further by providing the color vector. This can be done by ```julia -prob = NonlinearProblem(NonlinearFunction(nlfunc; sparsity = jac_prototype, +prob = NonlinearProblem( + NonlinearFunction(nlfunc; sparsity = jac_prototype, colorvec = colorvec), x0) # OR -prob = NonlinearProblem(NonlinearFunction(nlfunc; jac_prototype = jac_prototype, +prob = NonlinearProblem( + NonlinearFunction(nlfunc; jac_prototype = jac_prototype, colorvec = colorvec), x0) ``` @@ -47,7 +49,8 @@ algorithm you want to use, then you can create your problem as follows: prob = NonlinearProblem(NonlinearFunction(nlfunc; sparsity = SymbolicsSparsityDetection()), x0) # Remember to have Symbolics.jl loaded # OR -prob = NonlinearProblem(NonlinearFunction(nlfunc; sparsity = ApproximateJacobianSparsity()), +prob = NonlinearProblem( + NonlinearFunction(nlfunc; sparsity = ApproximateJacobianSparsity()), x0) ``` diff --git a/docs/src/tutorials/large_systems.md b/docs/src/tutorials/large_systems.md index 38242c19f..aedd58445 100644 --- a/docs/src/tutorials/large_systems.md +++ b/docs/src/tutorials/large_systems.md @@ -308,10 +308,14 @@ for the exact sparsity detection case, we left out the time it takes to perform sparsity detection. Let's compare the two by setting the sparsity detection algorithms. ```@example ill_conditioned_nlprob -prob_brusselator_2d_exact = NonlinearProblem(NonlinearFunction(brusselator_2d_loop; - sparsity = SymbolicsSparsityDetection()), u0, p; abstol = 1e-10, reltol = 1e-10) -prob_brusselator_2d_approx = NonlinearProblem(NonlinearFunction(brusselator_2d_loop; - sparsity = ApproximateJacobianSparsity()), u0, p; abstol = 1e-10, reltol = 1e-10) +prob_brusselator_2d_exact = NonlinearProblem( + NonlinearFunction(brusselator_2d_loop; + sparsity = SymbolicsSparsityDetection()), + u0, p; abstol = 1e-10, reltol = 1e-10) +prob_brusselator_2d_approx = NonlinearProblem( + NonlinearFunction(brusselator_2d_loop; + sparsity = ApproximateJacobianSparsity()), + u0, p; abstol = 1e-10, reltol = 1e-10) @btime solve(prob_brusselator_2d_exact, NewtonRaphson()); @btime solve(prob_brusselator_2d_approx, NewtonRaphson()); diff --git a/docs/src/tutorials/modelingtoolkit.md b/docs/src/tutorials/modelingtoolkit.md index d6d9711c3..17dbc985e 100644 --- a/docs/src/tutorials/modelingtoolkit.md +++ b/docs/src/tutorials/modelingtoolkit.md @@ -22,8 +22,8 @@ u0 = [x => 1.0, z => 0.0] ps = [σ => 10.0 - ρ => 26.0 - β => 8 / 3] + ρ => 26.0 + β => 8 / 3] prob = NonlinearProblem(ns, u0, ps) sol = solve(prob, NewtonRaphson()) @@ -65,7 +65,7 @@ eqs = [ 0 ~ u2 - cos(u1), 0 ~ u3 - hypot(u1, u2), 0 ~ u4 - hypot(u2, u3), - 0 ~ u5 - hypot(u4, u1), + 0 ~ u5 - hypot(u4, u1) ] @named sys = NonlinearSystem(eqs, [u1, u2, u3, u4, u5], []) ``` diff --git a/ext/NonlinearSolveMINPACKExt.jl b/ext/NonlinearSolveMINPACKExt.jl index a15e8d968..4465051ea 100644 --- a/ext/NonlinearSolveMINPACKExt.jl +++ b/ext/NonlinearSolveMINPACKExt.jl @@ -4,7 +4,8 @@ using MINPACK, NonlinearSolve, SciMLBase import FastClosures: @closure function SciMLBase.__solve(prob::Union{NonlinearLeastSquaresProblem, - NonlinearProblem}, alg::CMINPACK, args...; abstol = nothing, maxiters = 1000, + NonlinearProblem}, + alg::CMINPACK, args...; abstol = nothing, maxiters = 1000, alias_u0::Bool = false, show_trace::Val{ShT} = Val(false), store_trace::Val{StT} = Val(false), termination_condition = nothing, kwargs...) where {ShT, StT} diff --git a/src/NonlinearSolve.jl b/src/NonlinearSolve.jl index a2321ef83..de46fe153 100644 --- a/src/NonlinearSolve.jl +++ b/src/NonlinearSolve.jl @@ -9,13 +9,14 @@ import PrecompileTools: @recompile_invalidations, @compile_workload, @setup_work @recompile_invalidations begin using ADTypes, ConcreteStructs, DiffEqBase, FastBroadcast, FastClosures, LazyArrays, - LineSearches, LinearAlgebra, LinearSolve, MaybeInplace, Preferences, Printf, - SciMLBase, SimpleNonlinearSolve, SparseArrays, SparseDiffTools + LineSearches, LinearAlgebra, LinearSolve, MaybeInplace, Preferences, Printf, + SciMLBase, SimpleNonlinearSolve, SparseArrays, SparseDiffTools import ArrayInterface: undefmatrix, can_setindex, restructure, fast_scalar_indexing import DiffEqBase: AbstractNonlinearTerminationMode, - AbstractSafeNonlinearTerminationMode, AbstractSafeBestNonlinearTerminationMode, - NonlinearSafeTerminationReturnCode, get_termination_mode + AbstractSafeNonlinearTerminationMode, + AbstractSafeBestNonlinearTerminationMode, + NonlinearSafeTerminationReturnCode, get_termination_mode import FiniteDiff import ForwardDiff import ForwardDiff: Dual @@ -23,7 +24,7 @@ import PrecompileTools: @recompile_invalidations, @compile_workload, @setup_work import RecursiveArrayTools: recursivecopy!, recursivefill! import SciMLBase: AbstractNonlinearAlgorithm, JacobianWrapper, AbstractNonlinearProblem, - AbstractSciMLOperator, NLStats, _unwrap_val, has_jac, isinplace + AbstractSciMLOperator, NLStats, _unwrap_val, has_jac, isinplace import SparseDiffTools: AbstractSparsityDetection, AutoSparseEnzyme import StaticArraysCore: StaticArray, SVector, SArray, MArray, Size, SMatrix, MMatrix end @@ -95,20 +96,28 @@ include("default.jl") probs_nlls = NonlinearLeastSquaresProblem[] nlfuncs = ((NonlinearFunction{false}((u, p) -> (u .^ 2 .- p)[1:1]), [0.1, 0.0]), (NonlinearFunction{false}((u, p) -> vcat(u .* u .- p, u .* u .- p)), [0.1, 0.1]), - (NonlinearFunction{true}((du, u, p) -> du[1] = u[1] * u[1] - p, - resid_prototype = zeros(1)), [0.1, 0.0]), - (NonlinearFunction{true}((du, u, p) -> du .= vcat(u .* u .- p, u .* u .- p), - resid_prototype = zeros(4)), [0.1, 0.1])) + ( + NonlinearFunction{true}((du, u, p) -> du[1] = u[1] * u[1] - p, + resid_prototype = zeros(1)), + [0.1, 0.0]), + ( + NonlinearFunction{true}((du, u, p) -> du .= vcat(u .* u .- p, u .* u .- p), + resid_prototype = zeros(4)), + [0.1, 0.1])) for (fn, u0) in nlfuncs push!(probs_nlls, NonlinearLeastSquaresProblem(fn, u0, 2.0)) end nlfuncs = ((NonlinearFunction{false}((u, p) -> (u .^ 2 .- p)[1:1]), Float32[0.1, 0.0]), (NonlinearFunction{false}((u, p) -> vcat(u .* u .- p, u .* u .- p)), Float32[0.1, 0.1]), - (NonlinearFunction{true}((du, u, p) -> du[1] = u[1] * u[1] - p, - resid_prototype = zeros(Float32, 1)), Float32[0.1, 0.0]), - (NonlinearFunction{true}((du, u, p) -> du .= vcat(u .* u .- p, u .* u .- p), - resid_prototype = zeros(Float32, 4)), Float32[0.1, 0.1])) + ( + NonlinearFunction{true}((du, u, p) -> du[1] = u[1] * u[1] - p, + resid_prototype = zeros(Float32, 1)), + Float32[0.1, 0.0]), + ( + NonlinearFunction{true}((du, u, p) -> du .= vcat(u .* u .- p, u .* u .- p), + resid_prototype = zeros(Float32, 4)), + Float32[0.1, 0.1])) for (fn, u0) in nlfuncs push!(probs_nlls, NonlinearLeastSquaresProblem(fn, u0, 2.0f0)) end @@ -132,18 +141,18 @@ end export NewtonRaphson, PseudoTransient, Klement, Broyden, LimitedMemoryBroyden, DFSane export GaussNewton, LevenbergMarquardt, TrustRegion export NonlinearSolvePolyAlgorithm, - RobustMultiNewton, FastShortcutNonlinearPolyalg, FastShortcutNLLSPolyalg + RobustMultiNewton, FastShortcutNonlinearPolyalg, FastShortcutNLLSPolyalg # Extension Algorithms export LeastSquaresOptimJL, FastLevenbergMarquardtJL, CMINPACK, NLsolveJL, - FixedPointAccelerationJL, SpeedMappingJL, SIAMFANLEquationsJL + FixedPointAccelerationJL, SpeedMappingJL, SIAMFANLEquationsJL # Advanced Algorithms -- Without Bells and Whistles export GeneralizedFirstOrderAlgorithm, ApproximateJacobianSolveAlgorithm, GeneralizedDFSane # Descent Algorithms export NewtonDescent, SteepestDescent, Dogleg, DampedNewtonDescent, - GeodesicAcceleration + GeodesicAcceleration # Globalization ## Line Search Algorithms @@ -153,9 +162,9 @@ export RadiusUpdateSchemes # Export the termination conditions from DiffEqBase export SteadyStateDiffEqTerminationMode, SimpleNonlinearSolveTerminationMode, - NormTerminationMode, RelTerminationMode, RelNormTerminationMode, AbsTerminationMode, - AbsNormTerminationMode, RelSafeTerminationMode, AbsSafeTerminationMode, - RelSafeBestTerminationMode, AbsSafeBestTerminationMode + NormTerminationMode, RelTerminationMode, RelNormTerminationMode, AbsTerminationMode, + AbsNormTerminationMode, RelSafeTerminationMode, AbsSafeTerminationMode, + RelSafeBestTerminationMode, AbsSafeBestTerminationMode # Tracing Functionality export TraceAll, TraceMinimal, TraceWithJacobianConditionNumber diff --git a/src/abstract_types.jl b/src/abstract_types.jl index f0324ed41..1b30f2b9f 100644 --- a/src/abstract_types.jl +++ b/src/abstract_types.jl @@ -16,7 +16,8 @@ squares solver. ### `__internal_init` specification ```julia -__internal_init(prob::NonlinearProblem{uType, iip}, alg::AbstractDescentAlgorithm, J, fu, u; +__internal_init( + prob::NonlinearProblem{uType, iip}, alg::AbstractDescentAlgorithm, J, fu, u; pre_inverted::Val{INV} = Val(false), linsolve_kwargs = (;), abstol = nothing, reltol = nothing, alias_J::Bool = true, shared::Val{N} = Val(1), kwargs...) where {INV, N, uType, iip} --> AbstractDescentCache @@ -232,7 +233,8 @@ Abstract Type for Damping Functions in DampedNewton. ### `__internal_init` specification ```julia -__internal_init(prob::AbstractNonlinearProblem, f::AbstractDampingFunction, initial_damping, +__internal_init( + prob::AbstractNonlinearProblem, f::AbstractDampingFunction, initial_damping, J, fu, u, args...; internal_norm = DEFAULT_NORM, kwargs...) --> AbstractDampingFunctionCache ``` diff --git a/src/algorithms/broyden.jl b/src/algorithms/broyden.jl index 1d063c6c0..bd3b490e4 100644 --- a/src/algorithms/broyden.jl +++ b/src/algorithms/broyden.jl @@ -28,7 +28,8 @@ search. useful for specific problems, but whether it will work may depend strongly on the problem """ -function Broyden(; max_resets = 100, linesearch = NoLineSearch(), reset_tolerance = nothing, +function Broyden(; + max_resets = 100, linesearch = NoLineSearch(), reset_tolerance = nothing, init_jacobian::Val{IJ} = Val(:identity), autodiff = nothing, alpha = nothing, update_rule::Val{UR} = Val(:good_broyden)) where {IJ, UR} if IJ === :identity diff --git a/src/algorithms/dfsane.jl b/src/algorithms/dfsane.jl index 17bdcac55..9122fb6a1 100644 --- a/src/algorithms/dfsane.jl +++ b/src/algorithms/dfsane.jl @@ -19,7 +19,8 @@ For other keyword arguments, see [`RobustNonMonotoneLineSearch`](@ref). function DFSane(; σ_min = 1 // 10^10, σ_max = 1e10, σ_1 = 1, M::Int = 10, γ = 1 // 10^4, τ_min = 1 // 10, τ_max = 1 // 2, n_exp::Int = 2, max_inner_iterations::Int = 100, η_strategy::ETA = (fn_1, n, x_n, f_n) -> fn_1 / n^2) where {ETA} - linesearch = RobustNonMonotoneLineSearch(; gamma = γ, sigma_1 = σ_1, M, tau_min = τ_min, + linesearch = RobustNonMonotoneLineSearch(; + gamma = γ, sigma_1 = σ_1, M, tau_min = τ_min, tau_max = τ_max, n_exp, η_strategy, maxiters = max_inner_iterations) return GeneralizedDFSane{:DFSane}(linesearch, σ_min, σ_max, nothing) end diff --git a/src/algorithms/extension_algs.jl b/src/algorithms/extension_algs.jl index 57b24eab6..eeed0ea5b 100644 --- a/src/algorithms/extension_algs.jl +++ b/src/algorithms/extension_algs.jl @@ -155,19 +155,21 @@ function CMINPACK(; show_trace = missing, tracing = missing, method::Symbol = :a end if show_trace !== missing - Base.depwarn("`show_trace` for CMINPACK has been deprecated and will be removed \ - in v4. Use the `show_trace` keyword argument via the logging API \ - https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ \ - instead.", :CMINPACK) + Base.depwarn( + "`show_trace` for CMINPACK has been deprecated and will be removed \ + in v4. Use the `show_trace` keyword argument via the logging API \ + https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ \ + instead.", :CMINPACK) else show_trace = false end if tracing !== missing - Base.depwarn("`tracing` for CMINPACK has been deprecated and will be removed \ - in v4. Use the `store_trace` keyword argument via the logging API \ - https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ \ - instead.", :CMINPACK) + Base.depwarn( + "`tracing` for CMINPACK has been deprecated and will be removed \ + in v4. Use the `store_trace` keyword argument via the logging API \ + https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ \ + instead.", :CMINPACK) else tracing = false end @@ -243,25 +245,29 @@ function NLsolveJL(; method = :trust_region, autodiff = :central, store_trace = Base.depwarn("`show_trace` for NLsolveJL has been deprecated and will be removed \ in v4. Use the `show_trace` keyword argument via the logging API \ https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ \ - instead.", :NLsolveJL) + instead.", + :NLsolveJL) else show_trace = false end if store_trace !== missing - Base.depwarn("`store_trace` for NLsolveJL has been deprecated and will be removed \ - in v4. Use the `store_trace` keyword argument via the logging API \ - https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ \ - instead.", :NLsolveJL) + Base.depwarn( + "`store_trace` for NLsolveJL has been deprecated and will be removed \ + in v4. Use the `store_trace` keyword argument via the logging API \ + https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ \ + instead.", + :NLsolveJL) else store_trace = false end if extended_trace !== missing - Base.depwarn("`extended_trace` for NLsolveJL has been deprecated and will be \ - removed in v4. Use the `trace_level = TraceAll()` keyword argument \ - via the logging API \ - https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ instead.", + Base.depwarn( + "`extended_trace` for NLsolveJL has been deprecated and will be \ + removed in v4. Use the `trace_level = TraceAll()` keyword argument \ + via the logging API \ + https://docs.sciml.ai/NonlinearSolve/stable/basics/Logging/ instead.", :NLsolveJL) else extended_trace = false @@ -317,7 +323,8 @@ function SpeedMappingJL(; σ_min = 0.0, stabilize::Bool = false, check_obj::Bool if time_limit !== missing Base.depwarn("`time_limit` keyword argument to `SpeedMappingJL` has been \ deprecated and will be removed in v4. Pass `maxtime = ` to \ - `SciMLBase.solve`.", :SpeedMappingJL) + `SciMLBase.solve`.", + :SpeedMappingJL) else time_limit = 1000 end diff --git a/src/algorithms/klement.jl b/src/algorithms/klement.jl index b67ab4f58..8aa94fbd1 100644 --- a/src/algorithms/klement.jl +++ b/src/algorithms/klement.jl @@ -28,8 +28,9 @@ function Klement(; max_resets::Int = 100, linsolve = nothing, alpha = nothing, linesearch = NoLineSearch(), precs = DEFAULT_PRECS, autodiff = nothing, init_jacobian::Val{IJ} = Val(:identity)) where {IJ} if !(linesearch isa AbstractNonlinearSolveLineSearchAlgorithm) - Base.depwarn("Passing in a `LineSearches.jl` algorithm directly is deprecated. \ - Please use `LineSearchesJL` instead.", :Klement) + Base.depwarn( + "Passing in a `LineSearches.jl` algorithm directly is deprecated. \ + Please use `LineSearchesJL` instead.", :Klement) linesearch = LineSearchesJL(; method = linesearch) end diff --git a/src/algorithms/lbroyden.jl b/src/algorithms/lbroyden.jl index ab2b26c50..43b362819 100644 --- a/src/algorithms/lbroyden.jl +++ b/src/algorithms/lbroyden.jl @@ -58,7 +58,8 @@ function __internal_init(prob::AbstractNonlinearProblem, internalnorm) end -function (cache::InitializedApproximateJacobianCache)(alg::BroydenLowRankInitialization, fu, +function (cache::InitializedApproximateJacobianCache)( + alg::BroydenLowRankInitialization, fu, u) α = __initial_alpha(alg.alpha, u, fu, cache.internalnorm) cache.J.idx = 0 diff --git a/src/algorithms/levenberg_marquardt.jl b/src/algorithms/levenberg_marquardt.jl index 0757b6d4c..adb7ee9a4 100644 --- a/src/algorithms/levenberg_marquardt.jl +++ b/src/algorithms/levenberg_marquardt.jl @@ -39,7 +39,8 @@ function LevenbergMarquardt(; concrete_jac = missing, linsolve = nothing, Base.depwarn("The `concrete_jac` keyword argument is deprecated and will be \ removed in v0.4. This kwarg doesn't make sense (and is currently \ ignored) for LM since it needs to materialize the Jacobian to \ - compute the Damping Term", :LevenbergMarquardt) + compute the Damping Term", + :LevenbergMarquardt) end descent = DampedNewtonDescent(; linsolve, precs, initial_damping = damping_initial, @@ -49,7 +50,8 @@ function LevenbergMarquardt(; concrete_jac = missing, linsolve = nothing, descent = GeodesicAcceleration(descent, finite_diff_step_geodesic, α_geodesic) end trustregion = LevenbergMarquardtTrustRegion(b_uphill) - return GeneralizedFirstOrderAlgorithm(; concrete_jac = true, name = :LevenbergMarquardt, + return GeneralizedFirstOrderAlgorithm(; + concrete_jac = true, name = :LevenbergMarquardt, trustregion, descent, jacobian_ad = autodiff) end diff --git a/src/core/approximate_jacobian.jl b/src/core/approximate_jacobian.jl index 54cf5b34a..ffc77cea8 100644 --- a/src/core/approximate_jacobian.jl +++ b/src/core/approximate_jacobian.jl @@ -283,11 +283,13 @@ function __step!(cache::ApproximateJacobianSolveCache{INV, GB, iip}; @static_timeit cache.timer "descent" begin if cache.trustregion_cache !== nothing && hasfield(typeof(cache.trustregion_cache), :trust_region) - δu, descent_success, descent_intermediates = __internal_solve!(cache.descent_cache, + δu, descent_success, descent_intermediates = __internal_solve!( + cache.descent_cache, J, cache.fu, cache.u; new_jacobian, trust_region = cache.trustregion_cache.trust_region) else - δu, descent_success, descent_intermediates = __internal_solve!(cache.descent_cache, + δu, descent_success, descent_intermediates = __internal_solve!( + cache.descent_cache, J, cache.fu, cache.u; new_jacobian) end end diff --git a/src/core/generalized_first_order.jl b/src/core/generalized_first_order.jl index 1ac5ae018..0812e7f05 100644 --- a/src/core/generalized_first_order.jl +++ b/src/core/generalized_first_order.jl @@ -215,11 +215,13 @@ function __step!(cache::GeneralizedFirstOrderAlgorithmCache{iip, GB}; @static_timeit cache.timer "descent" begin if cache.trustregion_cache !== nothing && hasfield(typeof(cache.trustregion_cache), :trust_region) - δu, descent_success, descent_intermediates = __internal_solve!(cache.descent_cache, + δu, descent_success, descent_intermediates = __internal_solve!( + cache.descent_cache, J, cache.fu, cache.u; new_jacobian, trust_region = cache.trustregion_cache.trust_region) else - δu, descent_success, descent_intermediates = __internal_solve!(cache.descent_cache, + δu, descent_success, descent_intermediates = __internal_solve!( + cache.descent_cache, J, cache.fu, cache.u; new_jacobian) end end diff --git a/src/core/spectral_methods.jl b/src/core/spectral_methods.jl index 31ef18343..deab95b3f 100644 --- a/src/core/spectral_methods.jl +++ b/src/core/spectral_methods.jl @@ -147,7 +147,8 @@ function SciMLBase.__init(prob::AbstractNonlinearProblem, alg::GeneralizedDFSane σ_n = T(alg.σ_1) end - return GeneralizedDFSaneCache{isinplace(prob), maxtime !== nothing}(fu, fu_cache, u, + return GeneralizedDFSaneCache{isinplace(prob), maxtime !== nothing}( + fu, fu_cache, u, u_cache, prob.p, du, alg, prob, σ_n, T(alg.σ_min), T(alg.σ_max), linesearch_cache, 0, 0, maxiters, maxtime, timer, 0.0, tc_cache, trace, ReturnCode.Default, false) diff --git a/src/default.jl b/src/default.jl index b83ee3f4e..dafdf7902 100644 --- a/src/default.jl +++ b/src/default.jl @@ -61,8 +61,10 @@ for (probType, pType) in ((:NonlinearProblem, :NLS), (:NonlinearLeastSquaresProb @eval begin function SciMLBase.__init(prob::$probType, alg::$algType{N}, args...; kwargs...) where {N} - return NonlinearSolvePolyAlgorithmCache{isinplace(prob), N}(map(solver -> SciMLBase.__init(prob, - solver, args...; kwargs...), alg.algs), alg, 1) + return NonlinearSolvePolyAlgorithmCache{isinplace(prob), N}( + map(solver -> SciMLBase.__init(prob, + solver, args...; kwargs...), alg.algs), + alg, 1) end end end @@ -71,9 +73,9 @@ end N}) where {iip, N} calls = [ quote - 1 ≤ cache.current ≤ length(cache.caches) || - error("Current choices shouldn't get here!") - end, + 1 ≤ cache.current ≤ length(cache.caches) || + error("Current choices shouldn't get here!") + end ] cache_syms = [gensym("cache") for i in 1:N] diff --git a/src/descent/damped_newton.jl b/src/descent/damped_newton.jl index 5a192a586..77ad95b54 100644 --- a/src/descent/damped_newton.jl +++ b/src/descent/damped_newton.jl @@ -51,7 +51,8 @@ end @internal_caches DampedNewtonDescentCache :lincache :damping_fn_cache -function __internal_init(prob::AbstractNonlinearProblem, alg::DampedNewtonDescent, J, fu, u; +function __internal_init( + prob::AbstractNonlinearProblem, alg::DampedNewtonDescent, J, fu, u; pre_inverted::Val{INV} = False, linsolve_kwargs = (;), abstol = nothing, timer = get_timer_output(), reltol = nothing, alias_J = true, shared::Val{N} = Val(1), kwargs...) where {INV, N} @@ -101,7 +102,8 @@ function __internal_init(prob::AbstractNonlinearProblem, alg::DampedNewtonDescen J_cache = _vcat(J, D) A, b = J_cache, rhs_cache elseif mode === :simple - damping_fn_cache = __internal_init(prob, alg.damping_fn, alg.initial_damping, J, fu, + damping_fn_cache = __internal_init( + prob, alg.damping_fn, alg.initial_damping, J, fu, u, False; kwargs...) J_cache = __maybe_unaliased(J, alias_J) D = damping_fn_cache(nothing) diff --git a/src/descent/geodesic_acceleration.jl b/src/descent/geodesic_acceleration.jl index fcb1ec83e..35764783c 100644 --- a/src/descent/geodesic_acceleration.jl +++ b/src/descent/geodesic_acceleration.jl @@ -31,7 +31,8 @@ for other methods are not theorectically or experimentally verified. end function Base.show(io::IO, alg::GeodesicAcceleration) - print(io, "GeodesicAcceleration(descent = $(alg.descent), finite_diff_step_geodesic = ", + print( + io, "GeodesicAcceleration(descent = $(alg.descent), finite_diff_step_geodesic = ", "$(alg.finite_diff_step_geodesic), α = $(alg.α))") end @@ -101,7 +102,8 @@ function __internal_init(prob::AbstractNonlinearProblem, alg::GeodesicAccelerati internalnorm, T(alg.finite_diff_step_geodesic), Jv, fu_cache, u_cache, false) end -function __internal_solve!(cache::GeodesicAccelerationCache, J, fu, u, idx::Val{N} = Val(1); +function __internal_solve!( + cache::GeodesicAccelerationCache, J, fu, u, idx::Val{N} = Val(1); skip_solve::Bool = false, kwargs...) where {N} a, v, δu = get_acceleration(cache, idx), get_velocity(cache, idx), get_du(cache, idx) skip_solve && return δu, true, (; a, v) diff --git a/src/globalization/line_search.jl b/src/globalization/line_search.jl index 73f88dc4e..6e13043de 100644 --- a/src/globalization/line_search.jl +++ b/src/globalization/line_search.jl @@ -56,7 +56,8 @@ function LineSearchesJL(; method = LineSearches.Static(), autodiff = nothing, α if method isa AbstractNonlinearSolveLineSearchAlgorithm Base.depwarn("Passing a native NonlinearSolve line search algorithm to \ `LineSearchesJL` or `LineSearch` is deprecated. Pass the method \ - directly instead.", :LineSearchesJL) + directly instead.", + :LineSearchesJL) return method end return LineSearchesJL(method, α, autodiff) @@ -141,7 +142,8 @@ function __internal_solve!(cache::LineSearchesJLCache, u, du; kwargs...) ϕ = @closure α -> cache.ϕ(cache.f, cache.p, u, du, α, cache.u_cache, cache.fu_cache) dϕ = @closure α -> cache.dϕ(cache.f, cache.p, u, du, α, cache.u_cache, cache.fu_cache, cache.grad_op) - ϕdϕ = @closure α -> cache.ϕdϕ(cache.f, cache.p, u, du, α, cache.u_cache, cache.fu_cache, + ϕdϕ = @closure α -> cache.ϕdϕ( + cache.f, cache.p, u, du, α, cache.u_cache, cache.fu_cache, cache.grad_op) ϕ₀, dϕ₀ = ϕdϕ(zero(eltype(u))) diff --git a/src/globalization/trust_region.jl b/src/globalization/trust_region.jl index 4e3b2f387..891767a4a 100644 --- a/src/globalization/trust_region.jl +++ b/src/globalization/trust_region.jl @@ -56,7 +56,8 @@ function reinit_cache!(cache::LevenbergMarquardtTrustRegionCache, args...; p = c cache.nf = 0 end -function __internal_init(prob::AbstractNonlinearProblem, alg::LevenbergMarquardtTrustRegion, +function __internal_init( + prob::AbstractNonlinearProblem, alg::LevenbergMarquardtTrustRegion, f::F, fu, u, p, args...; internalnorm::IF = DEFAULT_NORM, kwargs...) where {F, IF} T = promote_type(eltype(u), eltype(fu)) @bb v = copy(u) diff --git a/src/internal/forward_diff.jl b/src/internal/forward_diff.jl index 3e0937b20..4555c99a6 100644 --- a/src/internal/forward_diff.jl +++ b/src/internal/forward_diff.jl @@ -1,14 +1,16 @@ # Not part of public API but helps reduce code duplication import SimpleNonlinearSolve: __nlsolve_ad, - __nlsolve_dual_soln, __nlsolve_∂f_∂p, __nlsolve_∂f_∂u + __nlsolve_dual_soln, __nlsolve_∂f_∂p, __nlsolve_∂f_∂u -function SciMLBase.solve(prob::NonlinearProblem{<:Union{Number, <:AbstractArray}, +function SciMLBase.solve( + prob::NonlinearProblem{<:Union{Number, <:AbstractArray}, iip, <:Union{<:Dual{T, V, P}, <:AbstractArray{<:Dual{T, V, P}}}}, alg::Union{Nothing, AbstractNonlinearAlgorithm}, args...; kwargs...) where {T, V, P, iip} sol, partials = __nlsolve_ad(prob, alg, args...; kwargs...) dual_soln = __nlsolve_dual_soln(sol.u, partials, prob.p) - return SciMLBase.build_solution(prob, alg, dual_soln, sol.resid; sol.retcode, sol.stats, + return SciMLBase.build_solution( + prob, alg, dual_soln, sol.resid; sol.retcode, sol.stats, sol.original) end @@ -34,7 +36,8 @@ function reinit_cache!(cache::NonlinearSolveForwardDiffCache; p = cache.p, return cache end -function SciMLBase.init(prob::NonlinearProblem{<:Union{Number, <:AbstractArray}, +function SciMLBase.init( + prob::NonlinearProblem{<:Union{Number, <:AbstractArray}, iip, <:Union{<:Dual{T, V, P}, <:AbstractArray{<:Dual{T, V, P}}}}, alg::Union{Nothing, AbstractNonlinearAlgorithm}, args...; kwargs...) where {T, V, P, iip} diff --git a/src/internal/helpers.jl b/src/internal/helpers.jl index 8f18686db..4f475214b 100644 --- a/src/internal/helpers.jl +++ b/src/internal/helpers.jl @@ -37,8 +37,10 @@ function ForwardDiff.checktag(::Type{<:ForwardDiff.Tag{<:NonlinearSolveTag, <:T} return true end -function get_concrete_forward_ad(autodiff::Union{ADTypes.AbstractForwardMode, - ADTypes.AbstractFiniteDifferencesMode}, prob, sp::Val{test_sparse} = True, +function get_concrete_forward_ad( + autodiff::Union{ADTypes.AbstractForwardMode, + ADTypes.AbstractFiniteDifferencesMode}, + prob, sp::Val{test_sparse} = True, args...; kwargs...) where {test_sparse} return autodiff end @@ -68,8 +70,10 @@ function get_concrete_forward_ad(autodiff, prob, sp::Val{test_sparse} = True, ar return ad end -function get_concrete_reverse_ad(autodiff::Union{ADTypes.AbstractReverseMode, - ADTypes.AbstractFiniteDifferencesMode}, prob, sp::Val{test_sparse} = True, +function get_concrete_reverse_ad( + autodiff::Union{ADTypes.AbstractReverseMode, + ADTypes.AbstractFiniteDifferencesMode}, + prob, sp::Val{test_sparse} = True, args...; kwargs...) where {test_sparse} return autodiff end @@ -232,13 +236,18 @@ end function __internal_caches(__source__, __module__, cType, internal_cache_names::Tuple) fields = map(name -> :($(__query_stat)(getproperty(cache, $(name)), ST)), internal_cache_names) - callback_caches = map(name -> :($(callback_into_cache!)(cache, + callback_caches = map( + name -> :($(callback_into_cache!)(cache, getproperty(internalcache, $(name)), internalcache, args...)), internal_cache_names) - callbacks_self = map(name -> :($(callback_into_cache!)(internalcache, - getproperty(internalcache, $(name)))), internal_cache_names) - reinit_caches = map(name -> :($(reinit_cache!)(getproperty(cache, $(name)), - args...; kwargs...)), internal_cache_names) + callbacks_self = map( + name -> :($(callback_into_cache!)(internalcache, + getproperty(internalcache, $(name)))), + internal_cache_names) + reinit_caches = map( + name -> :($(reinit_cache!)(getproperty(cache, $(name)), + args...; kwargs...)), + internal_cache_names) return esc(quote function __query_stat(cache::$(cType), ST::Val{stat}) where {stat} val = $(__direct_query_stat)(cache, ST) diff --git a/src/internal/jacobian.jl b/src/internal/jacobian.jl index 4ab451408..6f28d5999 100644 --- a/src/internal/jacobian.jl +++ b/src/internal/jacobian.jl @@ -90,7 +90,8 @@ function JacobianCache(prob, alg, f::F, fu_, u, p; autodiff = nothing, end end - return JacobianCache{iip}(J, f, uf, fu, u, p, jac_cache, alg, 0, autodiff, vjp_autodiff, + return JacobianCache{iip}( + J, f, uf, fu, u, p, jac_cache, alg, 0, autodiff, vjp_autodiff, jvp_autodiff) end diff --git a/src/internal/operators.jl b/src/internal/operators.jl index 6412cfa07..d5e6f4145 100644 --- a/src/internal/operators.jl +++ b/src/internal/operators.jl @@ -104,10 +104,10 @@ function JacobianOperator(prob::AbstractNonlinearProblem, fu, u; jvp_autodiff = if iip # FIXME: Technically we should propagate the tag but ignoring that for now cache1 = Dual{ - typeof(ForwardDiff.Tag(NonlinearSolveTag(), eltype(u))), eltype(u), 1, + typeof(ForwardDiff.Tag(NonlinearSolveTag(), eltype(u))), eltype(u), 1 }.(similar(u), ForwardDiff.Partials.(tuple.(u))) cache2 = Dual{ - typeof(ForwardDiff.Tag(NonlinearSolveTag(), eltype(fu))), eltype(fu), 1, + typeof(ForwardDiff.Tag(NonlinearSolveTag(), eltype(fu))), eltype(fu), 1 }.(similar(fu), ForwardDiff.Partials.(tuple.(fu))) @closure (Jv, v, u, p) -> auto_jacvec!(Jv, uf, u, v, cache1, cache2) else @@ -127,7 +127,8 @@ function JacobianOperator(prob::AbstractNonlinearProblem, fu, u; jvp_autodiff = end end - return JacobianOperator{false, iip, promote_type(eltype(fu), eltype(u))}(jvp_op, vjp_op, + return JacobianOperator{false, iip, promote_type(eltype(fu), eltype(u))}( + jvp_op, vjp_op, u, fu) end diff --git a/test/core/nlls_tests.jl b/test/core/nlls_tests.jl index 1720d77fa..c95fd0de0 100644 --- a/test/core/nlls_tests.jl +++ b/test/core/nlls_tests.jl @@ -1,7 +1,7 @@ @testsetup module CoreNLLSTesting using Reexport @reexport using NonlinearSolve, - LinearSolve, LinearAlgebra, StableRNGs, Random, ForwardDiff, Zygote + LinearSolve, LinearAlgebra, StableRNGs, Random, ForwardDiff, Zygote true_function(x, θ) = @. θ[1] * exp(θ[2] * x) * cos(θ[3] * x + θ[4]) true_function(y, x, θ) = (@. y = θ[1] * exp(θ[2] * x) * cos(θ[3] * x + θ[4])) @@ -41,7 +41,7 @@ append!(solvers, LevenbergMarquardt(; linsolve = LUFactorization()), LevenbergMarquardt(; linsolve = KrylovJL_GMRES()), LevenbergMarquardt(; linsolve = KrylovJL_LSMR()), - nothing, + nothing ]) for radius_update_scheme in [RadiusUpdateSchemes.Simple, RadiusUpdateSchemes.NocedalWright, RadiusUpdateSchemes.NLsolve, RadiusUpdateSchemes.Hei, RadiusUpdateSchemes.Yuan, @@ -54,7 +54,8 @@ end @testitem "General NLLS Solvers" setup=[CoreNLLSTesting] begin prob_oop = NonlinearLeastSquaresProblem{false}(loss_function, θ_init, x) - prob_iip = NonlinearLeastSquaresProblem(NonlinearFunction(loss_function; + prob_iip = NonlinearLeastSquaresProblem( + NonlinearFunction(loss_function; resid_prototype = zero(y_target)), θ_init, x) nlls_problems = [prob_oop, prob_iip] @@ -82,10 +83,16 @@ end end probs = [ - NonlinearLeastSquaresProblem(NonlinearFunction{true}(loss_function; - resid_prototype = zero(y_target), vjp = vjp!), θ_init, x), - NonlinearLeastSquaresProblem(NonlinearFunction{false}(loss_function; - resid_prototype = zero(y_target), vjp = vjp), θ_init, x), + NonlinearLeastSquaresProblem( + NonlinearFunction{true}(loss_function; + resid_prototype = zero(y_target), vjp = vjp!), + θ_init, + x), + NonlinearLeastSquaresProblem( + NonlinearFunction{false}(loss_function; + resid_prototype = zero(y_target), vjp = vjp), + θ_init, + x) ] for prob in probs, solver in solvers diff --git a/test/core/rootfind_tests.jl b/test/core/rootfind_tests.jl index 412d7f1ac..6a9402651 100644 --- a/test/core/rootfind_tests.jl +++ b/test/core/rootfind_tests.jl @@ -1,7 +1,7 @@ @testsetup module CoreRootfindTesting using Reexport @reexport using BenchmarkTools, LinearSolve, NonlinearSolve, StaticArrays, Random, - LinearAlgebra, ForwardDiff, Zygote, Enzyme, SparseDiffTools, DiffEqBase + LinearAlgebra, ForwardDiff, Zygote, Enzyme, SparseDiffTools, DiffEqBase function __autosparseenzyme() @static if Sys.iswindows() @@ -34,7 +34,7 @@ const TERMINATION_CONDITIONS = [ SteadyStateDiffEqTerminationMode(), SimpleNonlinearSolveTerminationMode(), NormTerminationMode(), RelTerminationMode(), RelNormTerminationMode(), AbsTerminationMode(), AbsNormTerminationMode(), RelSafeTerminationMode(), - AbsSafeTerminationMode(), RelSafeBestTerminationMode(), AbsSafeBestTerminationMode(), + AbsSafeTerminationMode(), RelSafeBestTerminationMode(), AbsSafeBestTerminationMode() ] function benchmark_nlsolve_oop(f, u0, p = 2.0; solver, kwargs...) @@ -60,14 +60,15 @@ function nlprob_iterator_interface(f, p_range, ::Val{iip}, solver) where {iip} end export nlprob_iterator_interface, benchmark_nlsolve_oop, benchmark_nlsolve_iip, - TERMINATION_CONDITIONS, _nameof, newton_fails, quadratic_f, quadratic_f!, - __autosparseenzyme + TERMINATION_CONDITIONS, _nameof, newton_fails, quadratic_f, quadratic_f!, + __autosparseenzyme end # --- NewtonRaphson tests --- @testitem "NewtonRaphson" setup=[CoreRootfindTesting] begin - @testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad))" for lsmethod in (Static(), + @testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad))" for lsmethod in ( + Static(), StrongWolfe(), BackTracking(), HagerZhang(), MoreThuente()), ad in (AutoFiniteDiff(), AutoZygote()) @@ -87,7 +88,7 @@ end precs = [ (u0) -> NonlinearSolve.DEFAULT_PRECS, - u0 -> ((args...) -> (Diagonal(rand!(similar(u0))), nothing)), + u0 -> ((args...) -> (Diagonal(rand!(similar(u0))), nothing)) ] @testset "[IIP] u0: $(typeof(u0)) precs: $(_nameof(prec)) linsolve: $(_nameof(linsolve))" for u0 in ([ @@ -112,8 +113,11 @@ end @test nlprob_iterator_interface(quadratic_f, p, Val(false), NewtonRaphson()) ≈ sqrt.(p) @test nlprob_iterator_interface(quadratic_f!, p, Val(true), NewtonRaphson()) ≈ sqrt.(p) - @testset "ADType: $(autodiff) u0: $(_nameof(u0))" for autodiff in (AutoSparseForwardDiff(), - AutoSparseFiniteDiff(), AutoZygote(), AutoSparseZygote(), __autosparseenzyme()), u0 in (1.0, [1.0, 1.0]) + @testset "ADType: $(autodiff) u0: $(_nameof(u0))" for autodiff in ( + AutoSparseForwardDiff(), + AutoSparseFiniteDiff(), AutoZygote(), AutoSparseZygote(), __autosparseenzyme()), + u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, NewtonRaphson(; autodiff)).u .≈ sqrt(2.0)) end @@ -151,7 +155,9 @@ end end @testset "[IIP] u0: $(typeof(u0)) radius_update_scheme: $(radius_update_scheme) linear_solver: $(linsolve)" for u0 in ([ - 1.0, 1.0],), radius_update_scheme in radius_update_schemes, linsolve in linear_solvers + 1.0, 1.0],), radius_update_scheme in radius_update_schemes, + linsolve in linear_solvers + abstol = ifelse(linsolve isa KrylovJL, 1e-6, 1e-9) solver = TrustRegion(; radius_update_scheme, linsolve) sol = benchmark_nlsolve_iip(quadratic_f!, u0; solver, abstol) @@ -168,8 +174,10 @@ end @test nlprob_iterator_interface(quadratic_f, p, Val(false), TrustRegion()) ≈ sqrt.(p) @test nlprob_iterator_interface(quadratic_f!, p, Val(true), TrustRegion()) ≈ sqrt.(p) - @testset "ADType: $(autodiff) u0: $(_nameof(u0)) radius_update_scheme: $(radius_update_scheme)" for autodiff in (AutoSparseForwardDiff(), - AutoSparseFiniteDiff(), AutoZygote(), AutoSparseZygote(), __autosparseenzyme()), u0 in (1.0, [1.0, 1.0]), + @testset "ADType: $(autodiff) u0: $(_nameof(u0)) radius_update_scheme: $(radius_update_scheme)" for autodiff in ( + AutoSparseForwardDiff(), + AutoSparseFiniteDiff(), AutoZygote(), AutoSparseZygote(), __autosparseenzyme()), + u0 in (1.0, [1.0, 1.0]), radius_update_scheme in radius_update_schemes probN = NonlinearProblem(quadratic_f, u0, 2.0) @@ -262,8 +270,11 @@ end @test (@ballocated solve!($cache)) ≤ 64 end - @testset "ADType: $(autodiff) u0: $(_nameof(u0))" for autodiff in (AutoSparseForwardDiff(), - AutoSparseFiniteDiff(), AutoZygote(), AutoSparseZygote(), __autosparseenzyme()), u0 in (1.0, [1.0, 1.0]) + @testset "ADType: $(autodiff) u0: $(_nameof(u0))" for autodiff in ( + AutoSparseForwardDiff(), + AutoSparseFiniteDiff(), AutoZygote(), AutoSparseZygote(), __autosparseenzyme()), + u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, LevenbergMarquardt(; autodiff); abstol = 1e-9, reltol = 1e-9).u .≈ sqrt(2.0)) @@ -371,7 +382,7 @@ end η_strategy = [ (f_1, k, x, F) -> f_1 / k^2, (f_1, k, x, F) -> f_1 / k^3, - (f_1, k, x, F) -> f_1 / k^4, + (f_1, k, x, F) -> f_1 / k^4 ] list_of_options = zip(σ_min, σ_max, σ_1, M, γ, τ_min, τ_max, nexp, @@ -442,8 +453,11 @@ end @test nlprob_iterator_interface(quadratic_f!, p, Val(true), PseudoTransient(; alpha_initial = 10.0)) ≈ sqrt.(p) - @testset "ADType: $(autodiff) u0: $(_nameof(u0))" for autodiff in (AutoSparseForwardDiff(), - AutoSparseFiniteDiff(), AutoZygote(), AutoSparseZygote(), __autosparseenzyme()), u0 in (1.0, [1.0, 1.0]) + @testset "ADType: $(autodiff) u0: $(_nameof(u0))" for autodiff in ( + AutoSparseForwardDiff(), + AutoSparseFiniteDiff(), AutoZygote(), AutoSparseZygote(), __autosparseenzyme()), + u0 in (1.0, [1.0, 1.0]) + probN = NonlinearProblem(quadratic_f, u0, 2.0) @test all(solve(probN, PseudoTransient(; alpha_initial = 10.0, autodiff)).u .≈ sqrt(2.0)) @@ -461,7 +475,8 @@ end # --- Broyden tests --- @testitem "Broyden" setup=[CoreRootfindTesting] begin - @testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad)) Init Jacobian: $(init_jacobian) Update Rule: $(update_rule)" for lsmethod in (Static(), + @testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad)) Init Jacobian: $(init_jacobian) Update Rule: $(update_rule)" for lsmethod in ( + Static(), StrongWolfe(), BackTracking(), HagerZhang(), MoreThuente(), LiFukushimaLineSearch()), ad in (AutoFiniteDiff(), AutoZygote()), @@ -511,7 +526,8 @@ end # --- Klement tests --- @testitem "Klement" setup=[CoreRootfindTesting] begin - @testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad)) Init Jacobian: $(init_jacobian)" for lsmethod in (Static(), + @testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad)) Init Jacobian: $(init_jacobian)" for lsmethod in ( + Static(), StrongWolfe(), BackTracking(), HagerZhang(), MoreThuente()), ad in (AutoFiniteDiff(), AutoZygote()), init_jacobian in (Val(:identity), Val(:true_jacobian), Val(:true_jacobian_diagonal)) @@ -560,7 +576,8 @@ end # --- LimitedMemoryBroyden tests --- @testitem "LimitedMemoryBroyden" setup=[CoreRootfindTesting] begin - @testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad))" for lsmethod in (Static(), + @testset "LineSearch: $(_nameof(lsmethod)) LineSearch AD: $(_nameof(ad))" for lsmethod in ( + Static(), StrongWolfe(), BackTracking(), HagerZhang(), MoreThuente(), LiFukushimaLineSearch()), ad in (AutoFiniteDiff(), AutoZygote()) diff --git a/test/wrappers/nlls_tests.jl b/test/wrappers/nlls_tests.jl index fbcf3cf84..f578b192c 100644 --- a/test/wrappers/nlls_tests.jl +++ b/test/wrappers/nlls_tests.jl @@ -30,12 +30,14 @@ end @testitem "LeastSquaresOptim.jl" setup=[WrapperNLLSSetup] begin prob_oop = NonlinearLeastSquaresProblem{false}(loss_function, θ_init, x) - prob_iip = NonlinearLeastSquaresProblem(NonlinearFunction(loss_function; + prob_iip = NonlinearLeastSquaresProblem( + NonlinearFunction(loss_function; resid_prototype = zero(y_target)), θ_init, x) nlls_problems = [prob_oop, prob_iip] - solvers = [LeastSquaresOptimJL(alg; autodiff) for alg in (:lm, :dogleg), + solvers = [LeastSquaresOptimJL(alg; autodiff) + for alg in (:lm, :dogleg), autodiff in (nothing, AutoForwardDiff(), AutoFiniteDiff(), :central, :forward)] for prob in nlls_problems, solver in solvers @@ -56,12 +58,18 @@ end jac(θ, p) = ForwardDiff.jacobian(θ -> loss_function(θ, p), θ) probs = [ - NonlinearLeastSquaresProblem(NonlinearFunction{true}(loss_function; - resid_prototype = zero(y_target), jac = jac!), θ_init, x), - NonlinearLeastSquaresProblem(NonlinearFunction{false}(loss_function; - resid_prototype = zero(y_target), jac = jac), θ_init, x), + NonlinearLeastSquaresProblem( + NonlinearFunction{true}(loss_function; + resid_prototype = zero(y_target), jac = jac!), + θ_init, + x), + NonlinearLeastSquaresProblem( + NonlinearFunction{false}(loss_function; + resid_prototype = zero(y_target), jac = jac), + θ_init, + x), NonlinearLeastSquaresProblem(NonlinearFunction{false}(loss_function; jac), - θ_init, x), + θ_init, x) ] solvers = Any[FastLevenbergMarquardtJL(linsolve) for linsolve in (:cholesky, :qr)] @@ -75,11 +83,15 @@ end @testitem "FastLevenbergMarquardt.jl + CMINPACK: Jacobian Not Provided" setup=[ WrapperNLLSSetup] begin probs = [ - NonlinearLeastSquaresProblem(NonlinearFunction{true}(loss_function; - resid_prototype = zero(y_target)), θ_init, x), - NonlinearLeastSquaresProblem(NonlinearFunction{false}(loss_function; - resid_prototype = zero(y_target)), θ_init, x), - NonlinearLeastSquaresProblem(NonlinearFunction{false}(loss_function), θ_init, x), + NonlinearLeastSquaresProblem( + NonlinearFunction{true}(loss_function; + resid_prototype = zero(y_target)), + θ_init, x), + NonlinearLeastSquaresProblem( + NonlinearFunction{false}(loss_function; + resid_prototype = zero(y_target)), + θ_init, x), + NonlinearLeastSquaresProblem(NonlinearFunction{false}(loss_function), θ_init, x) ] solvers = vec(Any[FastLevenbergMarquardtJL(linsolve; autodiff)