dpchcs.f 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. *DECK DPCHCS
  2. SUBROUTINE DPCHCS (SWITCH, N, H, SLOPE, D, INCFD, IERR)
  3. C***BEGIN PROLOGUE DPCHCS
  4. C***SUBSIDIARY
  5. C***PURPOSE Adjusts derivative values for DPCHIC
  6. C***LIBRARY SLATEC (PCHIP)
  7. C***TYPE DOUBLE PRECISION (PCHCS-S, DPCHCS-D)
  8. C***AUTHOR Fritsch, F. N., (LLNL)
  9. C***DESCRIPTION
  10. C
  11. C DPCHCS: DPCHIC Monotonicity Switch Derivative Setter.
  12. C
  13. C Called by DPCHIC to adjust the values of D in the vicinity of a
  14. C switch in direction of monotonicity, to produce a more "visually
  15. C pleasing" curve than that given by DPCHIM .
  16. C
  17. C ----------------------------------------------------------------------
  18. C
  19. C Calling sequence:
  20. C
  21. C PARAMETER (INCFD = ...)
  22. C INTEGER N, IERR
  23. C DOUBLE PRECISION SWITCH, H(N), SLOPE(N), D(INCFD,N)
  24. C
  25. C CALL DPCHCS (SWITCH, N, H, SLOPE, D, INCFD, IERR)
  26. C
  27. C Parameters:
  28. C
  29. C SWITCH -- (input) indicates the amount of control desired over
  30. C local excursions from data.
  31. C
  32. C N -- (input) number of data points. (assumes N.GT.2 .)
  33. C
  34. C H -- (input) real*8 array of interval lengths.
  35. C SLOPE -- (input) real*8 array of data slopes.
  36. C If the data are (X(I),Y(I)), I=1(1)N, then these inputs are:
  37. C H(I) = X(I+1)-X(I),
  38. C SLOPE(I) = (Y(I+1)-Y(I))/H(I), I=1(1)N-1.
  39. C
  40. C D -- (input) real*8 array of derivative values at the data points,
  41. C as determined by DPCHCI.
  42. C (output) derivatives in the vicinity of switches in direction
  43. C of monotonicity may be adjusted to produce a more "visually
  44. C pleasing" curve.
  45. C The value corresponding to X(I) is stored in
  46. C D(1+(I-1)*INCFD), I=1(1)N.
  47. C No other entries in D are changed.
  48. C
  49. C INCFD -- (input) increment between successive values in D.
  50. C This argument is provided primarily for 2-D applications.
  51. C
  52. C IERR -- (output) error flag. should be zero.
  53. C If negative, trouble in DPCHSW. (should never happen.)
  54. C
  55. C -------
  56. C WARNING: This routine does no validity-checking of arguments.
  57. C -------
  58. C
  59. C Fortran intrinsics used: ABS, MAX, MIN.
  60. C
  61. C***SEE ALSO DPCHIC
  62. C***ROUTINES CALLED DPCHST, DPCHSW
  63. C***REVISION HISTORY (YYMMDD)
  64. C 820218 DATE WRITTEN
  65. C 820617 Redesigned to (1) fix problem with lack of continuity
  66. C approaching a flat-topped peak (2) be cleaner and
  67. C easier to verify.
  68. C Eliminated subroutines PCHSA and PCHSX in the process.
  69. C 820622 1. Limited fact to not exceed one, so computed D is a
  70. C convex combination of DPCHCI value and DPCHSD value.
  71. C 2. Changed fudge from 1 to 4 (based on experiments).
  72. C 820623 Moved PCHSD to an inline function (eliminating MSWTYP).
  73. C 820805 Converted to SLATEC library version.
  74. C 870707 Corrected conversion to double precision.
  75. C 870813 Minor cosmetic changes.
  76. C 890411 Added SAVE statements (Vers. 3.2).
  77. C 890531 Changed all specific intrinsics to generic. (WRB)
  78. C 890831 Modified array declarations. (WRB)
  79. C 891006 Modified spacing in computation of DFLOC. (WRB)
  80. C 891006 REVISION DATE from Version 3.2
  81. C 891214 Prologue converted to Version 4.0 format. (BAB)
  82. C 900328 Added TYPE section. (WRB)
  83. C 910408 Updated AUTHOR section in prologue. (WRB)
  84. C 930503 Improved purpose. (FNF)
  85. C***END PROLOGUE DPCHCS
  86. C
  87. C Programming notes:
  88. C 1. The function DPCHST(ARG1,ARG2) is assumed to return zero if
  89. C either argument is zero, +1 if they are of the same sign, and
  90. C -1 if they are of opposite sign.
  91. C**End
  92. C
  93. C DECLARE ARGUMENTS.
  94. C
  95. INTEGER N, INCFD, IERR
  96. DOUBLE PRECISION SWITCH, H(*), SLOPE(*), D(INCFD,*)
  97. C
  98. C DECLARE LOCAL VARIABLES.
  99. C
  100. INTEGER I, INDX, K, NLESS1
  101. DOUBLE PRECISION DEL(3), DEXT, DFLOC, DFMX, FACT, FUDGE, ONE,
  102. * SLMAX, WTAVE(2), ZERO
  103. SAVE ZERO, ONE, FUDGE
  104. DOUBLE PRECISION DPCHST
  105. C
  106. C DEFINE INLINE FUNCTION FOR WEIGHTED AVERAGE OF SLOPES.
  107. C
  108. DOUBLE PRECISION DPCHSD, S1, S2, H1, H2
  109. DPCHSD(S1,S2,H1,H2) = (H2/(H1+H2))*S1 + (H1/(H1+H2))*S2
  110. C
  111. C INITIALIZE.
  112. C
  113. DATA ZERO /0.D0/, ONE/1.D0/
  114. DATA FUDGE /4.D0/
  115. C***FIRST EXECUTABLE STATEMENT DPCHCS
  116. IERR = 0
  117. NLESS1 = N - 1
  118. C
  119. C LOOP OVER SEGMENTS.
  120. C
  121. DO 900 I = 2, NLESS1
  122. IF ( DPCHST(SLOPE(I-1),SLOPE(I)) ) 100, 300, 900
  123. C --------------------------
  124. C
  125. 100 CONTINUE
  126. C
  127. C....... SLOPE SWITCHES MONOTONICITY AT I-TH POINT .....................
  128. C
  129. C DO NOT CHANGE D IF 'UP-DOWN-UP'.
  130. IF (I .GT. 2) THEN
  131. IF ( DPCHST(SLOPE(I-2),SLOPE(I)) .GT. ZERO) GO TO 900
  132. C --------------------------
  133. ENDIF
  134. IF (I .LT. NLESS1) THEN
  135. IF ( DPCHST(SLOPE(I+1),SLOPE(I-1)) .GT. ZERO) GO TO 900
  136. C ----------------------------
  137. ENDIF
  138. C
  139. C ....... COMPUTE PROVISIONAL VALUE FOR D(1,I).
  140. C
  141. DEXT = DPCHSD (SLOPE(I-1), SLOPE(I), H(I-1), H(I))
  142. C
  143. C ....... DETERMINE WHICH INTERVAL CONTAINS THE EXTREMUM.
  144. C
  145. IF ( DPCHST(DEXT, SLOPE(I-1)) ) 200, 900, 250
  146. C -----------------------
  147. C
  148. 200 CONTINUE
  149. C DEXT AND SLOPE(I-1) HAVE OPPOSITE SIGNS --
  150. C EXTREMUM IS IN (X(I-1),X(I)).
  151. K = I-1
  152. C SET UP TO COMPUTE NEW VALUES FOR D(1,I-1) AND D(1,I).
  153. WTAVE(2) = DEXT
  154. IF (K .GT. 1)
  155. * WTAVE(1) = DPCHSD (SLOPE(K-1), SLOPE(K), H(K-1), H(K))
  156. GO TO 400
  157. C
  158. 250 CONTINUE
  159. C DEXT AND SLOPE(I) HAVE OPPOSITE SIGNS --
  160. C EXTREMUM IS IN (X(I),X(I+1)).
  161. K = I
  162. C SET UP TO COMPUTE NEW VALUES FOR D(1,I) AND D(1,I+1).
  163. WTAVE(1) = DEXT
  164. IF (K .LT. NLESS1)
  165. * WTAVE(2) = DPCHSD (SLOPE(K), SLOPE(K+1), H(K), H(K+1))
  166. GO TO 400
  167. C
  168. 300 CONTINUE
  169. C
  170. C....... AT LEAST ONE OF SLOPE(I-1) AND SLOPE(I) IS ZERO --
  171. C CHECK FOR FLAT-TOPPED PEAK .......................
  172. C
  173. IF (I .EQ. NLESS1) GO TO 900
  174. IF ( DPCHST(SLOPE(I-1), SLOPE(I+1)) .GE. ZERO) GO TO 900
  175. C -----------------------------
  176. C
  177. C WE HAVE FLAT-TOPPED PEAK ON (X(I),X(I+1)).
  178. K = I
  179. C SET UP TO COMPUTE NEW VALUES FOR D(1,I) AND D(1,I+1).
  180. WTAVE(1) = DPCHSD (SLOPE(K-1), SLOPE(K), H(K-1), H(K))
  181. WTAVE(2) = DPCHSD (SLOPE(K), SLOPE(K+1), H(K), H(K+1))
  182. C
  183. 400 CONTINUE
  184. C
  185. C....... AT THIS POINT WE HAVE DETERMINED THAT THERE WILL BE AN EXTREMUM
  186. C ON (X(K),X(K+1)), WHERE K=I OR I-1, AND HAVE SET ARRAY WTAVE--
  187. C WTAVE(1) IS A WEIGHTED AVERAGE OF SLOPE(K-1) AND SLOPE(K),
  188. C IF K.GT.1
  189. C WTAVE(2) IS A WEIGHTED AVERAGE OF SLOPE(K) AND SLOPE(K+1),
  190. C IF K.LT.N-1
  191. C
  192. SLMAX = ABS(SLOPE(K))
  193. IF (K .GT. 1) SLMAX = MAX( SLMAX, ABS(SLOPE(K-1)) )
  194. IF (K.LT.NLESS1) SLMAX = MAX( SLMAX, ABS(SLOPE(K+1)) )
  195. C
  196. IF (K .GT. 1) DEL(1) = SLOPE(K-1) / SLMAX
  197. DEL(2) = SLOPE(K) / SLMAX
  198. IF (K.LT.NLESS1) DEL(3) = SLOPE(K+1) / SLMAX
  199. C
  200. IF ((K.GT.1) .AND. (K.LT.NLESS1)) THEN
  201. C NORMAL CASE -- EXTREMUM IS NOT IN A BOUNDARY INTERVAL.
  202. FACT = FUDGE* ABS(DEL(3)*(DEL(1)-DEL(2))*(WTAVE(2)/SLMAX))
  203. D(1,K) = D(1,K) + MIN(FACT,ONE)*(WTAVE(1) - D(1,K))
  204. FACT = FUDGE* ABS(DEL(1)*(DEL(3)-DEL(2))*(WTAVE(1)/SLMAX))
  205. D(1,K+1) = D(1,K+1) + MIN(FACT,ONE)*(WTAVE(2) - D(1,K+1))
  206. ELSE
  207. C SPECIAL CASE K=1 (WHICH CAN OCCUR ONLY IF I=2) OR
  208. C K=NLESS1 (WHICH CAN OCCUR ONLY IF I=NLESS1).
  209. FACT = FUDGE* ABS(DEL(2))
  210. D(1,I) = MIN(FACT,ONE) * WTAVE(I-K+1)
  211. C NOTE THAT I-K+1 = 1 IF K=I (=NLESS1),
  212. C I-K+1 = 2 IF K=I-1(=1).
  213. ENDIF
  214. C
  215. C
  216. C....... ADJUST IF NECESSARY TO LIMIT EXCURSIONS FROM DATA.
  217. C
  218. IF (SWITCH .LE. ZERO) GO TO 900
  219. C
  220. DFLOC = H(K)*ABS(SLOPE(K))
  221. IF (K .GT. 1) DFLOC = MAX( DFLOC, H(K-1)*ABS(SLOPE(K-1)) )
  222. IF (K.LT.NLESS1) DFLOC = MAX( DFLOC, H(K+1)*ABS(SLOPE(K+1)) )
  223. DFMX = SWITCH*DFLOC
  224. INDX = I-K+1
  225. C INDX = 1 IF K=I, 2 IF K=I-1.
  226. C ---------------------------------------------------------------
  227. CALL DPCHSW(DFMX, INDX, D(1,K), D(1,K+1), H(K), SLOPE(K), IERR)
  228. C ---------------------------------------------------------------
  229. IF (IERR .NE. 0) RETURN
  230. C
  231. C....... END OF SEGMENT LOOP.
  232. C
  233. 900 CONTINUE
  234. C
  235. RETURN
  236. C------------- LAST LINE OF DPCHCS FOLLOWS -----------------------------
  237. END