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) |
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 |
|
| 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 | = | 1 |
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 | :: | 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, 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 |
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 |
LSQR: relative error in definition of |
|
| real(kind=wp), | intent(in), | optional | :: | btol |
LSQR: relative error in definition of |
|
| real(kind=wp), | intent(in), | optional | :: | conlim |
condition number of the matrix |
|
| real(kind=wp), | intent(in), | optional | :: | damp |
LSQR: damp factor |
|
| integer, | intent(in), | optional | :: | itnlim |
LSQR: max iterations |
|
| integer, | intent(in), | optional | :: | nout |
LSQR: output unit for printing |
|
| integer, | intent(in), | optional | :: | lusol_method |
Main solver.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(nlesolver_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(inout), | dimension(:) | :: | x |
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] |