Py: Sparse Nonlinear OPTimizer (SNOPT)¶
-
class
pygmo_plugins_nonfree.
snopt7
(screen_output=False, library='/usr/local/lib/libsnopt7.so', minor_version=6)¶ SNOPT 7 - (Sparse Nonlinear OPTimizer, Version 7)
This class is a user-defined algorithm (UDA) that contains a plugin to the Sparse Nonlinear OPTimizer (SNOPT, V7) solver, a software package for large-scale nonlinear optimization. SNOPT7 is a powerful solver that is able to handle robustly and efficiently constrained nonlinear opimization problems also at high dimensionalities.
- Intended use::
>>> import pygmo as pg >>> import pygmo_plugins_nonfree as ppnf >>> uda = ppnf.snopt7(screen_output = False, library = "/usr/local/lib/libsnopt76.so", minor_version = 6) >>> algo = pg.algorithm(uda)
SNOPT7 supports only single-objective minimisation, using a sequential quadratic programming (SQP) algorithm. Search directions are obtained from QP subproblems that minimize a quadratic model of the Lagrangian function subject to linearized constraints. An augmented Lagrangian merit function is reduced along each search direction to ensure convergence from any starting point.
In order to support pagmo’s population-based optimisation model, snopt7 selects a single individual from the input population to be optimised. If the optimisation produces an improved individual (as established by pagmo comparison criteria), the optimised individual will be inserted back into the population.
- Parameters
screen_output (
bool
) – when True will activate the original screen output from SNOPT7 and deactivate the logging system based onset_verbosity()
.library (
str
) – the snopt7 library filename in your system (absolute path included)minor_version (
int
) – The minor version of your Snopt7 library. Only two APIs are supported at the moment: 7.6 and 7.7. You may try to use this plugin with different minor version numbers, but at your own risk.
- Raises
ArgumentError – for any conversion problems between the python types and the c++ signature
Note
SNOPT7 fortran code is only available acquiring a licence. If you do have such a licence, then you will also have the fortran files and can build them into the library snopt7 (one single library). The library snopt7_c will then need to be built, compiling the correct release of the project https://github.com/snopt/snopt-interface. The library thus created will link to your fortran snopt7 library. As an alternative you may have only one library libsnopt7 containing both the Fortran and the C interface (this is the case, for example, of the library you can download for evaluation).
Note
This plugin was tested with snopt version 7.2 as well as with the compiled evaluation libraries (7.7) made available via the snopt7 official web site (C/Fortran library).
Warning
Constructing this class with an inconsistent minor_version parameter results in undefined behaviour.
Warning
A moved-from
ppnf::snopt7
is destructible and assignable. Any other operation will result in undefined behaviour.Warning
The possibility to exploit the linear part of the problem fitness, part of the original SNOPT7 library, is deactivated in this plugin for pagmo.
See also the docs of the C++ class
ppnf::snopt7
.-
get_log
()¶ - Returns
the optimisation log containing the values
objevals
,objval
,violated
,viol. norm
,feas.
, where:objevals
(int
), the number of objective function evaluations made so farobjval
(float
), the objective function value for the current decision vectorviolated
(int
), the number of constraints violated by the current decision vectorviol. norm
(float
), the constraints violation norm for the current decision vectorfeas.
(bool
), a boolean flag signalling the feasibility of the current decision vector (as determined by pagmo)
- Return type
list
- Raises
unspecified – any exception thrown by failures at the intersection between C++ and Python (e.g.,
type conversion errors, mismatched function signatures, etc.) –
Warning
The number of constraints violated, the constraints violation norm and the feasibility flag stored in the log are all determined via the facilities and the tolerances specified within
pygmo.problem
. That is, they might not necessarily be consistent with Snopt’s notion of feasibility. See the explanation of how the"Major feasibility tolerance"
numeric option is handled inpygmo.snopt7
and the note below.Note
The definitions of feasibility are different for SNOPT7 and pygmo. SNOPT7 requires that max(c_viol)/||x|| <= eps_r where ||x|| is the Euclidean norm of x, a candidate solution vector, and eps_r is the “Major feasibility tolerance” option in SNOPT7. In contrast, pygmo requires that c_viol <= c_tol where c_viol is the vector of absolute values of the nonlinear constraint violations and c_tol is the vector of constraint tolerances in pygmo.problem. To guarantee feasibility with respect to pygmo when SNOPT7 reports feasibility, try setting eps_r <= min(c_tol)/||x||_ub, where ||x||_ub is an upper bound on the value of ||x||. Care must be taken with this approach to ensure eps_r is not too small.
Note
Snopt7 supports its own logging format and protocol, including the ability to print to screen and write to file. Snopt7’s screen logging is disabled by default. It can be activated upon construction by setting the relative kwarg to
True
Examples
>>> from pygmo import * >>> from pygmo_plugins_nonfree import snopt7 >>> algo = algorithm(snopt7(screen_output = False, library = "/usr/local/lib/libsnopt7.so")) >>> algo.set_verbosity(1) >>> prob = problem(cec2006(prob_id = 1)) >>> prob.c_tol = [1e-6]*9 >>> pop = population(prob, 1) >>> pop = algo.evolve(pop) SNOPT7 plugin for pagmo/pygmo: The gradient sparsity is assumed dense: 130 components detected. The gradient is computed numerically by SNOPT7. objevals: objval: violated: viol. norm: 1 -214.451 9 294.796 i 11 -214.451 9 294.796 i 21 -210.962 9 289.599 i 31 -207.466 9 284.397 i 41 -207.466 9 284.397 i 51 -207.469 9 284.397 i 61 -14.802 0 0 71 -14.802 1 9.50602e-08 i 81 -14.798 1 1.04126e-07 i 91 -15 0 0 101 -15 1 9.54841e-08 i 111 -14.9987 0 0 121 -14.9997 1 0.000534611 i 131 -14.9997 0 0 Finished successfully - optimality conditions satisfied >>> uda = algo.extract(snopt7) >>> uda.get_log() [(1, -214.45104382308432, 9, 294.79616317933454, False), (11, -214.45108700799688, ...
-
property
replacement
¶ Individual replacement policy.
This attribute represents the policy that is used in the
evolve()
method to select the individual that will be replaced by the optimised individual. The attribute can be either a string or an integral.If the attribute is a string, it must be one of
"best"
,"worst"
and"random"
:"best"
will select the best individual in the population,"worst"
will select the worst individual in the population,"random"
will randomly choose one individual in the population.
set_random_sr_seed()
can be used to seed the random number generator used by the"random"
policy.If the attribute is an integer, it represents the index (in the population) of the individual that will be replaced by the optimised individual.
- Returns
the individual replacement policy or index
- Return type
int
orstr
- Raises
OverflowError – if the attribute is set to an integer which is negative or too large
ValueError – if the attribute is set to an invalid string
TypeError – if the attribute is set to a value of an invalid type
unspecified – any exception thrown by failures at the intersection between C++ and Python (e.g., type conversion errors, mismatched function signatures, etc.)
-
property
selection
¶ Individual selection policy.
This attribute represents the policy that is used in the
evolve()
method to select the individual that will be optimised. The attribute can be either a string or an integral.If the attribute is a string, it must be one of
"best"
,"worst"
and"random"
:"best"
will select the best individual in the population,"worst"
will select the worst individual in the population,"random"
will randomly choose one individual in the population.
set_random_sr_seed()
can be used to seed the random number generator used by the"random"
policy.If the attribute is an integer, it represents the index (in the population) of the individual that is selected for optimisation.
- Returns
the individual selection policy or index
- Return type
int
orstr
- Raises
OverflowError – if the attribute is set to an integer which is negative or too large
ValueError – if the attribute is set to an invalid string
TypeError – if the attribute is set to a value of an invalid type
unspecified – any exception thrown by failures at the intersection between C++ and Python (e.g., type conversion errors, mismatched function signatures, etc.)
-
set_integer_option
(name, value)¶ Set integer option.
This method will set the optimisation integer option p name to p value. The optimisation options are passed to the snOptA API when calling evolve().
- Parameters
name (
string
) – name of the optionvalue (
int
) – value of the option
The available integer options are listed in the following table:
Name
Default Value
Notes
Objective row
1
has precedence over ObjRow (snOptA)
Verify level
0
Gradients Check Flag
Scale option
1
Scaling (1 - linear constraints and variables)
Crash option
3
3 - first basis is essentially triangular
Iterations limit
10000
or 20*ncons if that is more
Partial price
1
10 for large LPs
Major iterations limit
1000
or ncons if that is more
Minor iterations limit
500
or 3*ncons if that is more
Superbasics limit
None
n1 + 1, n1 = number of nonlinear variables
New superbasics limit
99
controls early termination of QPs
Proximal point method
1
1 - satisfies linear constraints near x0
Reduced Hessian dimension
2000
or Superbasics limit if that is less
Violation limit
10.0
unscaled constraint violation limit
Hessian frequency
999999
for full Hessian (never reset)
Hessian updates
10
for limited memory Hessian
Hessian flush
999999
no flushing
Check frequency
60
test row residuals l2norm(Ax - sk)
Expand frequency
10000
for anti-cycling procedure
Factorization frequency
50
100 for LPs
Save frequency
100
save basis map
Old basis file
0
input basis map
New basis file
0
output basis map
Backup basis file
0
output extra basis map
Insert file
0
input in industry format
Punch file
0
output Insert data
Load file
0
input names and values
Dump file
0
output Load data
Solution file
0
different from printed solution
Total character workspace
500
lencw: 500
Total integer workspace
None
leniw: 500 + 100 * (m+n)
Total real workspace
None
lenrw: 500 + 200 * (m+n)
User character workspace
500
User integer workspace
500
User real workspace
500
Debug level
0
0 - Normal, 1 - for developers
Timing level
3
3 - print cpu times
Note
In case of invalid option name this function will be correctly executed, but a subsequent call to evolve() will raise a ValueError.
Examples
>>> import pygmo as pg >>> import pygmo_plugins_nonfree as pg7 >>> udp = pg.problem(pg.cec2006(prob_id = 1)) >>> uda = pg7.snopt7(False, "/usr/local/lib/libsnopt7.so") >>> uda.set_integer_option("Iterations limit", 10) >>> algo = pg.algorithm(uda) >>> algo.set_verbosity(10) >>> pop = pg.population(udp,1) >>> pop = algo.evolve(pop) SNOPT7 plugin for pagmo/pygmo: The gradient sparsity is assumed dense: 130 components detected. The gradient is computed numerically by SNOPT7. objevals: objval: violated: viol. norm: 1 -78.0445 8 105.847 i 11 -78.0445 8 105.847 i 21 -74.7751 8 100.505 i 31 -74.7751 8 100.505 i Resource limit error - iteration limit reached
-
set_numeric_option
(name, value)¶ Set numeric option.
This method will set the optimisation numeric option p name to p value. The optimisation options are passed to the snOptA API when calling evolve().
- Parameters
name (
string
) – name of the optionvalue (
float
) – value of the option
The available numeric options are listed in the following table:
Name
Default Value
Notes
Infinite bound
1.0e+20
Infinite Bound Value
Major feasibility tolerance
1.0e-6
Target Nonlinear Constraint Violation
Major optimality tolerance
1.0e-6
Target Complementarity Gap
Minor feasibility tolerance
1.0e-6
For Satisfying the QP Bounds
Scale tolerance
0.9
Scaling Tolerance
Crash tolerance
0.1
Linesearch tolerance
0.9
smaller for more accurate search
Pivot tolerance
3.7e-11
epsilon^{2/3}
Elastic weight
1.0e+4
used only during elastic mode
Major step limit
2.0
Function precision
3.0e-13
epsilon^0.8 (almost full accuracy)
Difference interval
5.5e-7
Function precision^(1/2)
Central difference interval
6.7e-5
Function precision^(1/3)
Penalty parameter
0.0
initial penalty parameter
Unbounded step size
1.0e+18
Unbounded objective
1.0e+15
LU factor tolerance
3.99
for NP (100.0 for LP)
LU update tolerance
3.99
for NP ( 10.0 for LP)
LU singularity tolerance
3.2e-11
Note
In case of invalid option name this function will not throw, but a subsequent call to evolve() will raise a ValueError.
Examples
>>> import pygmo as pg >>> import pygmo_plugins_nonfree as pg7 >>> udp = pg.problem(pg.cec2006(prob_id = 1)) >>> uda = pg7.snopt7(False, "/usr/local/lib/libsnopt7.so") >>> uda.set_numeric_option("Major feasibility tolerance", 1e-2) >>> algo = pg.algorithm(uda) >>> algo.set_verbosity(20) >>> pop = pg.population(udp,1) >>> pop = algo.evolve(pop) SNOPT7 plugin for pagmo/pygmo: The gradient sparsity is assumed dense: 130 components detected. The gradient is computed numerically by SNOPT7. objevals: objval: violated: viol. norm: 1 -112.494 9 175.091 i 21 -109.07 9 169.082 i 41 -105.64 9 163.066 i 61 -11.3869 1 2.00323e-09 i 81 -11.3764 2 1.09242e-06 i 101 -11.4844 4 3.09867e-06 i 121 -11.4841 5 0.000267805 i Finished successfully - optimality conditions satisfied
-
set_random_sr_seed
(seed)¶ Set the seed for the
"random"
selection/replacement policies.- Parameters
seed (
int
) – the value that will be used to seed the random number generator used by the"random"
election/replacement policies (seeselection
andreplacement
)- Raises
OverflowError – if the attribute is set to an integer which is negative or too large
unspecified – any exception thrown by failures at the intersection between C++ and Python (e.g., type conversion errors, mismatched function signatures, etc.)