# newton_solver Robust Newton-Raphson solver for systems of nonlinear equations F(x) = 0.
@note Note This module was generated by a LLM.
Algorithm: Pure Newton with Levenberg-Marquardt (LM) regularization and Armijo backtracking line search used as a globalization strategy. The solver starts as pure Newton (lambda = 0) and promotes to LM whenever the Jacobian is detected to be singular or ill-conditioned, or when the line search cannot find a sufficient decrease.
Dependencies: LAPACK – dgetrf (LU factorisation with partial pivoting) dgetrs (triangular back-substitution) dgecon (1-norm condition number estimator)
## Examples ### Minimal call:
call newton(my_sub, x)
### Full call:
type(newton_settings) :: s
type(newton_result) :: r
s%atol = 1.0e-10_pr
s%verbosity = 2
call newton(my_sub, x, s, r)
if (r%status /= NEWTON_SUCCESS) write(*,*) newton_status_msg(r%status)
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | public, | parameter | :: | NEWTON_LINE_SEARCH_FAIL | = | 5 | |
| integer, | public, | parameter | :: | NEWTON_MAX_ITS | = | 1 | |
| integer, | public, | parameter | :: | NEWTON_NAN_INF | = | 2 | |
| integer, | public, | parameter | :: | NEWTON_SINGULAR | = | 3 | |
| integer, | public, | parameter | :: | NEWTON_STAGNATION | = | 4 | |
| integer, | public, | parameter | :: | NEWTON_SUCCESS | = | 0 |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=pr), | intent(in) | :: | X(:) | |||
| real(kind=pr), | intent(out) | :: | F(:) | |||
| real(kind=pr), | intent(out) | :: | J(:,:) |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=pr), | public | :: | cond_est | = | 0.0_pr |
Estimated condition number of J (or J^T J + lambda I when LM active) at the final iteration, via LAPACK dgecon. Dimensionless. |
|
| real(kind=pr), | public | :: | dx_norm | = | 0.0_pr |
||dX||_inf of the last computed Newton step at exit. Units: same as x. |
|
| real(kind=pr), | public, | allocatable | :: | f_history(:) |
||F||_inf at iterations 0, 1, …, result%iterations. Allocated only when settings%save_history = .true. Size: (iterations + 1). |
||
| real(kind=pr), | public | :: | f_norm | = | 0.0_pr |
||F(x)||_inf at exit. Should be < atol on NEWTON_SUCCESS. Units: same as F. |
|
| integer, | public | :: | iterations | = | 0 |
Total number of Newton iterations performed (accepted + rejected). |
|
| real(kind=pr), | public | :: | lambda | = | 0.0_pr |
Value of the LM regularisation parameter at exit. 0.0 means the final solve was a pure Newton step. Units: [J]^2. |
|
| integer, | public | :: | status | = | 0 |
Exit status code. Compare with NEWTON_SUCCESS, NEWTON_MAX_ITS, etc. Use newton_status_msg(status) for a human-readable string. |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=pr), | public | :: | armijo_c | = | 1.0e-4_pr |
Sufficient decrease constant (Wolfe c1 condition). Smaller values accept more steps but give weaker convergence guarantees. Must satisfy 0 < armijo_c < 0.5. Dimensionless. Default: 1e-4. |
|
| integer, | public | :: | armijo_max_its | = | 50 |
Maximum number of backtracking halvings per Newton step. If reached without satisfying Armijo, ls_failed is set .true. Default: 50. |
|
| real(kind=pr), | public | :: | armijo_tau | = | 0.5_pr |
Step-length reduction factor applied each backtracking iteration. t_new = armijo_tau * t_old until Armijo or t < t_min. Must satisfy 0 < armijo_tau < 1. Dimensionless. Default: 0.5. |
|
| real(kind=pr), | public | :: | atol | = | 1.0e-9_pr |
Absolute residual tolerance. Converged when max_i |F_i(x)| < atol. Units: same as F. Default: 1e-8. |
|
| real(kind=pr), | public | :: | cond_max | = | 1.0e10_pr |
Condition number threshold above which LM regularization is activated (or strengthened) to stabilise the linear solve. Estimated via LAPACK dgecon. Dimensionless. Default: 1e10. |
|
| real(kind=pr), | public | :: | lambda0 | = | 0.0_pr |
Initial value of the LM damping parameter. 0.0 = start as pure Newton; the solver activates LM automatically if conditioning is poor. Set > 0 to force LM from the first iteration. Units: [J]^2 (scales with the Jacobian entries squared). Default: 0. |
|
| real(kind=pr), | public | :: | lambda_down | = | 5.0_pr |
Factor by which lambda is divided after a successful step with t > 0.1. Drives the solver back toward pure Newton as the iterate improves. Dimensionless. Default: 5. |
|
| real(kind=pr), | public | :: | lambda_max | = | 1.0e8_pr |
Maximum lambda, expressed as a multiplier of jacobian_scale. If lambda exceeds this ceiling the solver returns NEWTON_LINE_SEARCH_FAIL. Dimensionless multiplier. Default: 1e8. |
|
| real(kind=pr), | public | :: | lambda_min | = | 1.0e-6_pr |
Minimum non-zero lambda, expressed as a multiplier of jacobian_scale. Effective floor = lambda_min * ||J||_F^2/n. Prevents lambda from decaying to numerical zero after a good step. Dimensionless multiplier. Default: 1e-6. |
|
| real(kind=pr), | public | :: | lambda_up | = | 10.0_pr |
Factor by which lambda is multiplied on a line-search failure. Larger values recover faster from bad Jacobians but may overshoot. Dimensionless. Default: 10. |
|
| integer, | public | :: | max_its | = | 100 |
Maximum number of Newton iterations before returning NEWTON_MAX_ITS. Default: 100. |
|
| real(kind=pr), | public | :: | rtol | = | 1.0e-9_pr |
Relative step tolerance. Converged when max_i |dX_i| < rtol * (max_i |x_i| + atol). Catches the case where the step becomes negligible compared to x. Dimensionless. Default: 1e-6. |
|
| logical, | public | :: | save_history | = | .false. |
If .true., allocate result%f_history(0:iterations) and store ||F||_inf at each iteration. Slightly increases memory use. Default: .false. |
|
| integer, | public | :: | stagnation_nits | = | 5 |
Number of consecutive iterations with negligible change in ||dX|| before the solver exits with NEWTON_STAGNATION. Default: 5. |
|
| real(kind=pr), | public | :: | stagnation_tol | = | 1.0e-12_pr |
Relative threshold for stagnation: iteration is counted as stagnant when |||dX||_prev - ||dX||_curr| < stagnation_tol * (||dX|| + 1). Dimensionless. Default: 1e-12. |
|
| real(kind=pr), | public | :: | t_min | = | 1.0e-8_pr |
Minimum accepted step length. If t < t_min the line search declares failure instead of accepting a micro-step that satisfies Armijo trivially (m changes by ~machine eps). Dimensionless (fraction of the full Newton step). Default: 1e-8. |
|
| integer, | public | :: | verbosity | = | 0 |
Controls stdout output. 0 – silent 1 – print header + one-line summary at exit 2 – also print one line per accepted iteration Default: 0. |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | status |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=pr), | intent(in) | :: | v(:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=pr), | intent(in) | :: | J(:,:) |
Jacobian matrix, shape (n,n) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=pr), | intent(in) | :: | A(:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=pr), | intent(in) | :: | v(:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| procedure(to_solve) | :: | sub | ||||
| real(kind=pr), | intent(inout) | :: | x(:) | |||
| type(newton_settings), | intent(in), | optional | :: | settings | ||
| type(newton_result), | intent(out), | optional | :: | result |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=pr), | intent(inout) | :: | A(:,:) | |||
| real(kind=pr), | intent(in) | :: | val |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| procedure(to_solve) | :: | sub | ||||
| real(kind=pr), | intent(in) | :: | X_old(:) | |||
| real(kind=pr), | intent(in) | :: | F(:) | |||
| real(kind=pr), | intent(in) | :: | J(:,:) | |||
| real(kind=pr), | intent(in) | :: | dX(:) | |||
| type(newton_settings), | intent(in) | :: | s | |||
| real(kind=pr), | intent(inout) | :: | t | |||
| real(kind=pr), | intent(inout) | :: | F_new(:) | |||
| real(kind=pr), | intent(inout) | :: | J_new(:,:) | |||
| real(kind=pr), | intent(inout) | :: | f_norm_new | |||
| logical, | intent(out) | :: | failed |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(newton_result), | intent(inout) | :: | res | |||
| type(newton_result), | intent(out), | optional | :: | res_out | ||
| type(newton_settings), | intent(in) | :: | s | |||
| real(kind=pr), | intent(in), | optional | :: | hist_buf(:) | ||
| integer, | intent(in) | :: | its |
Iterations done |
||
| real(kind=pr), | intent(in) | :: | f_norm |
||F||_inf at exit |
||
| real(kind=pr), | intent(in) | :: | dx_norm |
||dX||_inf at exit |
||
| real(kind=pr), | intent(in) | :: | lambda |
LM lambda at exit |
||
| real(kind=pr), | intent(in) | :: | cond_est |
cond(J) at exit |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | n |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(newton_result), | intent(in) | :: | res |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=pr), | intent(in) | :: | J(:,:) |
Jacobian at x |
||
| real(kind=pr), | intent(in) | :: | F(:) |
Residual at x |
||
| real(kind=pr), | intent(inout) | :: | lambda |
LM damping (absolute) |
||
| real(kind=pr), | intent(in) | :: | jscale |
||J||_F^2/n |
||
| type(newton_settings), | intent(in) | :: | s |
Solver settings |
||
| real(kind=pr), | intent(out) | :: | dX(:) |
Computed Newton/LM step |
||
| real(kind=pr), | intent(out) | :: | cond_est |
cond(A) estimate |