Check a single cubic for monotonicity
Called by dpchcm to determine the monotonicity properties of the cubic with boundary derivative values D1,D2 and chord slope DELTA.
This is essentially the same as old DCHFMC
, except that a
new output value, -3, was added February 1989. (Formerly, -3
and +3 were lumped together in the single value 3.) Codes that
flag nonmonotonicity by "IF (ISMON==2)" need not be changed.
Codes that check via "IF (ISMON>=3)" should change the test to
"IF (IABS(ISMON)>=3)". Codes that declare monotonicity via
"IF (ISMON<=1)" should change to "IF (IABS(ISMON)<=1)".
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in) | :: | d1 |
derivative value at the end of an interval. |
||
real(kind=wp), | intent(in) | :: | d2 |
derivative value at the end of an interval. |
||
real(kind=wp), | intent(in) | :: | delta |
the data slope over that interval |
indicates the monotonicity of the cubic segment:
If ABS(ISMON)=3, the derivative values are too close to the boundary of the monotonicity region to declare monotonicity in the presence of roundoff error.
function dchfcm (d1, d2, delta) result(ismon) real(wp),intent(in) :: d1 !! derivative value at the end of an interval. real(wp),intent(in) :: d2 !! derivative value at the end of an interval. real(wp),intent(in) :: delta !! the data slope over that interval integer :: ismon !! indicates the monotonicity of the cubic segment: !! !! * ISMON = -3 if function is probably decreasing !! * ISMON = -1 if function is strictly decreasing !! * ISMON = 0 if function is constant !! * ISMON = 1 if function is strictly increasing !! * ISMON = 2 if function is non-monotonic !! * ISMON = 3 if function is probably increasing !! !! If ABS(ISMON)=3, the derivative values are too close to the !! boundary of the monotonicity region to declare monotonicity !! in the presence of roundoff error. integer :: itrue real(wp) :: a, b, phi real(wp),parameter :: eps = ten*d1mach4 !! machine-dependent parameter -- should be about 10*uround. !! TEN is actually a tuning parameter, which determines the !! width of the fuzz around the elliptical boundary. if (delta == zero) then ! case of constant data. if ((d1==zero) .and. (d2==zero)) then ismon = 0 else ismon = 2 endif else ! data is not constant -- pick up sign. itrue = int(sign (one, delta)) a = d1/delta b = d2/delta if ((a<zero) .or. (b<zero)) then ismon = 2 else if ((a<=three-eps) .and. (b<=three-eps)) then ! inside square (0,3)x(0,3) implies ok. ismon = itrue else if ((a>four+eps) .and. (b>four+eps)) then ! outside square (0,4)x(0,4) implies nonmonotonic. ismon = 2 else ! must check against boundary of ellipse. a = a - two b = b - two phi = ((a*a + b*b) + a*b) - three if (phi < -eps) then ismon = itrue else if (phi > eps) then ismon = 2 else ! to close to boundary to tell, ! in the presence of round-off errors. ismon = 3*itrue endif endif endif end function dchfcm