A basic multidimensional nonlinear equation solver, using a Newton-Raphson type direct method.
dgesv or dgels) to solve the linear system.Todo
add an istat output to func and grad, for user stopping
or to take a smaller stop (if istat>0 take a smaller step, if istat<0 abort)
Note
The default real kind (wp) can be
changed using optional preprocessor flags.
This library was built with real kind:
real(kind=real64) [8 bytes]
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | parameter | :: | nlesolver_rk | = | real64 |
real kind used by this module [8 bytes] |
| integer, | private, | parameter | :: | wp | = | nlesolver_rk |
local copy of |
| real(kind=wp), | private, | parameter | :: | zero | = | 0.0_wp | |
| real(kind=wp), | private, | parameter | :: | one | = | 1.0_wp | |
| real(kind=wp), | private, | parameter | :: | two | = | 2.0_wp | |
| real(kind=wp), | private, | parameter | :: | eps | = | epsilon(one) |
machine |
| real(kind=wp), | private, | parameter | :: | big | = | huge(one) | |
| integer, | public, | parameter | :: | NLESOLVER_SPARSITY_DENSE | = | 1 |
sparsity_mode : assume dense (use dense solver). |
| integer, | public, | parameter | :: | NLESOLVER_SPARSITY_LSQR | = | 2 |
sparsity_mode : assume sparse (use LSQR sparse solver). |
| integer, | public, | parameter | :: | NLESOLVER_SPARSITY_LUSOL | = | 3 |
sparsity_mode : assume sparse (use LUSOL sparse solver). |
| integer, | public, | parameter | :: | NLESOLVER_SPARSITY_LSMR | = | 4 |
sparsity_mode : assume sparse (use LSMR sparse solver). |
| integer, | public, | parameter | :: | NLESOLVER_SPARSITY_CUSTOM_SPARSE | = | 5 |
sparsity_mode : assume sparse (use a user provided sparse solver). |
| integer, | public, | parameter | :: | NLESOLVER_IGNORE_BOUNDS | = | 0 |
bounds_mode : ignore bounds |
| integer, | public, | parameter | :: | NLESOLVER_SCALAR_BOUNDS | = | 1 |
bounds_mode : scalar mode |
| integer, | public, | parameter | :: | NLESOLVER_VECTOR_BOUNDS | = | 2 |
bounds_mode : vector mode |
| integer, | public, | parameter | :: | NLESOLVER_WALL_BOUNDS | = | 3 |
bounds_mode : wall mode |
| integer, | public, | parameter | :: | NLESOLVER_2_NORM | = | 1 |
norm_mode : 2-norm |
| integer, | public, | parameter | :: | NLESOLVER_INF_NORM | = | 2 |
norm_mode : infinity-norm |
| integer, | public, | parameter | :: | NLESOLVER_1_NORM | = | 3 |
norm_mode : 1-norm |
| integer, | public, | parameter | :: | NLESOLVER_LINESEARCH_SIMPLE | = | 1 |
linesearch : use the specified |
| integer, | public, | parameter | :: | NLESOLVER_LINESEARCH_BACKTRACKING | = | 2 |
linesearch : backtracking linesearch (between |
| integer, | public, | parameter | :: | NLESOLVER_LINESEARCH_EXACT | = | 3 |
linesearch : exact linesearch (between |
| integer, | public, | parameter | :: | NLESOLVER_LINESEARCH_FIXEDPOINT | = | 4 |
linesearch : evaluate function at specified fixed points (between |
function vector norm.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(in) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%m) | :: | fvec |
the function vector |
norm of the vector
for a custom user-provided linear solver (sparse version)
solve Ax = b for x, given A and b.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| integer, | intent(in) | :: | n_cols |
|
||
| integer, | intent(in) | :: | n_rows |
|
||
| integer, | intent(in) | :: | n_nonzero |
number of nonzero elements of A. |
||
| integer, | intent(in), | dimension(n_nonzero) | :: | irow |
sparsity pattern (size is |
|
| integer, | intent(in), | dimension(n_nonzero) | :: | icol |
sparsity pattern (size is |
|
| real(kind=wp), | intent(in), | dimension(n_nonzero) | :: | a |
matrix elements (size is |
|
| real(kind=wp), | intent(in), | dimension(n_rows) | :: | b |
right hand side (size is |
|
| real(kind=wp), | intent(out), | dimension(n_cols) | :: | x |
solution (size is |
|
| integer, | intent(out) | :: | istat |
status code (=0 for success) |
compute the function
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(:) | :: | x | ||
| real(kind=wp), | intent(out), | dimension(:) | :: | f |
compute the gradient of the function (Jacobian). Dense version.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(:) | :: | x | ||
| real(kind=wp), | intent(out), | dimension(:,:) | :: | g |
compute the gradient of the function (Jacobian). Sparse version.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(:) | :: | x | ||
| real(kind=wp), | intent(out), | dimension(:) | :: | g |
sparse jacobian. length is |
export an iteration:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(:) | :: | x | ||
| real(kind=wp), | intent(in), | dimension(:) | :: | f | ||
| integer, | intent(in) | :: | iter |
iteration number |
enable a user-triggered stop of the iterations:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| logical, | intent(out) | :: | user_stop |
line search method. Note that not all inputs/outputs are used by all methods.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%n) | :: | xold |
previous value of |
|
| real(kind=wp), | intent(in), | dimension(me%n) | :: | p |
search direction |
|
| real(kind=wp), | intent(out), | dimension(me%n) | :: | x |
new |
|
| real(kind=wp), | intent(inout) | :: | f |
|
||
| real(kind=wp), | intent(inout), | dimension(me%m) | :: | fvec |
|
|
| real(kind=wp), | intent(in), | optional, | dimension(:,:) | :: | fjac |
jacobian matrix [dense] |
| real(kind=wp), | intent(in), | optional, | dimension(:) | :: | fjac_sparse |
jacobian matrix [sparse] |
Nonlinear equations solver class.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | n | = | 0 |
number of opt vars |
|
| integer, | private | :: | m | = | 0 |
number of constraints |
|
| integer, | private | :: | max_iter | = | 100 |
maximum number of iterations |
|
| real(kind=wp), | private | :: | tol | = | 1.0e-6_wp |
convergence tolerance for function values |
|
| real(kind=wp), | private | :: | alpha | = | 1.0_wp |
step length (when specified constant) |
|
| real(kind=wp), | private | :: | alpha_min | = | 0.1_wp |
minimum step length (when allowed to vary) |
|
| real(kind=wp), | private | :: | alpha_max | = | 1.0_wp |
maximum step length (when allowed to vary) |
|
| real(kind=wp), | private | :: | tolx | = | 1.0e-8_wp |
convergence tolerance for |
|
| real(kind=wp), | private | :: | c | = | 0.5_wp |
backtracking linesearch parameter (0,1) |
|
| real(kind=wp), | private | :: | tau | = | 0.5_wp |
backtracking linesearch parameter (0,1) |
|
| real(kind=wp), | private | :: | fmin_tol | = | 1.0e-5_wp |
tolerance for "exact" linesearch |
|
| integer, | private | :: | n_intervals | = | 2 |
number of intervals for fixed point linesearch |
|
| logical, | private | :: | use_broyden | = | .false. |
if true, a Broyden update is used
rather than computing the Jacobian
at every step. The |
|
| integer, | private | :: | broyden_update_n | = | 4 |
if this value is |
|
| integer, | private | :: | n_uphill_max | = | 5 |
maximum number of consecutive steps
to allow where the value of |
|
| logical, | private | :: | verbose | = | .false. |
verbose output printing |
|
| integer, | private | :: | iunit | = | output_unit |
output unit for printing (assumed to be open). |
|
| character(len=:), | private, | allocatable | :: | message |
latest status message |
||
| integer, | private | :: | istat | = | -999 |
latest status message |
|
| integer, | private | :: | norm_mode | = | NLESOLVER_2_NORM |
how to compute the norm of the function vector: |
|
| integer, | private | :: | bounds_mode | = | NLESOLVER_IGNORE_BOUNDS |
how to handle the |
|
| real(kind=wp), | private, | dimension(:), allocatable | :: | xlow |
lower bounds for |
||
| real(kind=wp), | private, | dimension(:), allocatable | :: | xupp |
upper bounds for |
||
| procedure(func_func), | private, | pointer | :: | func | => | null() |
user-supplied routine to compute the function |
| procedure(export_func), | private, | pointer | :: | export_iteration | => | null() |
user-supplied routine to export iterations |
| procedure(wait_func), | private, | pointer | :: | user_input_check | => | null() |
user-supplied routine to enable user to stop iterations |
| procedure(linesearch_func), | private, | pointer | :: | linesearch | => | null() |
line search method (determined by |
| integer, | private | :: | sparsity_mode | = | NLESOLVER_SPARSITY_DENSE |
sparsity mode: |
|
| integer, | private | :: | n_nonzeros | = | -1 |
number of nonzero Jacobian elements (used for |
|
| integer, | private, | dimension(:), allocatable | :: | irow |
sparsity pattern nonzero elements row indices. |
||
| integer, | private, | dimension(:), allocatable | :: | icol |
sparsity pattern nonzero elements column indices |
||
| real(kind=wp), | private | :: | atol | = | zero |
relative error in definition of |
|
| real(kind=wp), | private | :: | btol | = | zero |
relative error in definition of |
|
| real(kind=wp), | private | :: | conlim | = | zero |
An upper limit on |
|
| integer, | private | :: | itnlim | = | 100 |
max iterations |
|
| integer, | private | :: | nout | = | 0 |
output unit for printing |
|
| real(kind=wp), | private | :: | damp | = | zero |
damp parameter for LSQR |
|
| integer, | private | :: | localSize | = | 0 |
0 This many n-vectors "v" (the most recent ones) are saved for reorthogonalizing the next v. |
|
| integer, | private | :: | lusol_method | = | 0 |
|
|
| procedure(grad_func), | private, | pointer | :: | grad | => | null() |
user-supplied routine to compute the gradient of the function (dense version) |
| procedure(grad_func_sparse), | private, | pointer | :: | grad_sparse | => | null() |
user-supplied routine to compute the gradient of the function (sparse version) |
| procedure(sparse_solver_func), | private, | pointer | :: | custom_solver_sparse | => | null() |
user-supplied sparse linear solver routine (used for |
| procedure(norm_func), | private, | pointer | :: | norm | => | null() |
function for computing the norm of the |
| procedure, public :: initialize => initialize_nlesolver_variables | |
| procedure, public :: solve => nlesolver_solver | |
| procedure, public :: destroy => destroy_nlesolver_variables | |
| procedure, public :: status => get_status | |
| procedure, private :: set_status | |
| procedure, private :: adjust_x_for_bounds | |
| procedure, private :: adjust_search_direction | |
| procedure, private :: compute_next_step |
Convert an integer to a string. Works for up to 256 digits.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | i |
integer to convert |
string result
Convert a real to a string. Works for up to 256 digits.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | r |
real to convert |
string result
2-norm function
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(in) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%m) | :: | fvec |
the function vector |
norm of the vector
1-norm function
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(in) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%m) | :: | fvec |
the function vector |
norm of the vector
Infinity-norm function
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(in) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%m) | :: | fvec |
the function vector |
norm of the vector
Set status flag and message.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| integer, | intent(in) | :: | istat |
status code |
||
| character(len=*), | intent(in) | :: | string |
status message |
||
| integer, | intent(in), | optional | :: | i |
an integer value to append |
|
| real(kind=wp), | intent(in), | optional | :: | r |
a real value to append |
Return the status code and message from the nlesolver_type class.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| integer, | intent(out), | optional | :: | istat |
Integer status code. |
|
| character(len=:), | intent(out), | optional, | allocatable | :: | message |
Text status message |
Constructor for the class.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| integer, | intent(in) | :: | n |
number of optimization variables |
||
| integer, | intent(in) | :: | m |
number of constraints |
||
| integer, | intent(in) | :: | max_iter |
maximum number of iterations |
||
| real(kind=wp), | intent(in) | :: | tol |
function convergence tolerance |
||
| real(kind=wp), | intent(in), | optional | :: | alpha |
constant step length for |
|
| real(kind=wp), | intent(in), | optional | :: | alpha_min |
minimum step length (0,1] |
|
| real(kind=wp), | intent(in), | optional | :: | alpha_max |
maximum step length (0,1] |
|
| real(kind=wp), | intent(in), | optional | :: | tolx |
convergence tolerance for changes in |
|
| real(kind=wp), | intent(in), | optional | :: | fmin_tol |
convergence tolerance for fmin (used when |
|
| real(kind=wp), | intent(in), | optional | :: | backtrack_c |
backtracking linesearch parameter (0,1) |
|
| real(kind=wp), | intent(in), | optional | :: | backtrack_tau |
backtracking linesearch parameter (0,1) |
|
| logical, | intent(in), | optional | :: | use_broyden |
use a Broyden update (default is False) |
|
| integer, | intent(in), | optional | :: | broyden_update_n |
For Broyden mode, update the full Jacobian at most every this many iterations (must be >1) If <=1 then Jacobian is only computed on the first iteration. |
|
| integer, | intent(in), | optional | :: | step_mode |
step mode: |
|
| procedure(func_func) | :: | func |
computes the function vector |
|||
| procedure(grad_func), | optional | :: | grad |
computes the jacobian [required for dense mode: |
||
| procedure(grad_func_sparse), | optional | :: | grad_sparse |
computes the jacobian [required for sparse mode: |
||
| procedure(export_func), | optional | :: | export_iteration |
function to export each iteration |
||
| procedure(wait_func), | optional | :: | user_input_check |
check for user input (to stop solver if necessary) |
||
| logical, | intent(in), | optional | :: | verbose |
for verbose status printing |
|
| integer, | intent(in), | optional | :: | iunit |
unit for verbose printing (assumed to be open).
by default this is |
|
| integer, | intent(in), | optional | :: | n_uphill_max |
maximum number of consecutive steps
to allow where the value of |
|
| integer, | intent(in), | optional | :: | n_intervals |
number of intervals for fixed point linesearch |
|
| integer, | intent(in), | optional | :: | sparsity_mode |
sparsity mode: |
|
| integer, | intent(in), | optional, | dimension(:) | :: | irow |
sparsity pattern nonzero elements row indices.
must be specified with |
| integer, | intent(in), | optional, | dimension(:) | :: | icol |
sparsity pattern nonzero elements column indices
must be specified with |
| real(kind=wp), | intent(in), | optional | :: | atol |
|
|
| real(kind=wp), | intent(in), | optional | :: | btol |
|
|
| real(kind=wp), | intent(in), | optional | :: | conlim |
|
|
| real(kind=wp), | intent(in), | optional | :: | damp |
|
|
| integer, | intent(in), | optional | :: | itnlim |
|
|
| integer, | intent(in), | optional | :: | nout |
|
|
| integer, | intent(in), | optional | :: | lusol_method |
|
|
| integer, | intent(in), | optional | :: | localSize |
|
|
| procedure(sparse_solver_func), | optional | :: | custom_solver_sparse |
for |
||
| integer, | intent(in), | optional | :: | bounds_mode |
how to handle the |
|
| real(kind=wp), | intent(in), | optional, | dimension(n) | :: | xlow |
lower bounds for |
| real(kind=wp), | intent(in), | optional, | dimension(n) | :: | xupp |
upper bounds for |
| integer, | intent(in), | optional | :: | norm_mode |
how to compute the norm of the function vector: |
Main solver.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(inout), | dimension(:) | :: | x |
if necessary, adjust the x vector to be within the bounds.
used for the initial guess.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(inout), | dimension(me%n) | :: | x |
the |
if necessary, adjust the search direction vector p so that bounds are not violated.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%n) | :: | x |
initial |
|
| real(kind=wp), | intent(in), | dimension(me%n) | :: | p |
search direction |
|
| real(kind=wp), | intent(out), | dimension(me%n) | :: | pnew |
new search direction |
|
| logical, | intent(out), | dimension(me%n) | :: | modified |
indicates the elements of |
Compute the next step.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%n) | :: | xold |
initial |
|
| real(kind=wp), | intent(in), | dimension(me%n) | :: | search_direction |
search direction vector |
|
| real(kind=wp), | intent(in) | :: | alpha |
step length to take in the search direction |
||
| logical, | intent(in), | dimension(me%n) | :: | modified |
indicates the elements of |
|
| real(kind=wp), | intent(out), | dimension(me%n) | :: | xnew |
final |
Solve the linear system: , using a dense, direct method.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | m |
number of rows in |
||
| integer, | intent(in) | :: | n |
number of columns in |
||
| real(kind=wp), | intent(in), | dimension(m,n) | :: | a |
|
|
| real(kind=wp), | intent(in), | dimension(m) | :: | b |
RHS of the linear system |
|
| real(kind=wp), | intent(out), | dimension(n) | :: | x |
the solution of the linear system. |
|
| integer, | intent(out) | :: | info |
output status flag ( |
Take a simple step in the search direction of p * alpha.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%n) | :: | xold |
previous value of |
|
| real(kind=wp), | intent(in), | dimension(me%n) | :: | p |
search direction |
|
| real(kind=wp), | intent(out), | dimension(me%n) | :: | x |
new |
|
| real(kind=wp), | intent(inout) | :: | f |
magnitude of |
||
| real(kind=wp), | intent(inout), | dimension(me%m) | :: | fvec |
function vector |
|
| real(kind=wp), | intent(in), | optional, | dimension(:,:) | :: | fjac |
jacobian matrix [dense] |
| real(kind=wp), | intent(in), | optional, | dimension(:) | :: | fjac_sparse |
jacobian matrix [sparse] |
Backtracking line search.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%n) | :: | xold |
previous value of |
|
| real(kind=wp), | intent(in), | dimension(me%n) | :: | p |
search direction |
|
| real(kind=wp), | intent(out), | dimension(me%n) | :: | x |
new |
|
| real(kind=wp), | intent(inout) | :: | f |
magnitude of |
||
| real(kind=wp), | intent(inout), | dimension(me%m) | :: | fvec |
function vector |
|
| real(kind=wp), | intent(in), | optional, | dimension(:,:) | :: | fjac |
jacobian matrix [dense] |
| real(kind=wp), | intent(in), | optional, | dimension(:) | :: | fjac_sparse |
jacobian matrix [sparse] |
An exact linesearch that uses a derivative-free minimizer to
find the minimum value of f(x) between
x = xold + p * alpha_min and
x = xold + p * alpha_max.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%n) | :: | xold |
previous value of |
|
| real(kind=wp), | intent(in), | dimension(me%n) | :: | p |
search direction |
|
| real(kind=wp), | intent(out), | dimension(me%n) | :: | x |
new |
|
| real(kind=wp), | intent(inout) | :: | f |
magnitude of |
||
| real(kind=wp), | intent(inout), | dimension(me%m) | :: | fvec |
function vector |
|
| real(kind=wp), | intent(in), | optional, | dimension(:,:) | :: | fjac |
jacobian matrix [dense] |
| real(kind=wp), | intent(in), | optional, | dimension(:) | :: | fjac_sparse |
jacobian matrix [sparse] |
A simple search that just evaluates the function at a specified number of points and picks the one with the minimum function value.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(me%n) | :: | xold |
previous value of |
|
| real(kind=wp), | intent(in), | dimension(me%n) | :: | p |
search direction |
|
| real(kind=wp), | intent(out), | dimension(me%n) | :: | x |
new |
|
| real(kind=wp), | intent(inout) | :: | f |
magnitude of |
||
| real(kind=wp), | intent(inout), | dimension(me%m) | :: | fvec |
function vector |
|
| real(kind=wp), | intent(in), | optional, | dimension(:,:) | :: | fjac |
jacobian matrix [dense] |
| real(kind=wp), | intent(in), | optional, | dimension(:) | :: | fjac_sparse |
jacobian matrix [sparse] |