Compute noise and number of good digits in function results.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
procedure(fcn_t) | :: | fcn |
User-supplied subroutine for evaluating the model. |
|||
integer, | intent(in) | :: | n |
Number of observations. |
||
integer, | intent(in) | :: | m |
Number of columns of data in the explanatory variable. |
||
integer, | intent(in) | :: | np |
Number of function parameters. |
||
integer, | intent(in) | :: | q |
Number of responses per observation. |
||
real(kind=wp), | intent(in) | :: | xplusd(n,m) |
Values of |
||
real(kind=wp), | intent(in) | :: | beta(np) |
Function parameters. |
||
real(kind=wp), | intent(in) | :: | epsmac |
Value of machine precision. |
||
integer, | intent(in) | :: | nrow |
Row number at which the derivative is to be checked. |
||
real(kind=wp), | intent(out) | :: | partmp(np) |
Model parameters. |
||
real(kind=wp), | intent(in) | :: | pv0(n,q) |
Original predicted values. |
||
integer, | intent(in) | :: | ifixb(np) |
Values designating whether the elements of |
||
integer, | intent(in) | :: | ifixx(ldifx,m) |
Values designating whether the elements of |
||
integer, | intent(in) | :: | ldifx |
Leading dimension of array |
||
integer, | intent(out) | :: | istop |
Variable designating whether there are problems computing the function at the
current |
||
integer, | intent(inout) | :: | nfev |
Number of function evaluations. |
||
real(kind=wp), | intent(out) | :: | eta |
Noise in the model results. |
||
integer, | intent(out) | :: | neta |
Number of accurate digits in the model results. |
||
real(kind=wp), | intent(out) | :: | fjacd(n,m,q) |
Jacobian wrt |
||
real(kind=wp), | intent(out) | :: | f(n,q) |
Function values. |
||
real(kind=wp), | intent(out) | :: | fjacb(n,np,q) |
Jacobian wrt |
||
real(kind=wp), | intent(out) | :: | wrk7(-2:2,q) |
Work array of |
||
integer, | intent(out) | :: | info |
Variable indicating the status of the computation. |
||
real(kind=wp), | intent(in) | :: | lower(np) |
Lower bound of |
||
real(kind=wp), | intent(in) | :: | upper(np) |
Upper bound of |
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
real(kind=wp), | public, | parameter | :: | p1 | = | 0.1_wp | |
real(kind=wp), | public, | parameter | :: | p2 | = | 0.2_wp | |
real(kind=wp), | public, | parameter | :: | p5 | = | 0.5_wp | |
real(kind=wp), | public | :: | a | ||||
real(kind=wp), | public | :: | b | ||||
real(kind=wp), | public | :: | fac | ||||
real(kind=wp), | public | :: | shift | ||||
real(kind=wp), | public | :: | stp | ||||
integer, | public | :: | j | ||||
integer, | public | :: | k | ||||
integer, | public | :: | sbk | ||||
real(kind=wp), | public | :: | parpts(-2:2,np) |
subroutine eta_fcn & (fcn, & n, m, np, q, & xplusd, beta, epsmac, nrow, & partmp, pv0, & ifixb, ifixx, ldifx, & istop, nfev, eta, neta, & fjacd, f, fjacb, wrk7, & info, & lower, upper) !! Compute noise and number of good digits in function results. ! Adapted from STARPAC subroutine ETAFUN. use odrpack_kinds, only: zero, one, two procedure(fcn_t) :: fcn !! User-supplied subroutine for evaluating the model. integer, intent(in) :: n !! Number of observations. integer, intent(in) :: m !! Number of columns of data in the explanatory variable. integer, intent(in) :: np !! Number of function parameters. integer, intent(in) :: q !! Number of responses per observation. real(wp), intent(in) :: xplusd(n, m) !! Values of `x + delta`. real(wp), intent(in) :: beta(np) !! Function parameters. real(wp), intent(in) :: epsmac !! Value of machine precision. integer, intent(in) :: nrow !! Row number at which the derivative is to be checked. real(wp), intent(out) :: partmp(np) !! Model parameters. real(wp), intent(in) :: pv0(n, q) !! Original predicted values. integer, intent(in) :: ifixb(np) !! Values designating whether the elements of `beta` are fixed at their input values or not. integer, intent(in) :: ifixx(ldifx, m) !! Values designating whether the elements of `x` are fixed at their input values or not. integer, intent(in) :: ldifx !! Leading dimension of array `ifixx`. integer, intent(out) :: istop !! Variable designating whether there are problems computing the function at the !! current `beta` and `delta`. integer, intent(inout) :: nfev !! Number of function evaluations. real(wp), intent(out) :: eta !! Noise in the model results. integer, intent(out) :: neta !! Number of accurate digits in the model results. real(wp), intent(out) :: fjacd(n, m, q) !! Jacobian wrt `delta`. real(wp), intent(out) :: f(n, q) !! Function values. real(wp), intent(out) :: fjacb(n, np, q) !! Jacobian wrt `beta`. real(wp), intent(out) :: wrk7(-2:2, q) !! Work array of `(5, q)` elements. integer, intent(out) :: info !! Variable indicating the status of the computation. real(wp), intent(in) :: lower(np) !! Lower bound of `beta`. real(wp), intent(in) :: upper(np) !! Upper bound of `beta`. ! Local scalars real(wp), parameter :: p1 = 0.1_wp, p2 = 0.2_wp, p5 = 0.5_wp real(wp) :: a, b, fac, shift, stp integer :: j, k, sbk ! Local arrays real(wp) :: parpts(-2:2, np) ! Variable Definitions (ALPHABETICALLY) ! A: Parameters of the local fit. ! B: Parameters of the local fit. ! FAC: A factor used in the computations. ! J: An index variable. ! K: An index variable. ! SHIFT: When PARPTS cross the parameter bounds they are shifted by SHIFT. ! SBK: The sign of BETA(K). ! STP: A small value used to perturb the parameters. stp = 100*epsmac eta = epsmac ! Create points to use in calculating FCN for ETA and NETA do j = -2, 2 if (j == 0) then parpts(0, :) = beta else do k = 1, np if (ifixb(1) < 0) then parpts(j, k) = beta(k) + j*stp*beta(k) elseif (ifixb(k) /= 0) then parpts(j, k) = beta(k) + j*stp*beta(k) else parpts(j, k) = beta(k) end if end do end if end do ! Adjust the points used in calculating FCN to uphold the boundary constraints do k = 1, np sbk = int(sign(one, parpts(2, k) - parpts(-2, k))) if (parpts(sbk*2, k) > upper(k)) then shift = upper(k) - parpts(sbk*2, k) parpts(sbk*2, k) = upper(k) do j = -sbk*2, sbk*1, sbk parpts(j, k) = parpts(j, k) + shift end do if (parpts(-sbk*2, k) < lower(k)) then info = 90010 return end if end if if (parpts(-sbk*2, k) < lower(k)) then shift = lower(k) - parpts(-sbk*2, k) parpts(-sbk*2, k) = lower(k) do j = -sbk*1, sbk*2, sbk parpts(j, k) = parpts(j, k) + shift end do if (parpts(sbk*2, k) > upper(k)) then info = 90010 return end if end if end do ! Evaluate FCN for all points in PARPTS do j = -2, 2 if (all(parpts(j, :) == beta)) then wrk7(j, :) = pv0(nrow, :) else partmp = parpts(j, :) istop = 0 call fcn(partmp, xplusd, ifixb, ifixx, 003, f, fjacb, fjacd, istop) if (istop /= 0) then return else nfev = nfev + 1 end if wrk7(j, :) = f(nrow, :) end if end do ! Calculate ETA and NETA do k = 1, q a = zero b = zero do j = -2, 2 a = a + wrk7(j, k) b = b + j*wrk7(j, k) end do a = p2*a b = p1*b if ((wrk7(0, k) /= zero) .and. (abs(wrk7(1, k) + wrk7(-1, k)) > 100*epsmac)) then fac = 1/abs(wrk7(0, k)) else fac = one end if do j = -2, 2 wrk7(j, k) = abs((wrk7(j, k) - (a + j*b))*fac) eta = max(wrk7(j, k), eta) end do end do neta = int(max(two, p5 - log10(eta))) end subroutine eta_fcn