The main class used to interface with the SLSQP solver.
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
integer, | private | :: | n | = | 0 |
number of optimization variables () |
|
integer, | private | :: | m | = | 0 |
number of constraints () |
|
integer, | private | :: | meq | = | 0 |
number of equality constraints () |
|
integer, | private | :: | max_iter | = | 0 |
maximum number of iterations |
|
real(kind=wp), | private | :: | acc | = | zero |
accuracy tolerance |
|
real(kind=wp), | private | :: | tolf | = | -one |
accuracy tolerance over f: if then stop |
|
real(kind=wp), | private | :: | toldf | = | -one |
accuracy tolerance over df: if then stop.
It's different from |
|
real(kind=wp), | private | :: | toldx | = | -one |
accuracy tolerance over dx: if then stop |
|
integer, | private | :: | gradient_mode | = | 0 |
how the gradients are computed:
|
|
real(kind=wp), | private | :: | gradient_delta | = | 1.0e8_wp |
perturbation step size to approximate gradients
by finite differences ( |
|
real(kind=wp), | private | :: | alphamin | = | 0.1_wp |
min for line search |
|
real(kind=wp), | private | :: | alphamax | = | 1.0_wp |
max for line search |
|
integer, | private | :: | iprint | = | output_unit |
unit number of status printing (0 for no printing) |
|
real(kind=wp), | private, | dimension(:), allocatable | :: | xl |
lower bound on x |
||
real(kind=wp), | private, | dimension(:), allocatable | :: | xu |
upper bound on x |
||
integer, | private | :: | l_w | = | 0 |
size of |
|
real(kind=wp), | private, | dimension(:), allocatable | :: | w |
real work array |
||
procedure(func), | private, | pointer | :: | f | => | null() |
problem function subroutine |
procedure(grad), | private, | pointer | :: | g | => | null() |
gradient subroutine |
procedure(iterfunc), | private, | pointer | :: | report | => | null() |
for reporting an iteration |
integer, | private | :: | linesearch_mode | = | 1 |
linesearch mode:
|
|
type(linmin_data), | private | :: | linmin |
data formerly within linmin.
Only used when |
|||
type(slsqpb_data), | private | :: | slsqpb |
data formerly within slsqpb. |
|||
integer, | private | :: | nnls_mode | = | 1 |
Which NNLS method to use: |
|
integer, | private | :: | max_iter_ls | = | 0 |
max iterations in the least squares problem.
if |
|
logical, | private | :: | user_triggered_stop | = | .false. |
if the |
|
real(kind=wp), | private | :: | infinite_bound | = | huge(one) |
"infinity" for the upper and lower bounds.
if |
initialize the slsqp_solver class. see slsqp for more details.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(slsqp_solver), | intent(inout) | :: | me | |||
integer, | intent(in) | :: | n |
the number of variables, |
||
integer, | intent(in) | :: | m |
total number of constraints, |
||
integer, | intent(in) | :: | meq |
number of equality constraints, |
||
integer, | intent(in) | :: | max_iter |
maximum number of iterations |
||
real(kind=wp), | intent(in) | :: | acc |
accuracy |
||
procedure(func) | :: | f |
problem function |
|||
procedure(grad) | :: | g |
function to compute gradients (must be
associated if |
|||
real(kind=wp), | intent(in), | dimension(n) | :: | xl |
lower bounds on |
|
real(kind=wp), | intent(in), | dimension(n) | :: | xu |
upper bounds on |
|
logical, | intent(out) | :: | status_ok |
will be false if there were errors |
||
integer, | intent(in), | optional | :: | linesearch_mode |
1 = inexact (default), 2 = exact |
|
integer, | intent(in), | optional | :: | iprint |
unit number of status messages (default= |
|
procedure(iterfunc), | optional | :: | report |
user-defined procedure that will be called once per iteration |
||
real(kind=wp), | intent(in), | optional | :: | alphamin |
minimum alpha for linesearch [default 0.1] |
|
real(kind=wp), | intent(in), | optional | :: | alphamax |
maximum alpha for linesearch [default 1.0] |
|
integer, | intent(in), | optional | :: | gradient_mode |
how the gradients are to be computed: |
|
real(kind=wp), | intent(in), | optional | :: | gradient_delta |
perturbation step size (>epsilon) to compute the approximated
gradient by finite differences ( |
|
real(kind=wp), | intent(in), | optional | :: | tolf |
stopping criterion if then stop. |
|
real(kind=wp), | intent(in), | optional | :: | toldf |
stopping criterion if then stop |
|
real(kind=wp), | intent(in), | optional | :: | toldx |
stopping criterion if then stop |
|
integer, | intent(in), | optional | :: | max_iter_ls |
maximum number of iterations in the nnls problem |
|
integer, | intent(in), | optional | :: | nnls_mode |
Which NNLS method to use: |
|
real(kind=wp), | intent(in), | optional | :: | infinite_bound |
"infinity" for the upper and lower bounds.
if |
destructor for slsqp_solver.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(slsqp_solver), | intent(out) | :: | me |
main routine for calling slsqp.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(slsqp_solver), | intent(inout) | :: | me | |||
real(kind=wp), | intent(inout), | dimension(:) | :: | x |
in: initial optimization variables, out: solution. |
|
integer, | intent(out) | :: | istat |
status code (see |
||
integer, | intent(out), | optional | :: | iterations |
number of iterations |
|
character(len=:), | intent(out), | optional, | allocatable | :: | status_message |
string status message
corresponding to |
A method that the user can call to stop the iterations. (it can be called in any of the functions). SLSQP will stop at the end of the next iteration.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(slsqp_solver), | intent(inout) | :: | me |
for reporting messages to the user
Report a message from an slsqp_solver class. This uses the iprint
variable in the class as the unit number for printing. Note: for fatal errors,
if no unit is specified, the error_unit
is used.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(slsqp_solver), | intent(in) | :: | me | |||
character(len=*), | intent(in) | :: | str |
the message to report. |
||
integer, | intent(in), | optional | :: | ival |
optional integer to print after the message. |
|
real(kind=wp), | intent(in), | optional | :: | rval |
optional real to print after the message. |
|
logical, | intent(in), | optional | :: | fatal |
if True, then the program is stopped (default=False). |
type,public :: slsqp_solver !! The main class used to interface with the SLSQP solver. private integer :: n = 0 !! number of optimization variables (\( n > 0 \)) integer :: m = 0 !! number of constraints (\( m \ge 0 \)) integer :: meq = 0 !! number of equality constraints (\( m \ge m_{eq} \ge 0 \)) integer :: max_iter = 0 !! maximum number of iterations real(wp) :: acc = zero !! accuracy tolerance real(wp) :: tolf = -one !! accuracy tolerance over f: if \( |f| < tolf \) then stop real(wp) :: toldf = -one !! accuracy tolerance over df: if \( |f_{n+1} - f_n| < toldf \) then stop. !! It's different from `acc` in the case of positive derivative real(wp) :: toldx = -one !! accuracy tolerance over dx: if \( |x_{n+1} - x_n| < toldx \) then stop integer :: gradient_mode = 0 !! how the gradients are computed: !! !! * 0 - use the user-supplied `g` subroutine. [default] !! * 1 - approximate by basic backward differences !! * 2 - approximate by basic forward differences !! * 3 - approximate by basic central differences real(wp) :: gradient_delta = 1.0e8_wp !! perturbation step size to approximate gradients !! by finite differences (`gradient_mode` 1-3). !these two were not in the original code: real(wp) :: alphamin = 0.1_wp !! min \( \alpha \) for line search \( 0 < \alpha_{min} < \alpha_{max} \le 1 \) real(wp) :: alphamax = 1.0_wp !! max \( \alpha \) for line search \( 0 < \alpha_{min} < \alpha_{max} \le 1 \) integer :: iprint = output_unit !! unit number of status printing (0 for no printing) real(wp),dimension(:),allocatable :: xl !! lower bound on x real(wp),dimension(:),allocatable :: xu !! upper bound on x integer :: l_w = 0 !! size of `w` real(wp),dimension(:),allocatable :: w !! real work array procedure(func),pointer :: f => null() !! problem function subroutine procedure(grad),pointer :: g => null() !! gradient subroutine procedure(iterfunc),pointer :: report => null() !! for reporting an iteration integer :: linesearch_mode = 1 !! linesearch mode: !! !! * `1` = inexact (Armijo) linesearch, !! * `2` = exact linesearch. type(linmin_data) :: linmin !! data formerly within [[linmin]]. !! Only used when `linesearch_mode=2` type(slsqpb_data) :: slsqpb !! data formerly within [[slsqpb]]. ! note: the following two maybe should be combined into a separate type ! along with the two methods... integer :: nnls_mode = 1 !! Which NNLS method to use: !! !! 1. Use the original [[nnls]] !! 2. Use the newer [[bvls]] integer :: max_iter_ls = 0 !! max iterations in the least squares problem. !! if `<=0`, defaults to `3*n`. !! (use by either [[nnls]] or [[bvls]]) logical :: user_triggered_stop = .false. !! if the `abort` method has been called !! to stop the iterations real(wp) :: infinite_bound = huge(one) !! "infinity" for the upper and lower bounds. !! if `xl<=-infinite_bound` or `xu>=infinite_bound` !! then these bounds are considered nonexistant. contains private procedure,public :: initialize => initialize_slsqp procedure,public :: destroy => destroy_slsqp procedure,public :: optimize => slsqp_wrapper procedure,public :: abort => stop_iterations procedure :: report_message !! for reporting messages to the user end type slsqp_solver