SNOPT.jl is an unofficial Julia wrapper for
SNOPT, the sparse nonlinear
optimizer for large-scale constrained problems. It exposes SNOPT's snOptA,
snOptB, and snOptC interfaces through Julia callbacks, and provides snopt
as the main Julia-facing entry point.
SNOPT.jl is licensed under the MIT License. The underlying solver is
a closed-source commercial product for which you must
purchase a license; its
binaries are not distributed with this package.
SNOPT.jl needs a SNOPT shared library (libsnopt7.so on Linux,
libsnopt7.dylib on Intel macOS, libsnopt7.dll on Windows). Set the SNOPTDIR
environment variable to the directory containing it, then add the package:
import Pkg
Pkg.add("SNOPT")
using SNOPT
SNOPT.has_snopt() # true once the library is foundSNOPTDIR is the recommended setup on Linux and macOS. If it is unset, SNOPT.jl
also searches the platform library-path variables:
export LD_LIBRARY_PATH=/path/to/snopt:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=/path/to/snopt:$DYLD_LIBRARY_PATH # macOSIf the library is not found, the package still loads; has_snopt() returns
false and solves raise an informative error.
SNOPT solves are process-serial: run one solve at a time per Julia process, and use multiple Julia processes for parallel solves.
For most modeling workflows, the preferred interface will be
Optimization.jl. Support for that
interface is currently in progress. SNOPT.jl itself provides a compact API for
driving SNOPT directly with Julia callbacks.
The main entry point is snopt, which solves a problem through SNOPT's snOptB
interface. You supply an objective f(x), its gradient g!(g, x), and a starting
point:
using SNOPT
result = snopt(
x -> (x[1] - 1)^2 + (x[2] - 2)^2, # objective
(g, x) -> (g[1] = 2(x[1]-1); g[2] = 2(x[2]-2); nothing), # gradient
[0.0, 0.0];
lb = -10.0, ub = 10.0,
options = ["Major print level" => 0, :minor_print_level => 0],
)
result.status # SNOPT inform code
result.status_symbol # e.g. :Solve_Succeeded
result.objective # final objective value
result.x # solution vectorKey points of the low-level interface:
- Constraints. Pass
eval_con,eval_jac,lcon,ucon, and an optional sparse Jacobian sparsity patternJ(aSparseMatrixCSC).eval_jac(jnz, x)fills the Jacobian nonzeros inJ's column-major order; ifJis omitted, a dense pattern is assumed. The solve workspace is sized automatically from SNOPT's ownsnMemBestimator, exposed assnmemb. - Options. A vector of pairs whose keys are strings or symbols (symbol
underscores become spaces, so
:major_print_level => 0equals"Major print level" => 0). Options can also be read from a specs file withread_options. - Monitoring.
snlogreceives aSnoptMajorLogper major iteration (counters, objective, infeasibilities, the current point); the lower-levelcallbackkeyword fires on each objective/constraint evaluation. Returningfalsefrom either requests early termination.
result = snopt(f, g!, x0;
options = ["Major print level" => 1],
snlog = event -> (println("major $(event.major_iter): f = $(event.objective)"); true),
)Beyond snopt, the package exports the snOptA/snOptB/snOptC problem types
(SnoptA, SnoptB/SnoptProblem, SnoptC), their in-place solvers (snopta!,
snoptb!, snoptc!, snopt!), workspace management (initialize, set_option!,
snmemb), and callback builders (make_objfun, make_confun, make_usrfun_a,
make_usrfun_c, make_snlog). See the
documentation and the
examples/ directory (hs71.jl, unconstrained.jl) for full worked
problems.
Linux is tested with a compatible libsnopt7.
macOS on Intel should work with a compatible x86_64 libsnopt7.dylib, but it
has not been tested by the maintainers. Apple Silicon is not currently tested or
supported.
Windows requires a libsnopt7.dll built from the SNOPT source with
MinGW (the Intel-compiled distribution is not
ABI-compatible). If recompiling is not an option,
WSL is a working alternative.
This package draws on prior Julia SNOPT wrappers: