Skip to content

Commit

Permalink
Add NonlinearLeastSquaresProblem
Browse files Browse the repository at this point in the history
  • Loading branch information
avik-pal committed Sep 21, 2023
1 parent 434e752 commit 1bda590
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 4 deletions.
6 changes: 3 additions & 3 deletions src/SciMLBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -759,9 +759,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
Expand Down
81 changes: 80 additions & 1 deletion src/problems/basic_problems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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{

Check warning on line 366 in src/problems/basic_problems.jl

View check run for this annotation

Codecov / codecov/patch

src/problems/basic_problems.jl#L366

Added line #L366 was not covered by tests
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)

Check warning on line 369 in src/problems/basic_problems.jl

View check run for this annotation

Codecov / codecov/patch

src/problems/basic_problems.jl#L368-L369

Added lines #L368 - L369 were not covered by tests
end

function NonlinearLeastSquaresProblem{iip}(f, u0, p = NullParameters()) where {iip}
return NonlinearLeastSquaresProblem{iip}(NonlinearFunction{iip}(f), u0, p)

Check warning on line 373 in src/problems/basic_problems.jl

View check run for this annotation

Codecov / codecov/patch

src/problems/basic_problems.jl#L372-L373

Added lines #L372 - L373 were not covered by tests
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,

Check warning on line 385 in src/problems/basic_problems.jl

View check run for this annotation

Codecov / codecov/patch

src/problems/basic_problems.jl#L385

Added line #L385 was not covered by tests
p = NullParameters(); kwargs...)
return NonlinearLeastSquaresProblem{isinplace(f)}(f, u0, p; kwargs...)

Check warning on line 387 in src/problems/basic_problems.jl

View check run for this annotation

Codecov / codecov/patch

src/problems/basic_problems.jl#L387

Added line #L387 was not covered by tests
end

function NonlinearLeastSquaresProblem(f, u0, p = NullParameters(); kwargs...)
return NonlinearLeastSquaresProblem(NonlinearFunction(f), u0, p; kwargs...)

Check warning on line 391 in src/problems/basic_problems.jl

View check run for this annotation

Codecov / codecov/patch

src/problems/basic_problems.jl#L390-L391

Added lines #L390 - L391 were not covered by tests
end

@doc doc"""
Defines an integral problem.
Expand Down Expand Up @@ -434,7 +513,7 @@ struct SampledIntegralProblem{Y, X, K} <: AbstractIntegralProblem{false}
@add_kwonly function SampledIntegralProblem(y::AbstractArray, x::AbstractVector;
dim = ndims(y),
kwargs...)
@assert dim <= ndims(y) "The integration dimension `dim` is larger than the number of dimensions of the integrand `y`"
@assert dim<=ndims(y) "The integration dimension `dim` is larger than the number of dimensions of the integrand `y`"

Check warning on line 516 in src/problems/basic_problems.jl

View check run for this annotation

Codecov / codecov/patch

src/problems/basic_problems.jl#L516

Added line #L516 was not covered by tests
@assert length(x)==size(y, dim) "The integrand `y` must have the same length as the sampling points `x` along the integrated dimension."
@assert axes(x, 1)==axes(y, dim) "The integrand `y` must obey the same indexing as the sampling points `x` along the integrated dimension."
new{typeof(y), typeof(x), typeof(kwargs)}(y, x, dim, kwargs)
Expand Down
32 changes: 32 additions & 0 deletions src/remake.jl
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,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,

Check warning on line 256 in src/remake.jl

View check run for this annotation

Codecov / codecov/patch

src/remake.jl#L256

Added line #L256 was not covered by tests
kwargs = missing, _kwargs...)
if p === missing && u0 === missing
p, u0 = prob.p, prob.u0

Check warning on line 259 in src/remake.jl

View check run for this annotation

Codecov / codecov/patch

src/remake.jl#L258-L259

Added lines #L258 - L259 were not covered by tests
else # at least one of them has a value
if p === missing
p = prob.p

Check warning on line 262 in src/remake.jl

View check run for this annotation

Codecov / codecov/patch

src/remake.jl#L261-L262

Added lines #L261 - L262 were not covered by tests
end
if u0 === missing
u0 = prob.u0

Check warning on line 265 in src/remake.jl

View check run for this annotation

Codecov / codecov/patch

src/remake.jl#L264-L265

Added lines #L264 - L265 were not covered by tests
end
end

if f === missing
f = prob.f

Check warning on line 270 in src/remake.jl

View check run for this annotation

Codecov / codecov/patch

src/remake.jl#L269-L270

Added lines #L269 - L270 were not covered by tests
end

if kwargs === missing
return NonlinearLeastSquaresProblem{isinplace(prob)}(; f, u0, p, prob.kwargs...,

Check warning on line 274 in src/remake.jl

View check run for this annotation

Codecov / codecov/patch

src/remake.jl#L273-L274

Added lines #L273 - L274 were not covered by tests
_kwargs...)
else
return NonlinearLeastSquaresProblem{isinplace(prob)}(; f, u0, p, kwargs...)

Check warning on line 277 in src/remake.jl

View check run for this annotation

Codecov / codecov/patch

src/remake.jl#L277

Added line #L277 was not covered by tests
end
end

# overloaded in MTK to intercept symbolic remake
function process_p_u0_symbolic(prob, p, u0)
if typeof(prob) <: Union{AbstractDEProblem, OptimizationProblem, NonlinearProblem}
Expand Down

0 comments on commit 1bda590

Please sign in to comment.