~ubuntu-branches/ubuntu/lucid/pdl/lucid

« back to all changes in this revision

Viewing changes to Lib/Slatec/slatec/dpchcs.f

  • Committer: Bazaar Package Importer
  • Author(s): Ben Gertzfield
  • Date: 2002-04-08 18:47:16 UTC
  • Revision ID: james.westby@ubuntu.com-20020408184716-0hf64dc96kin3htp
Tags: upstream-2.3.2
ImportĀ upstreamĀ versionĀ 2.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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