7 module subroutine newt1var_solve(this, fcn, x, lim, f, ib, err)
9 class(newton_1var_solver),
intent(inout) :: this
10 class(fcn1var_helper),
intent(in) :: fcn
11 real(real64),
intent(inout) :: x
12 type(value_pair),
intent(in) :: lim
13 real(real64),
intent(out),
optional :: f
14 type(iteration_behavior),
optional :: ib
15 class(errors),
intent(inout),
optional,
target :: err
18 real(real64),
parameter :: zero = 0.0d0
19 real(real64),
parameter :: p5 = 0.5d0
20 real(real64),
parameter :: two = 2.0d0
23 logical :: fcnvrg, xcnvrg, dcnvrg
24 integer(int32) :: neval, ndiff, maxeval, flag, iter
25 real(real64) :: ftol, xtol, dtol, xh, xl, fh, fl, x1, x2, eps, dxold, &
27 class(errors),
pointer :: errmgr
28 type(errors),
target :: deferr
29 character(len = 256) :: errmsg
38 ftol = this%get_fcn_tolerance()
39 xtol = this%get_var_tolerance()
40 dtol = this%get_diff_tolerance()
41 maxeval = this%get_max_fcn_evals()
42 if (
present(f)) f = zero
46 ib%jacobian_count = ndiff
48 ib%converge_on_fcn = fcnvrg
49 ib%converge_on_chng = xcnvrg
50 ib%converge_on_zero_diff = dcnvrg
52 if (
present(err))
then
57 x1 = min(lim%x1, lim%x2)
58 x2 = max(lim%x1, lim%x2)
62 if (.not.fcn%is_fcn_defined())
then
64 call errmgr%report_error(
"brent_solve", &
65 "No function has been defined.", &
66 nl_invalid_operation_error)
69 if (abs(x1 - x2) < eps)
then
71 write(errmsg, 100)
"Search limits have no " // &
72 "appreciable difference between them. Lower Limit: ", x1, &
74 call errmgr%report_error(
"brent_solve", trim(errmsg), &
75 nl_invalid_operation_error)
84 if (abs(fl) < ftol)
then
86 if (
present(f)) f = fl
88 ib%converge_on_fcn = .true.
93 if (abs(fh) < ftol)
then
95 if (
present(f)) f = fh
97 ib%converge_on_fcn = .true.
124 if ((((x - xh) * df - ff) * ((x - xl) * df - ff) > zero) .or. &
125 (abs(two * ff) > abs(dxold * df))) &
131 if (abs(xl - x) < xtol)
then
142 if (abs(temp - x) < xtol)
then
156 if (abs(ff) < ftol)
then
160 if (abs(dx) < xtol)
then
164 if (abs(df) < dtol)
then
177 if (this%get_print_status())
then
178 call print_status(iter, neval, ndiff, dx, ff)
182 if (neval >= maxeval)
then
195 if (
present(f)) f = ff
196 if (
present(ib))
then
199 ib%jacobian_count = ndiff
200 ib%gradient_count = 0
201 ib%converge_on_fcn = fcnvrg
202 ib%converge_on_chng = xcnvrg
203 ib%converge_on_zero_diff = dcnvrg
208 write(errmsg, 101)
"The algorithm failed to " // &
209 "converge. Function evaluations performed: ", neval, &
210 "." // new_line(
'c') //
"Root estimate: ", x, &
211 new_line(
'c') //
"Residual: ", ff
212 call errmgr%report_error(
"newt1var_solve", trim(errmsg), &
213 nl_convergence_error)
217100
format(a, e10.3, a, e10.3)
218101
format(a, i0, a, e10.3, a, e10.3)