Solver behaviour

This page describes how OptimizationSNOPT.jl translates between Optimization.jl and SNOPT: how a SNOPT status code becomes a return code, which SNOPT results the solution keeps, how derivatives and maximization are handled, and which limits follow from SNOPT and from the single SNOPT workspace per process. The SNOPT.jl concepts page explains the SNOPT terms used here, such as major iterations and the basis.

Return codes

When a solve ends, SNOPT returns an integer status code, which the solution keeps in sol.original.inform. OptimizationSNOPT.jl maps this code to the Optimization.jl return code in sol.retcode, so that program logic can test the return code in the same way for every Optimization.jl solver:

SNOPT status codesol.retcodeMeaning
1ReturnCode.SuccessOptimal solution found.
2–3ReturnCode.SuccessPartial success: a feasible point only (2), or less than the requested accuracy (3). Check sol.original.inform.
5–6, 11–16ReturnCode.InfeasibleThe constraints cannot be satisfied. Codes 5 and 6 come from SNOPT's elastic mode, in which the constraints may be violated.
21–22ReturnCode.FailureThe objective decreases without limit.
31–32ReturnCode.MaxItersAn iteration limit was reached.
34ReturnCode.MaxTimeThe CPU time limit (maxtime) was reached.
71–74ReturnCode.TerminatedThe callback returned true.
all othersReturnCode.FailureNumerical difficulties, wrong derivatives, insufficient memory, and other errors.

Because several SNOPT outcomes share ReturnCode.Success and ReturnCode.Failure, check sol.original.inform when the exact reason matters; the SNOPT 7.7 user guide explains each code.

SNOPT results in the solution

sol.original is a NamedTuple with the SNOPT results that Optimization.jl has no field for:

FieldContent
informSNOPT status code.
lambdaLagrange multipliers: one per variable, then one per constraint.
iterationsTotal number of minor iterations.
major_itnsNumber of major iterations.
num_infNumber of bounds and constraints that are still violated.
sum_infSum of these violations.
traceThe stored SnoptTrace, or nothing; also available as sol.trace.

sol.stats holds the Optimization.jl statistics: the wall-clock time of the solve and the number of objective and gradient evaluations. Its iteration count is not reliable in this version; use sol.original.major_itns.

Derivatives

SNOPT needs the gradient of the objective and the Jacobian of the constraints, but no second derivatives. OptimizationSNOPT.jl takes both from the OptimizationFunction: either from the automatic differentiation backend given as its second argument, such as AutoForwardDiff(), or from the functions passed as its grad and cons_j keywords. A solve without either source fails with an error that names the missing function.

The constraint Jacobian is passed to SNOPT as a dense matrix unless the OptimizationFunction has a sparsity pattern, either from a sparse backend such as AutoSparse(AutoForwardDiff()) or from the cons_jac_prototype keyword. All constraints are treated as nonlinear.

Maximization

SNOPT only minimizes. For a problem created with sense = MaxSense, OptimizationSNOPT.jl minimizes the negative objective and changes the sign back, so sol.objective, the callback and the trace all show the objective of the original problem.

Integer variables

SNOPT solves continuous problems only. If the OptimizationProblem marks variables as integer with the int keyword, OptimizationSNOPT.jl shows a warning and solves the continuous relaxation, in which those variables can take any real value.

One solve at a time

The SNOPT library allows only one active session, called the workspace, in each Julia process. OptimizationSNOPT.jl therefore runs solves one at a time: when several tasks or threads call solve at the same time, each call waits until the previous call has finished. To solve several problems in parallel, start several Julia processes, for example with the Distributed standard library.

Constructing a SnoptOptimizer and each solve open and close a workspace, so they close any SNOPT.jl workspace that is open in the same process.

Limits

  • Linear constraints cannot be given separately; they are treated as nonlinear.
  • Warm and hot starts are not available; each solve starts from u0 only.
  • SNOPT's print and summary files are not written.

SNOPT.jl gives access to linear constraints, warm and hot starts, and the SNOPT output files.