nonlin 1.5.2
A library that provides routines to compute the solutions to systems of nonlinear equations.
Loading...
Searching...
No Matches
nonlin_least_squares::least_squares_solver Type Reference

Defines a Levenberg-Marquardt based solver for unconstrained least-squares problems. More...

Inheritance diagram for nonlin_least_squares::least_squares_solver:
nonlin_core::equation_solver

Public Member Functions

procedure, public get_step_scaling_factor (this)
 Gets a factor used to scale the bounds on the initial step.
 
procedure, public set_step_scaling_factor (this, x)
 Sets a factor used to scale the bounds on the initial step.
 
procedure, public solve (this, fcn, x, fvec, ib, err)
 Solves the system of equations.
 
- Public Member Functions inherited from nonlin_core::equation_solver
procedure, public get_max_fcn_evals es_get_max_eval
 Gets the maximum number of function evaluations allowed during a single solve.
 
procedure, public set_max_fcn_evals es_set_max_eval
 Sets the maximum number of function evaluations allowed during a single solve.
 
procedure, public get_fcn_tolerance es_get_fcn_tol
 Gets the convergence on function value tolerance.
 
procedure, public set_fcn_tolerance es_set_fcn_tol
 Sets the convergence on function value tolerance.
 
procedure, public get_var_tolerance es_get_var_tol
 Gets the convergence on change in variable tolerance.
 
procedure, public set_var_tolerance es_set_var_tol
 Sets the convergence on change in variable tolerance.
 
procedure, public get_gradient_tolerance es_get_grad_tol
 Gets the convergence on slope of the gradient vector tolerance.
 
procedure, public set_gradient_tolerance es_set_grad_tol
 Sets the convergence on slope of the gradient vector tolerance.
 
procedure, public get_print_status es_get_print_status
 Gets a logical value determining if iteration status should be printed.
 
procedure, public set_print_status es_set_print_status
 Sets a logical value determining if iteration status should be printed.
 
procedure(nonlin_solver), deferred, pass, public solve nonlin_solver
 Solves the system of equations.
 

Private Attributes

real(real64) m_factor = 100.0d0
 Initial step bounding factor.
 

Additional Inherited Members

- Public Attributes inherited from nonlin_core::equation_solver
real(real64) m_fcntol = 1.0d-8
 The convergence criteria on function values.
 
real(real64) m_xtol = 1.0d-12
 The convergence criteria on change in variable values.
 
real(real64) m_gtol = 1.0d-12
 The convergence criteria for the slope of the gradient vector.
 
logical m_printstatus = .false.
 Set to true to print iteration status; else, false.
 

Detailed Description

Defines a Levenberg-Marquardt based solver for unconstrained least-squares problems.

Definition at line 21 of file nonlin_least_squares.f90.

Member Function/Subroutine Documentation

◆ get_step_scaling_factor()

procedure, public nonlin_least_squares::least_squares_solver::get_step_scaling_factor ( class(least_squares_solver), intent(in) this)

Gets a factor used to scale the bounds on the initial step.

Parameters
[in]thisThe least_squares_solver object.
Returns
The factor.
Remarks
This factor is used to set the bounds on the initial step such that the initial step is bounded as the product of the factor with the Euclidean norm of the vector resulting from multiplication of the diagonal scaling matrix and the solution estimate. If zero, the factor itself is used.

Definition at line 27 of file nonlin_least_squares.f90.

◆ set_step_scaling_factor()

procedure, public nonlin_least_squares::least_squares_solver::set_step_scaling_factor ( class(least_squares_solver), intent(inout) this,
real(real64), intent(in) x )

Sets a factor used to scale the bounds on the initial step.

Parameters
[in]thisThe least_squares_solver object.
[in]xThe factor. Notice, the factor is limited to the interval [0.1, 100].
Remarks
This factor is used to set the bounds on the initial step such that the initial step is bounded as the product of the factor with the Euclidean norm of the vector resulting from multiplication of the diagonal scaling matrix and the solution estimate. If zero, the factor itself is used.

Definition at line 29 of file nonlin_least_squares.f90.

◆ solve()

procedure, public nonlin_least_squares::least_squares_solver::solve ( class(least_squares_solver), intent(inout) this,
class(vecfcn_helper), intent(in) fcn,
real(real64), dimension(:), intent(inout) x,
real(real64), dimension(:), intent(out) fvec,
type(iteration_behavior), optional ib,
class(errors), intent(inout), optional, target err )

Solves the system of equations.

Parameters
[in,out]thisThe least_squares_solver object.
[in]fcnThe vecfcn_helper object containing the equations to solve.
[in,out]xOn input, an M-element array containing an initial estimate to the solution. On output, the updated solution estimate. M is the number of variables.
[out]fvecAn N-element array that, on output, will contain the values of each equation as evaluated at the variable values given in x. N is the number of equations.
[out]ibAn optional output, that if provided, allows the caller to obtain iteration performance statistics.
[out]errAn optional errors-based object that if provided can be used to retrieve information relating to any errors encountered during execution. If not provided, a default implementation of the errors class is used internally to provide error handling. Possible errors and warning messages that may be encountered are as follows.
  • NL_INVALID_OPERATION_ERROR: Occurs if no equations have been defined.
  • NL_INVALID_INPUT_ERROR: Occurs if the number of equations is less than than the number of variables.
  • NL_ARRAY_SIZE_ERROR: Occurs if any of the input arrays are not sized correctly.
  • NL_CONVERGENCE_ERROR: Occurs if the line search cannot converge within the allowed number of iterations.
  • NL_OUT_OF_MEMORY_ERROR: Occurs if there is insufficient memory available.
  • NL_TOLERANCE_TOO_SMALL_ERROR: Occurs if the requested tolerance is to small to be practical for the problem at hand.
