Bounded Solvers
Use solve(prob) for a problem with lb or ub. The bounded default is SobolMultistart wrapping FastShortcutBoundedPolyalg: each start works in the original coordinates, trying BoundedTrustRegion() and then BoundedGaussNewton() with projected backtracking if needed, and a stalled local solve triggers deterministic restarts. Passing FastShortcutBoundedPolyalg() explicitly selects the purely local sequence without restarts. The bound-constraints tutorial shows how to construct root and least-squares problems.
Choosing a solver
Start with the default when the problem's numerical behavior is unknown. For repeated solves of the same model, benchmark individual methods after checking residuals and stationarity: in the bounded solver benchmark in SciMLBenchmarks.jl, BoundedTrustRegion() has low overhead, while projected BoundedGaussNewton() also handles its difficult underdetermined case. For operator-based problems, also benchmark projected BoundedGaussNewton() explicitly: it was faster on the diffusion operator cases in that benchmark. Reuse a cache with init/reinit!/solve!; retain_best = true can reuse a successful fallback stage across parameter sweeps, with periodic retries of the earlier stages.
When a postcondition corrector is supplied, the default restricts the sequence to BoundedTrustRegion, the stage that supports iterate correction.
The native methods share the Jacobian, linear-solver, and bound-handling machinery. Their step models and globalization strategies differ:
| Method | Step and globalization |
|---|---|
BoundedTrustRegion | Projected dogleg step with a spherical trust region |
TrustRegionReflective | Coleman–Li distance-to-bound scaling and reflected trial steps |
BoundedLevenbergMarquardt | Box-constrained damped least-squares model with a feasible line search |
Dogbox | Dogleg step inside a rectangular trust region intersected with the bounds |
BoundedGaussNewton | Active-set Gauss–Newton with projected line search, trust region, or their combination |
Feasibility and convergence
Supply a real floating-point state. A feasible initial guess is recommended; the automatic default and explicit polyalgorithms containing only native bounded stages project an out-of-bounds guess onto the box. Individual native algorithms require a feasible initial guess. This projection also applies to auxiliary initialization problems, after their initialization callbacks update the guess. Exact-bound initial values and fixed coordinates are supported. TrustRegionReflective moves nonfixed exact-bound initial values into the strict interior; the other native methods permit exact-bound iterates. Bounds are local constraints, not a global-search strategy.
For a NonlinearProblem, success still requires a small residual. For a NonlinearLeastSquaresProblem, projected-gradient stationarity can establish success even when the residual is nonzero. A stationary constrained least-squares point is not necessarily a root or a global minimum.
Restarts and restoration
A local bounded method can converge to a constrained stationary point on an active bound that is not a root of the system. The default SobolMultistart wrapper reruns a bounded algorithm from prob.u0 and a deterministic Sobol sequence of restarts, keeping the best feasible result. It also performs a restoration probe: when a start stalls on an active bound, one unbounded solve from the stalled iterate checks whether a nearby root lies inside the original box. A restarted start can converge to a different root than the u0 basin; select FastShortcutBoundedPolyalg() to stay in the local sequence.
using NonlinearSolve, SciMLBase
f(u, p) = [cos(u[2]) + sin(u[1]) - 0.5, sin(u[2]) + cos(u[1]) - 0.3]
prob = NonlinearProblem(
f, [0.3, 1.0], nothing; lb = [-100.0, 0.0], ub = [100.0, 10.0]
)
@assert !SciMLBase.successful_retcode(solve(prob, FastShortcutBoundedPolyalg()))
sol = solve(prob)
@assert SciMLBase.successful_retcode(sol)
sol.u2-element Vector{Float64}:
-0.24457517905731213
5.548652801868546SobolMultistart never reports a stalled sub-solve as a success: when no start reaches a root the returned retcode is ReturnCode.Stalled.
using NonlinearSolve, SciMLBase
prob = NonlinearLeastSquaresProblem(
(u, p) -> [u[1] - 2.0, 1.0], [0.0]; lb = -1.0, ub = 1.0
)
sol = solve(prob)
@assert SciMLBase.successful_retcode(sol)
@assert sol.u ≈ [1.0]
sol.resid2-element Vector{Float64}:
-1.0
1.0Sparse and operator Jacobians
A sparse jac_prototype remains sparse. A Krylov linear solver uses Jacobian-vector and transpose-Jacobian-vector operators unless concrete_jac = true is requested. The native methods reuse the selected linear solver and support jvp_autodiff, vjp_autodiff, analytic jvp/vjp callbacks, and preconditioning.
using LinearSolve, SparseArrays
f! = (r, u, p) -> (r .= u .- p)
nf = NonlinearFunction(f!; jac_prototype = spdiagm(0 => ones(20)))
prob_sparse = NonlinearLeastSquaresProblem(
nf, fill(0.5, 20), collect(range(-0.5, 1.5; length = 20)); lb = 0.0, ub = 1.0
)
sol_sparse = solve(prob_sparse, BoundedGaussNewton())
sol_operator = solve(prob_sparse, BoundedGaussNewton(linsolve = KrylovJL_LSMR()))
@assert SciMLBase.successful_retcode(sol_sparse)
@assert SciMLBase.successful_retcode(sol_operator)
@assert maximum(abs, sol_sparse.u - sol_operator.u) < 1e-6┌ Warning: `SparseMatrixColorings` must be explicitly imported for sparse automatic differentiation to work. Proceeding with Dense Automatic Differentiation.
└ @ NonlinearSolveBase ~/_work/NonlinearSolve.jl/NonlinearSolve.jl/lib/NonlinearSolveBase/src/jacobian.jl:366Choose a linear solver that supports rank deficiency or underdetermined systems when needed. KrylovJL_LSMR() solves the rectangular least-squares models; linear solvers requiring square systems use normal equations. A successful minimum-norm linear solve does not by itself ensure fast nonlinear convergence.
For a scalar state with an array residual, or an array state with a scalar residual, select BoundedGaussNewton() explicitly. The generalized dogleg stage used by the default currently requires matching scalar/array categories.
Analytic Jacobians and AD backends follow the usual solver interface. Native finite differences stay inside finite bounds and do not perturb fixed coordinates.
Explicit algorithms without native bound support
An explicitly selected algorithm such as NewtonRaphson() or LevenbergMarquardt() uses an automatic variable transformation. Two-sided bounds use a logistic map; one-sided bounds use an exponential map. This is useful when a particular unbounded algorithm is required, but the transformed derivative can become small near an active bound. Native methods operate directly on the box and can reach its boundary.
Solver API
NonlinearSolveFirstOrder.FastShortcutBoundedPolyalg — Function
FastShortcutBoundedPolyalg(; concrete_jac = nothing, linsolve = nothing,
autodiff = nothing, jvp_autodiff = nothing, vjp_autodiff = nothing, gtol = nothing, must_support_postcondition = false)A polyalgorithm for real, box-constrained nonlinear systems and nonlinear least squares. It tries BoundedTrustRegion, followed by BoundedGaussNewton with projected backtracking if the first method fails. Each stage starts from the supplied initial guess and operates in the original bounded coordinates.
This is the default for NonlinearProblem and NonlinearLeastSquaresProblem with lb or ub. An out-of-bounds initial guess is projected onto the box, including when this polyalgorithm is selected explicitly. Least-squares problems may succeed at a constrained stationary point with nonzero residual; nonlinear systems must satisfy the residual tolerance. These are local methods and do not guarantee a global minimum.
concrete_jac, linsolve, and the differentiation backends are forwarded to both stages. Sparse Jacobian prototypes and matrix-free Krylov solvers use the usual Jacobian and linear-solver caches. gtol sets the projected-gradient tolerance; its default is sqrt(eps(T)) for least squares. For nonlinear systems, the trust-region stage disables this check by default and Gauss–Newton uses zero; detecting stationarity without a converged residual returns ReturnCode.Stalled.
Set must_support_postcondition = true to restrict the sequence to BoundedTrustRegion, which supports iterate correctors. Default algorithm selection sets this when a postcondition is supplied to the solve; pass the corrector itself to solve or init.
See the bounded solver recommendations for alternatives. The stage order may change as the benchmark coverage grows.
NonlinearSolveFirstOrder.SobolMultistart — Type
SobolMultistart(alg = FastShortcutBoundedPolyalg(); nstarts::Int = 16,
search_scale = 10, early_exit::Bool = true, restoration::Bool = true,
restoration_alg = nothing)A deterministic multistart wrapper for NonlinearProblem and NonlinearLeastSquaresProblem, intended for box-constrained solves where a local method can converge to a constrained stationary point on an active bound that is not a root of the system. This wrapper is the default algorithm for problems with lb or ub; select alg directly for a purely local solve without restarts.
The wrapper runs alg from nstarts deterministic start points and returns the best result. The first start is always prob.u0, so the wrapper is never worse than a direct local solve; the remaining starts are points of a Sobol low-discrepancy sequence over the search region. Every start goes through the ordinary solve/init path, so linsolve, concrete_jac, sparse jac_prototype, JVP/VJP callbacks, AD backends, and keyword arguments such as abstol, reltol, and maxiters apply to each sub-solve exactly as they would to a direct solve(prob, alg; kwargs...) call.
Arguments
alg: the local algorithm run from each start. Defaults toFastShortcutBoundedPolyalg.
Keyword Arguments
nstarts: the number of start points, includingprob.u0. Defaults to 16.search_scale: components with an infinite bound are sampled over a window of half-widthsearch_scale * max(1, |u0_i|)centered onu0_i; components with a finite bound use the bound itself as the edge of the sampling region. Defaults to 10.early_exit: return immediately once a sub-solve reports a successful retcode. Withearly_exit = falseevery start runs and the feasible solution with the lowest residual norm is returned. Defaults totrue.restoration: when a start stalls on an active bound, run one unbounded restoration probe from the stalled iterate with the nonfixed bounds relaxed. A probe that converges inside the original box returns that root as the start's result; a root outside the box confirms the boundary point is a genuine constrained solution and the stalled result is kept. Defaults totrue.restoration_alg: the algorithm used for restoration probes. Defaults toalg.
The returned retcode is the sub-solve's own retcode on success and ReturnCode.Stalled when no start finds a solution; a failure is never reported as a success. The winning sub-solve is stored in the solution's original field. The wrapper also applies to problems without bounds, where all starts are drawn from the search_scale windows around u0.
NonlinearSolveFirstOrder.BoundedTrustRegion — Function
BoundedTrustRegion(;
concrete_jac = nothing, linsolve = nothing,
max_trust_radius::Real = 0 // 1, initial_trust_radius::Real = 0 // 1,
step_threshold::Real = 1 // 10000, shrink_threshold::Real = 1 // 4,
expand_threshold::Real = 3 // 4, shrink_factor::Real = 1 // 4,
expand_factor::Real = 2 // 1, max_shrink_times::Int = 32,
gtol = nothing, vjp_autodiff = nothing, autodiff = nothing,
jvp_autodiff = nothing,
)A bound-constrained trust-region method for nonlinear systems and nonlinear least-squares problems. Bounds are handled directly in the original coordinates. The method compares a projected dogleg step with a feasible projected-Cauchy step and selects the step with the larger predicted reduction.
Unlike a coordinate transformation, this method permits iterates exactly on a bound and does not multiply the problem Jacobian by a transformation derivative that vanishes there. The initial guess must satisfy the problem bounds.
For a NonlinearLeastSquaresProblem, convergence is also detected when the infinity norm of the projected gradient is below gtol. This defaults to sqrt(eps(T)), where T is the working element type. Projected-gradient termination is disabled by default for a NonlinearProblem, because a constrained stationary point need not be a root. Setting gtol explicitly enables the check and reports such a point as ReturnCode.Stalled unless the residual has already converged.
Keyword Arguments
max_trust_radius: the maximum trust-region radius. A value of zero selectsInf.initial_trust_radius: the initial radius. A value of zero selectsmax(norm(u0), one(T)).step_threshold: minimum actual-to-predicted reduction ratio for accepting a step.shrink_threshold,expand_threshold: reduction-ratio thresholds for changing the radius.shrink_factor,expand_factor: factors used to change the radius.gtol: projected-gradient tolerance for constrained stationarity.
NonlinearSolveFirstOrder.TrustRegionReflective — Function
TrustRegionReflective(; autodiff = nothing, jvp_autodiff = nothing, vjp_autodiff = nothing,
linsolve = nothing, concrete_jac = nothing, gtol = nothing,
initial_trust_radius = 1, max_trust_radius = Inf)Coleman–Li interior reflective trust-region method for box-constrained nonlinear least squares and nonlinear equations. The quadratic model uses distance-to-bound scaling and the Coleman–Li diagonal correction. Each iteration compares a strictly feasible scaled trust-region step, a reflected direction, and a scaled gradient step.
Exact-bound initial guesses are moved into the strict interior; fixed variables remain fixed. For least squares, gtol bounds the infinity norm of u - clamp(u - J'F, lb, ub) and defaults to sqrt(eps(eltype(u0))). For nonlinear equations, stationarity with a nonzero residual returns ReturnCode.Stalled, never success; the default gtol is zero to avoid stopping near a root before residual convergence. abstol controls the default residual norm termination; other termination modes can be selected with termination_condition. Initial guesses must be feasible.
linsolve, concrete_jac, autodiff, jvp_autodiff, and vjp_autodiff use the same Jacobian and LinearSolve caches as GaussNewton. A sparse jac_prototype stays sparse; choosing a Krylov solver constructs a Jacobian operator unless a concrete Jacobian is requested. Analytic jvp and vjp callbacks are supported. Square-only linear solvers use normal equations; rectangular least-squares solvers operate on the scaled, diagonally augmented system. Rank-deficient and underdetermined problems require a suitable linear solver, such as SVDFactorization() or KrylovJL_LSMR().
The trust-region subproblem uses the subspace spanned by the scaled gradient and the Gauss–Newton step. Only that one- or two-dimensional model is diagonalized. AutoFiniteDiff uses bound-aware stencils for both concrete Jacobians and operator products; fixed coordinates are never perturbed. linsolve_kwargs passed to solve or init are forwarded to the linear-solver cache, including tolerances and preconditioners.
The positive initial_trust_radius is measured in scaled coordinates and is capped by max_trust_radius. Only real floating-point states and real residuals are supported.
Based on Coleman and Li, An Interior Trust Region Approach for Nonlinear Minimization Subject to Bounds, SIAM J. Optimization 6 (1996), 418–445, doi:10.1137/0806023.
NonlinearSolveFirstOrder.BoundedLevenbergMarquardt — Function
BoundedLevenbergMarquardt(; autodiff = nothing, jvp_autodiff = nothing, vjp_autodiff = nothing,
linsolve = nothing, concrete_jac = nothing, gtol = nothing,
damping = 1e-3, max_backtracks = 40)Native bound-constrained Levenberg–Marquardt method. An active-set solve minimizes the regularized Gauss–Newton model over the box, followed by a feasible Armijo line search. A projected-gradient line search supplies a fallback when the model step is unsuitable. The positive damping initializes residual-scaled regularization and is adapted using the agreement between actual and predicted reduction. max_backtracks limits each line search through the shared LineSearch.ProjectedBackTracking cache.
Uses the shared Jacobian and linear-solver caches, preserving sparse and operator representations. Bounds, linear solver and AD options, gtol, real state requirements, and root-versus-least-squares termination follow TrustRegionReflective, except that iterates may lie exactly on a bound. Fixed coordinates are eliminated from the subproblem. No coordinate transformation is used.
The constrained model and projected-gradient globalization follow the strategy of Kanzow, Yamashita and Fukushima, Levenberg–Marquardt methods with strong local convergence properties for solving nonlinear equations with convex constraints, Journal of Computational and Applied Mathematics 172 (2004), 375–397. This implementation uses an active-set box subproblem rather than a general convex-programming solver.
NonlinearSolveFirstOrder.Dogbox — Function
Dogbox(; autodiff = nothing, jvp_autodiff = nothing, vjp_autodiff = nothing,
linsolve = nothing, concrete_jac = nothing, gtol = nothing,
initial_trust_radius = 1, max_trust_radius = Inf)Rectangular trust-region dogleg method for box-constrained nonlinear least squares and nonlinear equations. The step follows the dogleg path from a constrained Cauchy point toward the Gauss–Newton step in the free variables, inside the intersection of the box and an infinity-norm trust region.
Uses the shared Jacobian and linear-solver caches, preserving sparse and operator representations. Rank deficiency requires a suitable linear solver and can cause slow convergence, so prefer BoundedLevenbergMarquardt for such problems. Bounds, autodiff, gtol, real state requirements, and root-versus-least-squares termination follow TrustRegionReflective, except that iterates can lie exactly on a bound and the trust radius uses the infinity norm in the original coordinates.
See Voglis and Lagaris, A Rectangular Trust Region Dogleg Approach for Unconstrained and Bound Constrained Nonlinear Optimization, WSEAS Applied Mathematics (2004).
NonlinearSolveFirstOrder.BoundedGaussNewton — Function
BoundedGaussNewton(; globalization = :linesearch, autodiff = nothing, jvp_autodiff = nothing,
vjp_autodiff = nothing, linsolve = nothing, concrete_jac = nothing, gtol = nothing,
initial_trust_radius = 1, max_trust_radius = Inf, max_backtracks = 40)Active-set Gauss–Newton method in the original bounded coordinates. Variables fixed by the box or satisfying the outward-gradient active-bound condition are excluded from the linear least-squares solve. For square nonlinear equations this gives a feasible reduced Newton path; a stationary point with nonzero residual is not reported as a root.
globalization selects :linesearch (projected Armijo search), :trustregion (spherical trust region with a projected Cauchy safeguard), or :trustregion_linesearch (trust region with a projected line-search fallback after rejection). max_backtracks bounds each line search. Projected searches use the shared LineSearch.ProjectedBackTracking cache. The trust radius is measured in the original coordinates.
Bounds, autodiff, gtol, real state requirements, and least-squares termination follow TrustRegionReflective, except that exact-bound iterates are permitted. The reduced systems use the shared Jacobian and linear-solver caches, preserving sparse and operator representations and honoring the same linear-solver and AD options. This is a Gauss–Newton model of the residual merit function, not an exact-Hessian constrained optimization method.