C++: Sparse Nonlinear OPTimizer (SNOPT)

class ppnf::snopt7 : public not_population_based

SNOPT 7 - (Sparse Nonlinear OPTimizer, Version 7)

_images/sol.png

This class is a user-defined algorithm (UDA) that contains a plugin to the Sparse Nonlinear OPTimizer (SNOPT) solver, a software package for large-scale nonlinear optimization. SNOPT is a powerful solver that is able to handle robustly and efficiently constrained nonlinear opimization problems also at high dimensionalities. Since the wrapper was developed around the version 7 of SNOPT the class is called ppnf::snopt7.

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).

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::evolve() will select a single individual from the input ppnf::population to be optimised. If the optimisation produces an improved individual (as established by ppnf::compare_fc()), the optimised individual will be inserted back into the population. The selection and replacement strategies can be configured via set_selection(const std::string &), set_selection(population::size_type), set_replacement(const std::string &) and set_replacement(population::size_type).

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 p 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.

Public Types

using log_line_type = std::tuple<unsigned long, double, pagmo::vector_double::size_type, double, bool>

Single data line for the algorithm’s log.

A log data line is a tuple consisting of:

  • the number of objective function evaluations made so far,

  • the objective function value for the current decision vector,

  • the number of constraints violated by the current decision vector,

  • the constraints violation norm for the current decision vector,

  • a boolean flag signalling the feasibility of the current decision vector.

using log_type = std::vector<log_line_type>

Log type.

The algorithm log is a collection of snopt7::log_line_type data lines, stored in chronological order during the optimisation if the verbosity of the algorithm is set to a nonzero value (see snopt7::set_verbosity()).

Public Functions

snopt7(bool screen_output = false, std::string snopt7_c_library = "/usr/local/lib/libsnopt7_c.so", unsigned minor_version = 6u)

Constructor.

The algorithm SNOPT7 can be constructed in two different ways, according to the user chioce, only one among the original SNOPT7 screen output and the pagmo logging system will be activated.

Parameters
  • screen_output: when true will activate the screen output from the SNOPT7 library, otherwise will let pagmo regulate logs and screen_output via its pagmo::algorithm::set_verbosity mechanism.

  • snopt7_c_library: The path to the snopt7_c library.

  • minor_version: The minor version of your Snopt7 library. Only two APIs are supported at the moment: a) 7.2 - 7.6 and b) 7.7. You may try to use this plugin with different minor version numbers, but at your own risk.

pagmo::population evolve(pagmo::population) const

Evolve population.

This method will select an individual from pop, optimise it using snOptA interface, replace an individual in pop with the optimised individual, and finally return pop. The individual selection and replacement criteria can be set via set_selection(const std::string &), set_selection(population::size_type), set_replacement(const std::string &) and set_replacement(population::size_type). The SNOPT7 solver will then run until one of the stopping criteria is satisfied, and the return status of the SNOPT7 solver will be recorded (it can be fetched with get_last_opt_result()).

Warning

All options passed to the snOptA interface are those set by the user via the ppnf::snopt7 interface, or where no user specifications are available, to the default detailed on the User Manual available online but with the following exception: “Major feasibility tolerance” is set to the default value 1E-6 or to the minimum among the values returned by pagmo::problem::get_c_tol() if not zero.

Note

The definitions of feasibility are different for SNOPT7 and pagmo. 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, pagmo 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 pagmo::problem. To guarantee feasibility with respect to pagmo 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.

Return

the optimised population.

Parameters
  • pop: the population to be optimised.

Exceptions
  • std::invalid_argument: in the following cases:

    • the population’s problem is multi-objective or stochastic

  • unspecified: any exception thrown by the public interface of pagmo::problem or pagmo::not_population_based.

void set_verbosity(unsigned)

Set verbosity.

This method will set the algorithm’s verbosity. If n is zero, no output is produced during the optimisation and no logging is performed. If n is nonzero, then every n objective function evaluations the status of the optimisation will be both printed to screen and recorded internally. See snopt7::log_line_type and snopt7::log_type for information on the logging format. The internal log can be fetched via get_log().

Example (verbosity 1):

objevals:        objval:      violated:    viol. norm:
        1        48.9451              1        1.25272 i
        2         30.153              1       0.716591 i
        3        26.2884              1        1.04269 i
        4        14.6958              2        7.80753 i
        5        14.7742              2        5.41342 i
        6         17.093              1      0.0905025 i
        7        17.1772              1      0.0158448 i
        8        17.0254              2      0.0261289 i
        9        17.0162              2     0.00435195 i
       10        17.0142              2    0.000188461 i
       11         17.014              1    1.90997e-07 i
       12         17.014              0              0
The i at the end of some rows indicates that the decision vector is infeasible. Feasibility is checked against the problem’s tolerance.
Parameters
  • n: the desired verbosity level.

By default, the verbosity level is zero.

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 pagmo::problem. That is, they might not necessarily be consistent with Snopt7’s notion of feasibility.

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. On-screen logging can be enabled constructing the object ppnf::snopt7 passing True as argument. In this case verbosity will not be allowed to be set.

const log_type &get_log() const

Get the optimisation log.

See snopt7::log_type for a description of the optimisation log. Logging is turned on/off via set_verbosity().

Return

a const reference to the log.

unsigned int get_verbosity() const

Gets the verbosity level.

Return

the verbosity level

std::string get_name() const

Algorithm name.

One of the optional methods of any user-defined algorithm (UDA).

Return

a string containing the algorithm name

std::string get_extra_info() const

Get extra information about the algorithm.

Return

a human-readable string containing useful information about the algorithm’s properties (e.g., the SNOPT7 user-set options, the selection/replacement policies, etc.), the snopt7_c library path

template<typename Archive>
void serialize(Archive &ar, unsigned)

Object serialization.

This method will save/load this into the archive ar.

Parameters
  • ar: target archive.

Exceptions
  • unspecified: any exception thrown by the serialization of the UDA and of primitive types.

void set_integer_option(const std::string&, int)

Set integer option.

This method will set the optimisation integer option name to value. The optimisation options are passed to the snOptA API when calling evolve().

Parameters
  • name: of the option.

  • value: of the option.

void set_integer_options(const std::map<std::string, int>&)

Set integer options.

This method will set the optimisation integer options contained in m. It is equivalent to calling set_integer_option() passing all the name-value pairs in m as arguments.

Parameters
  • m: the name-value map that will be used to set the options.

std::map<std::string, int> get_integer_options() const

Get integer options.

Return

the name-value map of optimisation integer options.

void set_numeric_option(const std::string&, double)

Set numeric option.

This method will set the optimisation numeric option name to value. The optimisation options are passed to the snOptA API when calling evolve().

Parameters
  • name: of the option.

  • value: of the option.

void set_numeric_options(const std::map<std::string, double>&)

Set numeric options.

This method will set the optimisation numeric options contained in m. It is equivalent to calling set_numeric_option() passing all the name-value pairs in m as arguments.

Parameters
  • m: the name-value map that will be used to set the options.

std::map<std::string, double> get_numeric_options() const

Get numeric options.

Return

the name-value map of optimisation numeric options.

void reset_integer_options()

Clear all integer options.

void reset_numeric_options()

Clear all numeric options.

int get_last_opt_result() const

Get the result of the last optimisation.

Return

the result of the last call to snOptA, or 0 if no optimisations have been run yet. The meaning of the code returned is detailed in the Snopt7 User Manual available on line.