From 790b559508c96a852ddf63e085e1644d7e7ee192 Mon Sep 17 00:00:00 2001 From: Avik Pal Date: Wed, 20 Sep 2023 20:50:33 -0400 Subject: [PATCH 1/2] Add NonlinearLeastSquaresProblem --- src/SciMLBase.jl | 6 +-- src/problems/basic_problems.jl | 79 ++++++++++++++++++++++++++++++++++ src/remake.jl | 32 ++++++++++++++ 3 files changed, 114 insertions(+), 3 deletions(-) diff --git a/src/SciMLBase.jl b/src/SciMLBase.jl index d206ca07d..8da9ff267 100644 --- a/src/SciMLBase.jl +++ b/src/SciMLBase.jl @@ -769,9 +769,9 @@ export isinplace export solve, solve!, init, discretize, symbolic_discretize -export LinearProblem, - NonlinearProblem, IntervalNonlinearProblem, - IntegralProblem, SampledIntegralProblem, OptimizationProblem +export LinearProblem, NonlinearProblem, IntervalNonlinearProblem, + IntegralProblem, SampledIntegralProblem, OptimizationProblem, + NonlinearLeastSquaresProblem export DiscreteProblem, ImplicitDiscreteProblem export SteadyStateProblem, SteadyStateSolution diff --git a/src/problems/basic_problems.jl b/src/problems/basic_problems.jl index 1207fe79b..3c2430c58 100644 --- a/src/problems/basic_problems.jl +++ b/src/problems/basic_problems.jl @@ -312,6 +312,85 @@ function NonlinearProblem(prob::AbstractODEProblem) NonlinearProblem{isinplace(prob)}(prob.f, prob.u0, prob.p) end +@doc doc""" +Defines a nonlinear least squares problem. + +## Mathematical Specification of a Nonlinear Least Squares Problem + +To define a Nonlinear Problem, you simply need to give the function ``f`` which defines the +nonlinear system: + +```math +\underset{x}{\min} \| f(x, p) \| +``` + +and an initial guess ``u_0`` for the minimization problem. ``f`` should be specified as +``f(u, p)`` (or in-place as ``f(du, u, p)``), and ``u_0``` should be an AbstractArray (or +number) whose geometry matches the desired geometry of ``u``. Note that we are not limited +to numbers or vectors for ``u_0``; one is allowed to provide ``u_0`` as arbitrary +matrices / higher-dimension tensors as well. + +## Problem Type + +### Constructors + +```julia +NonlinearLeastSquaresProblem(f::NonlinearFunction, u0, p=NullParameters(); kwargs...) +NonlinearLeastSquaresProblem{isinplace}(f, u0, p=NullParameters(); kwargs...) +``` + +`isinplace` optionally sets whether the function is in-place or not. This is +determined automatically, but not inferred. + +Parameters are optional, and if not given, then a `NullParameters()` singleton +will be used, which will throw nice errors if you try to index non-existent +parameters. + +For specifying Jacobians and mass matrices, see the +[NonlinearFunctions](@ref nonlinearfunctions) page. + +### Fields + +* `f`: The function in the problem. +* `u0`: The initial guess for the solution. +* `p`: The parameters for the problem. Defaults to `NullParameters`. +* `kwargs`: The keyword arguments passed on to the solvers. +""" +struct NonlinearLeastSquaresProblem{uType, isinplace, P, F, K} <: + AbstractNonlinearProblem{uType, isinplace} + f::F + u0::uType + p::P + kwargs::K + + @add_kwonly function NonlinearLeastSquaresProblem{iip}(f::AbstractNonlinearFunction{ + iip}, u0, p = NullParameters(); kwargs...) where {iip} + warn_paramtype(p) + return new{typeof(u0), iip, typeof(p), typeof(f), typeof(kwargs)}(f, u0, p, kwargs) + end + + function NonlinearLeastSquaresProblem{iip}(f, u0, p = NullParameters()) where {iip} + return NonlinearLeastSquaresProblem{iip}(NonlinearFunction{iip}(f), u0, p) + end +end + +TruncatedStacktraces.@truncate_stacktrace NonlinearLeastSquaresProblem 2 1 + +""" +$(SIGNATURES) + +Define a nonlinear least squares problem using an instance of +[`AbstractNonlinearFunction`](@ref AbstractNonlinearFunction). +""" +function NonlinearLeastSquaresProblem(f::AbstractNonlinearFunction, u0, + p = NullParameters(); kwargs...) + return NonlinearLeastSquaresProblem{isinplace(f)}(f, u0, p; kwargs...) +end + +function NonlinearLeastSquaresProblem(f, u0, p = NullParameters(); kwargs...) + return NonlinearLeastSquaresProblem(NonlinearFunction(f), u0, p; kwargs...) +end + @doc doc""" Defines an integral problem. diff --git a/src/remake.jl b/src/remake.jl index 8fe0feb1f..083f0fda6 100644 --- a/src/remake.jl +++ b/src/remake.jl @@ -369,6 +369,38 @@ function remake(prob::NonlinearProblem; end end + +""" + remake(prob::NonlinearLeastSquaresProblem; f = missing, u0 = missing, p = missing, + kwargs = missing, _kwargs...) + +Remake the given `NonlinearLeastSquaresProblem`. +""" +function remake(prob::NonlinearLeastSquaresProblem; f = missing, u0 = missing, p = missing, + kwargs = missing, _kwargs...) + if p === missing && u0 === missing + p, u0 = prob.p, prob.u0 + else # at least one of them has a value + if p === missing + p = prob.p + end + if u0 === missing + u0 = prob.u0 + end + end + + if f === missing + f = prob.f + end + + if kwargs === missing + return NonlinearLeastSquaresProblem{isinplace(prob)}(; f, u0, p, prob.kwargs..., + _kwargs...) + else + return NonlinearLeastSquaresProblem{isinplace(prob)}(; f, u0, p, kwargs...) + end +end + # overloaded in MTK to intercept symbolic remake function process_p_u0_symbolic(prob, p, u0) if typeof(prob) <: Union{AbstractDEProblem, OptimizationProblem, NonlinearProblem} From 5ddf69ab2cc37ca1c469bd87753b2de646339f76 Mon Sep 17 00:00:00 2001 From: Avik Pal Date: Sun, 8 Oct 2023 15:09:57 -0400 Subject: [PATCH 2/2] Update Project --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 7c190f21b..f2cf68910 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SciMLBase" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" authors = ["Chris Rackauckas and contributors"] -version = "2.3.1" +version = "2.4.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"