dpchce.f 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. *DECK DPCHCE
  2. SUBROUTINE DPCHCE (IC, VC, N, X, H, SLOPE, D, INCFD, IERR)
  3. C***BEGIN PROLOGUE DPCHCE
  4. C***SUBSIDIARY
  5. C***PURPOSE Set boundary conditions for DPCHIC
  6. C***LIBRARY SLATEC (PCHIP)
  7. C***TYPE DOUBLE PRECISION (PCHCE-S, DPCHCE-D)
  8. C***AUTHOR Fritsch, F. N., (LLNL)
  9. C***DESCRIPTION
  10. C
  11. C DPCHCE: DPCHIC End Derivative Setter.
  12. C
  13. C Called by DPCHIC to set end derivatives as requested by the user.
  14. C It must be called after interior derivative values have been set.
  15. C -----
  16. C
  17. C To facilitate two-dimensional applications, includes an increment
  18. C between successive values of the D-array.
  19. C
  20. C ----------------------------------------------------------------------
  21. C
  22. C Calling sequence:
  23. C
  24. C PARAMETER (INCFD = ...)
  25. C INTEGER IC(2), N, IERR
  26. C DOUBLE PRECISION VC(2), X(N), H(N), SLOPE(N), D(INCFD,N)
  27. C
  28. C CALL DPCHCE (IC, VC, N, X, H, SLOPE, D, INCFD, IERR)
  29. C
  30. C Parameters:
  31. C
  32. C IC -- (input) integer array of length 2 specifying desired
  33. C boundary conditions:
  34. C IC(1) = IBEG, desired condition at beginning of data.
  35. C IC(2) = IEND, desired condition at end of data.
  36. C ( see prologue to DPCHIC for details. )
  37. C
  38. C VC -- (input) real*8 array of length 2 specifying desired boundary
  39. C values. VC(1) need be set only if IC(1) = 2 or 3 .
  40. C VC(2) need be set only if IC(2) = 2 or 3 .
  41. C
  42. C N -- (input) number of data points. (assumes N.GE.2)
  43. C
  44. C X -- (input) real*8 array of independent variable values. (the
  45. C elements of X are assumed to be strictly increasing.)
  46. C
  47. C H -- (input) real*8 array of interval lengths.
  48. C SLOPE -- (input) real*8 array of data slopes.
  49. C If the data are (X(I),Y(I)), I=1(1)N, then these inputs are:
  50. C H(I) = X(I+1)-X(I),
  51. C SLOPE(I) = (Y(I+1)-Y(I))/H(I), I=1(1)N-1.
  52. C
  53. C D -- (input) real*8 array of derivative values at the data points.
  54. C The value corresponding to X(I) must be stored in
  55. C D(1+(I-1)*INCFD), I=1(1)N.
  56. C (output) the value of D at X(1) and/or X(N) is changed, if
  57. C necessary, to produce the requested boundary conditions.
  58. C no other entries in D are changed.
  59. C
  60. C INCFD -- (input) increment between successive values in D.
  61. C This argument is provided primarily for 2-D applications.
  62. C
  63. C IERR -- (output) error flag.
  64. C Normal return:
  65. C IERR = 0 (no errors).
  66. C Warning errors:
  67. C IERR = 1 if IBEG.LT.0 and D(1) had to be adjusted for
  68. C monotonicity.
  69. C IERR = 2 if IEND.LT.0 and D(1+(N-1)*INCFD) had to be
  70. C adjusted for monotonicity.
  71. C IERR = 3 if both of the above are true.
  72. C
  73. C -------
  74. C WARNING: This routine does no validity-checking of arguments.
  75. C -------
  76. C
  77. C Fortran intrinsics used: ABS.
  78. C
  79. C***SEE ALSO DPCHIC
  80. C***ROUTINES CALLED DPCHDF, DPCHST, XERMSG
  81. C***REVISION HISTORY (YYMMDD)
  82. C 820218 DATE WRITTEN
  83. C 820805 Converted to SLATEC library version.
  84. C 870707 Corrected XERROR calls for d.p. name(s).
  85. C 890206 Corrected XERROR calls.
  86. C 890411 Added SAVE statements (Vers. 3.2).
  87. C 890531 Changed all specific intrinsics to generic. (WRB)
  88. C 890831 Modified array declarations. (WRB)
  89. C 890831 REVISION DATE from Version 3.2
  90. C 891214 Prologue converted to Version 4.0 format. (BAB)
  91. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  92. C 900328 Added TYPE section. (WRB)
  93. C 910408 Updated AUTHOR section in prologue. (WRB)
  94. C 930503 Improved purpose. (FNF)
  95. C***END PROLOGUE DPCHCE
  96. C
  97. C Programming notes:
  98. C 1. The function DPCHST(ARG1,ARG2) is assumed to return zero if
  99. C either argument is zero, +1 if they are of the same sign, and
  100. C -1 if they are of opposite sign.
  101. C 2. One could reduce the number of arguments and amount of local
  102. C storage, at the expense of reduced code clarity, by passing in
  103. C the array WK (rather than splitting it into H and SLOPE) and
  104. C increasing its length enough to incorporate STEMP and XTEMP.
  105. C 3. The two monotonicity checks only use the sufficient conditions.
  106. C Thus, it is possible (but unlikely) for a boundary condition to
  107. C be changed, even though the original interpolant was monotonic.
  108. C (At least the result is a continuous function of the data.)
  109. C**End
  110. C
  111. C DECLARE ARGUMENTS.
  112. C
  113. INTEGER IC(2), N, INCFD, IERR
  114. DOUBLE PRECISION VC(2), X(*), H(*), SLOPE(*), D(INCFD,*)
  115. C
  116. C DECLARE LOCAL VARIABLES.
  117. C
  118. INTEGER IBEG, IEND, IERF, INDEX, J, K
  119. DOUBLE PRECISION HALF, STEMP(3), THREE, TWO, XTEMP(4), ZERO
  120. SAVE ZERO, HALF, TWO, THREE
  121. DOUBLE PRECISION DPCHDF, DPCHST
  122. C
  123. C INITIALIZE.
  124. C
  125. DATA ZERO /0.D0/, HALF/.5D0/, TWO/2.D0/, THREE/3.D0/
  126. C
  127. C***FIRST EXECUTABLE STATEMENT DPCHCE
  128. IBEG = IC(1)
  129. IEND = IC(2)
  130. IERR = 0
  131. C
  132. C SET TO DEFAULT BOUNDARY CONDITIONS IF N IS TOO SMALL.
  133. C
  134. IF ( ABS(IBEG).GT.N ) IBEG = 0
  135. IF ( ABS(IEND).GT.N ) IEND = 0
  136. C
  137. C TREAT BEGINNING BOUNDARY CONDITION.
  138. C
  139. IF (IBEG .EQ. 0) GO TO 2000
  140. K = ABS(IBEG)
  141. IF (K .EQ. 1) THEN
  142. C BOUNDARY VALUE PROVIDED.
  143. D(1,1) = VC(1)
  144. ELSE IF (K .EQ. 2) THEN
  145. C BOUNDARY SECOND DERIVATIVE PROVIDED.
  146. D(1,1) = HALF*( (THREE*SLOPE(1) - D(1,2)) - HALF*VC(1)*H(1) )
  147. ELSE IF (K .LT. 5) THEN
  148. C USE K-POINT DERIVATIVE FORMULA.
  149. C PICK UP FIRST K POINTS, IN REVERSE ORDER.
  150. DO 10 J = 1, K
  151. INDEX = K-J+1
  152. C INDEX RUNS FROM K DOWN TO 1.
  153. XTEMP(J) = X(INDEX)
  154. IF (J .LT. K) STEMP(J) = SLOPE(INDEX-1)
  155. 10 CONTINUE
  156. C -----------------------------
  157. D(1,1) = DPCHDF (K, XTEMP, STEMP, IERF)
  158. C -----------------------------
  159. IF (IERF .NE. 0) GO TO 5001
  160. ELSE
  161. C USE 'NOT A KNOT' CONDITION.
  162. D(1,1) = ( THREE*(H(1)*SLOPE(2) + H(2)*SLOPE(1))
  163. * - TWO*(H(1)+H(2))*D(1,2) - H(1)*D(1,3) ) / H(2)
  164. ENDIF
  165. C
  166. IF (IBEG .GT. 0) GO TO 2000
  167. C
  168. C CHECK D(1,1) FOR COMPATIBILITY WITH MONOTONICITY.
  169. C
  170. IF (SLOPE(1) .EQ. ZERO) THEN
  171. IF (D(1,1) .NE. ZERO) THEN
  172. D(1,1) = ZERO
  173. IERR = IERR + 1
  174. ENDIF
  175. ELSE IF ( DPCHST(D(1,1),SLOPE(1)) .LT. ZERO) THEN
  176. D(1,1) = ZERO
  177. IERR = IERR + 1
  178. ELSE IF ( ABS(D(1,1)) .GT. THREE*ABS(SLOPE(1)) ) THEN
  179. D(1,1) = THREE*SLOPE(1)
  180. IERR = IERR + 1
  181. ENDIF
  182. C
  183. C TREAT END BOUNDARY CONDITION.
  184. C
  185. 2000 CONTINUE
  186. IF (IEND .EQ. 0) GO TO 5000
  187. K = ABS(IEND)
  188. IF (K .EQ. 1) THEN
  189. C BOUNDARY VALUE PROVIDED.
  190. D(1,N) = VC(2)
  191. ELSE IF (K .EQ. 2) THEN
  192. C BOUNDARY SECOND DERIVATIVE PROVIDED.
  193. D(1,N) = HALF*( (THREE*SLOPE(N-1) - D(1,N-1)) +
  194. * HALF*VC(2)*H(N-1) )
  195. ELSE IF (K .LT. 5) THEN
  196. C USE K-POINT DERIVATIVE FORMULA.
  197. C PICK UP LAST K POINTS.
  198. DO 2010 J = 1, K
  199. INDEX = N-K+J
  200. C INDEX RUNS FROM N+1-K UP TO N.
  201. XTEMP(J) = X(INDEX)
  202. IF (J .LT. K) STEMP(J) = SLOPE(INDEX)
  203. 2010 CONTINUE
  204. C -----------------------------
  205. D(1,N) = DPCHDF (K, XTEMP, STEMP, IERF)
  206. C -----------------------------
  207. IF (IERF .NE. 0) GO TO 5001
  208. ELSE
  209. C USE 'NOT A KNOT' CONDITION.
  210. D(1,N) = ( THREE*(H(N-1)*SLOPE(N-2) + H(N-2)*SLOPE(N-1))
  211. * - TWO*(H(N-1)+H(N-2))*D(1,N-1) - H(N-1)*D(1,N-2) )
  212. * / H(N-2)
  213. ENDIF
  214. C
  215. IF (IEND .GT. 0) GO TO 5000
  216. C
  217. C CHECK D(1,N) FOR COMPATIBILITY WITH MONOTONICITY.
  218. C
  219. IF (SLOPE(N-1) .EQ. ZERO) THEN
  220. IF (D(1,N) .NE. ZERO) THEN
  221. D(1,N) = ZERO
  222. IERR = IERR + 2
  223. ENDIF
  224. ELSE IF ( DPCHST(D(1,N),SLOPE(N-1)) .LT. ZERO) THEN
  225. D(1,N) = ZERO
  226. IERR = IERR + 2
  227. ELSE IF ( ABS(D(1,N)) .GT. THREE*ABS(SLOPE(N-1)) ) THEN
  228. D(1,N) = THREE*SLOPE(N-1)
  229. IERR = IERR + 2
  230. ENDIF
  231. C
  232. C NORMAL RETURN.
  233. C
  234. 5000 CONTINUE
  235. RETURN
  236. C
  237. C ERROR RETURN.
  238. C
  239. 5001 CONTINUE
  240. C ERROR RETURN FROM DPCHDF.
  241. C *** THIS CASE SHOULD NEVER OCCUR ***
  242. IERR = -1
  243. CALL XERMSG ('SLATEC', 'DPCHCE', 'ERROR RETURN FROM DPCHDF',
  244. + IERR, 1)
  245. RETURN
  246. C------------- LAST LINE OF DPCHCE FOLLOWS -----------------------------
  247. END