Remarks
This routines is based upon the MINPACK routine LMDIF.
Example 1
The following code provides an example of how to solve a system of N equations of N unknonwns using the Levenberg-Marquardt method.
program main
type(vecfcn_helper) :: obj
procedure(vecfcn), pointer :: fcn
type(least_squares_solver) :: solver
real(real64) :: x(2), f(2)
! Set the initial conditions to [1, 1]
x = 1.0d0
! Define the function
fcn => fcn1
call obj%set_fcn(fcn, 2, 2)
! Solve the system of equations. The solution overwrites X
call solver%solve(obj, x, f)
! Print the output and the residual:
print '(AF5.3AF5.3A)', "The solution: (", x(1), ", ", x(2), ")"
print '(AE8.3AE8.3A)', "The residual: (", f(1), ", ", f(2), ")"
contains
! System of Equations:
!
! x**2 + y**2 = 34
! x**2 - 2 * y**2 = 7
!
! Solution:
! x = +/-5
! y = +/-3
subroutine fcn1(x, f)
real(real64), intent(in), dimension(:) :: x
real(real64), intent(out), dimension(:) :: f
f(1) = x(1)**2 + x(2)**2 - 34.0d0
f(2) = x(1)**2 - 2.0d0 * x(2)**2 - 7.0d0
end subroutine
end program
Describes an M-element vector-valued function of N-variables.
nonlin_core
nonlin_least_squares
Defines a type capable of encapsulating a system of nonlinear equations of the form: F(X) = 0....
Defines a Levenberg-Marquardt based solver for unconstrained least-squares problems.
The above program returns the following results.
The solution: (5.000, 3.000)
The residual: (.000E+00, .000E+00)
Example 2
program example
implicit none
! Local Variables
type(vecfcn_helper) :: obj
procedure(vecfcn), pointer :: fcn
type(least_squares_solver) :: solver
real(real64) :: x(4), f(21) ! There are 4 coefficients and 21 data points
! Locate the routine containing the equations to solve
fcn => fcns
call obj%set_fcn(fcn, 21, 4)
! Define an initial guess
x = 1.0d0 ! Equivalent to x = [1.0d0, 1.0d0, 1.0d0, 1.0d0]
! Solve
call solver%solve(obj, x, f)
! Display the output
print "(AF12.8)", "c1: ", x(1)
print "(AF12.8)", "c2: ", x(2)
print "(AF12.8)", "c3: ", x(3)
print "(AF12.8)", "c4: ", x(4)
print "(AF9.5)", "Max Residual: ", maxval(abs(f))
contains
! The function containing the data to fit
subroutine fcns(x, f)
! Arguments
real(real64), intent(in), dimension(:) :: x ! Contains the coefficients
real(real64), intent(out), dimension(:) :: f
! Local Variables
real(real64), dimension(21) :: xp, yp
! Data to fit (21 data points)
xp = [0.0d0, 0.1d0, 0.2d0, 0.3d0, 0.4d0, 0.5d0, 0.6d0, 0.7d0, 0.8d0, &
0.9d0, 1.0d0, 1.1d0, 1.2d0, 1.3d0, 1.4d0, 1.5d0, 1.6d0, 1.7d0, &
1.8d0, 1.9d0, 2.0d0]
yp = [1.216737514d0, 1.250032542d0, 1.305579195d0, 1.040182335d0, &
1.751867738d0, 1.109716707d0, 2.018141531d0, 1.992418729d0, &
1.807916923d0, 2.078806005d0, 2.698801324d0, 2.644662712d0, &
3.412756702d0, 4.406137221d0, 4.567156645d0, 4.999550779d0, &
5.652854194d0, 6.784320119d0, 8.307936836d0, 8.395126494d0, &
10.30252404d0]
! We'll apply a cubic polynomial model to this data:
! y = c1 * x**3 + c2 * x**2 + c3 * x + c4
f = x(1) * xp**3 + x(2) * xp**2 + x(3) * xp + x(4) - yp
! For reference, the data was generated by adding random errors to
! the following polynomial: y = x**3 - 0.3 * x**2 + 1.2 * x + 0.3
end subroutine
end program
The above program returns the following results.
c1: 1.06476276
c2: -0.12232029
c3: 0.44661345
c4: 1.18661422
Max Residual: 0.50636
See Also

Definition at line 31 of file nonlin_least_squares.f90.

Member Data Documentation

◆ m_factor

real(real64) nonlin_least_squares::least_squares_solver::m_factor = 100.0d0
private

Initial step bounding factor.

Definition at line 24 of file nonlin_least_squares.f90.


The documentation for this type was generated from the following file: