pchcs.f 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. *DECK PCHCS
  2. SUBROUTINE PCHCS (SWITCH, N, H, SLOPE, D, INCFD, IERR)
  3. C***BEGIN PROLOGUE PCHCS
  4. C***SUBSIDIARY
  5. C***PURPOSE Adjusts derivative values for PCHIC
  6. C***LIBRARY SLATEC (PCHIP)
  7. C***TYPE SINGLE PRECISION (PCHCS-S, DPCHCS-D)
  8. C***AUTHOR Fritsch, F. N., (LLNL)
  9. C***DESCRIPTION
  10. C
  11. C PCHCS: PCHIC Monotonicity Switch Derivative Setter.
  12. C
  13. C Called by PCHIC 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 PCHIM .
  16. C
  17. C ----------------------------------------------------------------------
  18. C
  19. C Calling sequence:
  20. C
  21. C PARAMETER (INCFD = ...)
  22. C INTEGER N, IERR
  23. C REAL SWITCH, H(N), SLOPE(N), D(INCFD,N)
  24. C
  25. C CALL PCHCS (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 array of interval lengths.
  35. C SLOPE -- (input) real 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 array of derivative values at the data points,
  41. C as determined by PCHCI.
  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 PCHSW. (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 PCHIC
  62. C***ROUTINES CALLED PCHST, PCHSW
  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 PCHCI value and PCHSD 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 870813 Minor cosmetic changes.
  75. C 890411 Added SAVE statements (Vers. 3.2).
  76. C 890531 Changed all specific intrinsics to generic. (WRB)
  77. C 890831 Modified array declarations. (WRB)
  78. C 890831 REVISION DATE from Version 3.2
  79. C 891214 Prologue converted to Version 4.0 format. (BAB)
  80. C 900328 Added TYPE section. (WRB)
  81. C 910408 Updated AUTHOR section in prologue. (WRB)
  82. C 930503 Improved purpose. (FNF)
  83. C***END PROLOGUE PCHCS
  84. C
  85. C Programming notes:
  86. C 1. The function PCHST(ARG1,ARG2) is assumed to return zero if
  87. C either argument is zero, +1 if they are of the same sign, and
  88. C -1 if they are of opposite sign.
  89. C**End
  90. C
  91. C DECLARE ARGUMENTS.
  92. C
  93. INTEGER N, INCFD, IERR
  94. REAL SWITCH, H(*), SLOPE(*), D(INCFD,*)
  95. C
  96. C DECLARE LOCAL VARIABLES.
  97. C
  98. INTEGER I, INDX, K, NLESS1
  99. REAL DEL(3), DEXT, DFLOC, DFMX, FACT, FUDGE, ONE, SLMAX,
  100. * WTAVE(2), ZERO
  101. SAVE ZERO, ONE, FUDGE
  102. REAL PCHST
  103. C
  104. C DEFINE INLINE FUNCTION FOR WEIGHTED AVERAGE OF SLOPES.
  105. C
  106. REAL PCHSD, S1, S2, H1, H2
  107. PCHSD(S1,S2,H1,H2) = (H2/(H1+H2))*S1 + (H1/(H1+H2))*S2
  108. C
  109. C INITIALIZE.
  110. C
  111. DATA ZERO /0./, ONE /1./
  112. DATA FUDGE /4./
  113. C***FIRST EXECUTABLE STATEMENT PCHCS
  114. IERR = 0
  115. NLESS1 = N - 1
  116. C
  117. C LOOP OVER SEGMENTS.
  118. C
  119. DO 900 I = 2, NLESS1
  120. IF ( PCHST(SLOPE(I-1),SLOPE(I)) ) 100, 300, 900
  121. C --------------------------
  122. C
  123. 100 CONTINUE
  124. C
  125. C....... SLOPE SWITCHES MONOTONICITY AT I-TH POINT .....................
  126. C
  127. C DO NOT CHANGE D IF 'UP-DOWN-UP'.
  128. IF (I .GT. 2) THEN
  129. IF ( PCHST(SLOPE(I-2),SLOPE(I)) .GT. ZERO) GO TO 900
  130. C --------------------------
  131. ENDIF
  132. IF (I .LT. NLESS1) THEN
  133. IF ( PCHST(SLOPE(I+1),SLOPE(I-1)) .GT. ZERO) GO TO 900
  134. C ----------------------------
  135. ENDIF
  136. C
  137. C ....... COMPUTE PROVISIONAL VALUE FOR D(1,I).
  138. C
  139. DEXT = PCHSD (SLOPE(I-1), SLOPE(I), H(I-1), H(I))
  140. C
  141. C ....... DETERMINE WHICH INTERVAL CONTAINS THE EXTREMUM.
  142. C
  143. IF ( PCHST(DEXT, SLOPE(I-1)) ) 200, 900, 250
  144. C -----------------------
  145. C
  146. 200 CONTINUE
  147. C DEXT AND SLOPE(I-1) HAVE OPPOSITE SIGNS --
  148. C EXTREMUM IS IN (X(I-1),X(I)).
  149. K = I-1
  150. C SET UP TO COMPUTE NEW VALUES FOR D(1,I-1) AND D(1,I).
  151. WTAVE(2) = DEXT
  152. IF (K .GT. 1)
  153. * WTAVE(1) = PCHSD (SLOPE(K-1), SLOPE(K), H(K-1), H(K))
  154. GO TO 400
  155. C
  156. 250 CONTINUE
  157. C DEXT AND SLOPE(I) HAVE OPPOSITE SIGNS --
  158. C EXTREMUM IS IN (X(I),X(I+1)).
  159. K = I
  160. C SET UP TO COMPUTE NEW VALUES FOR D(1,I) AND D(1,I+1).
  161. WTAVE(1) = DEXT
  162. IF (K .LT. NLESS1)
  163. * WTAVE(2) = PCHSD (SLOPE(K), SLOPE(K+1), H(K), H(K+1))
  164. GO TO 400
  165. C
  166. 300 CONTINUE
  167. C
  168. C....... AT LEAST ONE OF SLOPE(I-1) AND SLOPE(I) IS ZERO --
  169. C CHECK FOR FLAT-TOPPED PEAK .......................
  170. C
  171. IF (I .EQ. NLESS1) GO TO 900
  172. IF ( PCHST(SLOPE(I-1), SLOPE(I+1)) .GE. ZERO) GO TO 900
  173. C -----------------------------
  174. C
  175. C WE HAVE FLAT-TOPPED PEAK ON (X(I),X(I+1)).
  176. K = I
  177. C SET UP TO COMPUTE NEW VALUES FOR D(1,I) AND D(1,I+1).
  178. WTAVE(1) = PCHSD (SLOPE(K-1), SLOPE(K), H(K-1), H(K))
  179. WTAVE(2) = PCHSD (SLOPE(K), SLOPE(K+1), H(K), H(K+1))
  180. C
  181. 400 CONTINUE
  182. C
  183. C....... AT THIS POINT WE HAVE DETERMINED THAT THERE WILL BE AN EXTREMUM
  184. C ON (X(K),X(K+1)), WHERE K=I OR I-1, AND HAVE SET ARRAY WTAVE--
  185. C WTAVE(1) IS A WEIGHTED AVERAGE OF SLOPE(K-1) AND SLOPE(K),
  186. C IF K.GT.1
  187. C WTAVE(2) IS A WEIGHTED AVERAGE OF SLOPE(K) AND SLOPE(K+1),
  188. C IF K.LT.N-1
  189. C
  190. SLMAX = ABS(SLOPE(K))
  191. IF (K .GT. 1) SLMAX = MAX( SLMAX, ABS(SLOPE(K-1)) )
  192. IF (K.LT.NLESS1) SLMAX = MAX( SLMAX, ABS(SLOPE(K+1)) )
  193. C
  194. IF (K .GT. 1) DEL(1) = SLOPE(K-1) / SLMAX
  195. DEL(2) = SLOPE(K) / SLMAX
  196. IF (K.LT.NLESS1) DEL(3) = SLOPE(K+1) / SLMAX
  197. C
  198. IF ((K.GT.1) .AND. (K.LT.NLESS1)) THEN
  199. C NORMAL CASE -- EXTREMUM IS NOT IN A BOUNDARY INTERVAL.
  200. FACT = FUDGE* ABS(DEL(3)*(DEL(1)-DEL(2))*(WTAVE(2)/SLMAX))
  201. D(1,K) = D(1,K) + MIN(FACT,ONE)*(WTAVE(1) - D(1,K))
  202. FACT = FUDGE* ABS(DEL(1)*(DEL(3)-DEL(2))*(WTAVE(1)/SLMAX))
  203. D(1,K+1) = D(1,K+1) + MIN(FACT,ONE)*(WTAVE(2) - D(1,K+1))
  204. ELSE
  205. C SPECIAL CASE K=1 (WHICH CAN OCCUR ONLY IF I=2) OR
  206. C K=NLESS1 (WHICH CAN OCCUR ONLY IF I=NLESS1).
  207. FACT = FUDGE* ABS(DEL(2))
  208. D(1,I) = MIN(FACT,ONE) * WTAVE(I-K+1)
  209. C NOTE THAT I-K+1 = 1 IF K=I (=NLESS1),
  210. C I-K+1 = 2 IF K=I-1(=1).
  211. ENDIF
  212. C
  213. C
  214. C....... ADJUST IF NECESSARY TO LIMIT EXCURSIONS FROM DATA.
  215. C
  216. IF (SWITCH .LE. ZERO) GO TO 900
  217. C
  218. DFLOC = H(K)*ABS(SLOPE(K))
  219. IF (K .GT. 1) DFLOC = MAX( DFLOC, H(K-1)*ABS(SLOPE(K-1)) )
  220. IF (K.LT.NLESS1) DFLOC = MAX( DFLOC, H(K+1)*ABS(SLOPE(K+1)) )
  221. DFMX = SWITCH*DFLOC
  222. INDX = I-K+1
  223. C INDX = 1 IF K=I, 2 IF K=I-1.
  224. C ---------------------------------------------------------------
  225. CALL PCHSW (DFMX, INDX, D(1,K), D(1,K+1), H(K), SLOPE(K), IERR)
  226. C ---------------------------------------------------------------
  227. IF (IERR .NE. 0) RETURN
  228. C
  229. C....... END OF SEGMENT LOOP.
  230. C
  231. 900 CONTINUE
  232. C
  233. RETURN
  234. C------------- LAST LINE OF PCHCS FOLLOWS ------------------------------
  235. END