gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
tautsp.f
Go to the documentation of this file.
1  subroutine tautsp ( tau, gtau, ntau, gamma, s,
2  & break, coef, l, k, iflag )
3 
4 c*********************************************************************72
5 c
6 cc TAUTSP constructs a cubic spline interpolant to given data.
7 c
8 c from * a practical guide to splines * by c. de boor
9 constructs cubic spline interpolant to given data
10 c tau(i), gtau(i), i=1,...,ntau.
11 c if gamma .gt. 0., additional knots are introduced where needed to
12 c make the interpolant more flexible locally. this avoids extraneous
13 c inflection points typical of cubic spline interpolation at knots to
14 c rapidly changing data.
15 c
16 c parameters
17 c input
18 c tau sequence of data points. must be strictly increasing.
19 c gtau corresponding sequence of function values.
20 c ntau number of data points. must be at least 4 .
21 c gamma indicates whether additional flexibility is desired.
22 c = 0., no additional knots
23 c in (0.,3.), under certain conditions on the given data at
24 c points i-1, i, i+1, and i+2, a knot is added in the
25 c i-th interval, i=2,...,ntau-2. see description of meth-
26 c od below. the interpolant gets rounded with increasing
27 c gamma. a value of 2.5 for gamma is typical.
28 c in (3.,6.), same , except that knots might also be added in
29 c intervals in which an inflection point would be permit-
30 c ted. a value of 5.5 for gamma is typical.
31 c output
32 c break, coef, l, k give the pp-representation of the interpolant.
33 c specifically, for break(i) .le. x .le. break(i+1), the
34 c interpolant has the form
35 c f(x) = coef(1,i) +dx(coef(2,i) +(dx/2)(coef(3,i) +(dx/3)coef(4,i)))
36 c with dx = x - break(i) and i=1,...,l .
37 c iflag = 1, ok
38 c = 2, input was incorrect. a printout specifying the mistake
39 c was made.
40 c workspace
41 c s is required, of size (ntau,6). the individual columns of this
42 c array contain the following quantities mentioned in the write-
43 c up and below.
44 c s(.,1) = dtau = tau(.+1) - tau
45 c s(.,2) = diag = diagonal in linear system
46 c s(.,3) = u = upper diagonal in linear system
47 c s(.,4) = r = right side for linear system (initially)
48 c = fsecnd = solution of linear system , namely the second
49 c derivatives of interpolant at tau
50 c s(.,5) = z = indicator of additional knots
51 c s(.,6) = 1/hsecnd(1,x) with x = z or = 1-z. see below.
52 c
53 c ------ m e t h o d ------
54 c on the i-th interval, (tau(i), tau(i+1)), the interpolant is of the
55 c form
56 c (*) f(u(x)) = a + b*u + c*h(u,z) + d*h(1-u,1-z) ,
57 c with u = u(x) = (x - tau(i))/dtau(i). here,
58 c z = z(i) = addg(i+1)/(addg(i) + addg(i+1))
59 c (= .5, in case the denominator vanishes). with
60 c addg(j) = abs(ddg(j)), ddg(j) = dg(j+1) - dg(j),
61 c dg(j) = divdif(j) = (gtau(j+1) - gtau(j))/dtau(j)
62 c and
63 c h(u,z) = alpha*u**3 + (1 - alpha)*(max(((u-zeta)/(1-zeta)),0)**3
64 c with
65 c alpha(z) = (1-gamma/3)/zeta
66 c zeta(z) = 1 - gamma*min((1 - z), 1/3)
67 c thus, for 1/3 .le. z .le. 2/3, f is just a cubic polynomial on
68 c the interval i. otherwise, it has one additional knot, at
69 c tau(i) + zeta*dtau(i) .
70 c as z approaches 1, h(.,z) has an increasingly sharp bend near 1,
71 c thus allowing f to turn rapidly near the additional knot.
72 c in terms of f(j) = gtau(j) and
73 c fsecnd(j) = 2.derivative of f at tau(j),
74 c the coefficients for (*) are given as
75 c a = f(i) - d
76 c b = (f(i+1) - f(i)) - (c - d)
77 c c = fsecnd(i+1)*dtau(i)**2/hsecnd(1,z)
78 c d = fsecnd(i)*dtau(i)**2/hsecnd(1,1-z)
79 c hence can be computed once fsecnd(i),i=1,...,ntau, is fixed.
80 c f is automatically continuous and has a continuous second derivat-
81 c ive (except when z = 0 or 1 for some i). we determine fscnd(.) from
82 c the requirement that also the first derivative of f be contin-
83 c uous. in addition, we require that the third derivative be continuous
84 c across tau(2) and across tau(ntau-1) . this leads to a strictly
85 c diagonally dominant tridiagonal linear system for the fsecnd(i)
86 c which we solve by gauss elimination without pivoting.
87 c
88  implicit none
89 
90  integer iflag,k,l,ntau, i,method,ntaum1
91  double precision alph,break(1),coef(4,1),gamma,
92  & gtau(ntau),s(ntau,6),tau(ntau)
93  & ,alpha,c,d,del,denom,divdif,entry,entry3,factor,factr2,gam
94  & ,onemg3,onemzt,ratio,sixth,temp,x,z,zeta,zt2
95  alph(x) = dmin1(1.0d+00,onemg3/x)
96 c
97 c there must be at least 4 interpolation points.
98  if (ntau .ge. 4) go to 5
99  print 600,ntau
100  600 format(8h ntau = ,i4,20h. should be .ge. 4 .)
101  go to 999
102 c
103 construct delta tau and first and second (divided) differences of data
104 c
105  5 ntaum1 = ntau - 1
106  do 6 i=1,ntaum1
107  s(i,1) = tau(i+1) - tau(i)
108  if (s(i,1) .gt. 0.0d+00) go to 6
109  print 610,i,tau(i),tau(i+1)
110  610 format(7h point ,i3,13h and the next,2e15.6,15h are disordered)
111  go to 999
112  6 s(i+1,4) = (gtau(i+1)-gtau(i))/s(i,1)
113  do 7 i=2,ntaum1
114  7 s(i,4) = s(i+1,4) - s(i,4)
115 c
116 construct system of equations for second derivatives at tau. at each
117 c interior data point, there is one continuity equation, at the first
118 c and the last interior data point there is an additional one for a
119 c total of ntau equations in ntau unknowns.
120 c
121  i = 2
122  s(2,2) = s(1,1)/3.0d+00
123  sixth = 1.0d+00/6.0d+00
124  method = 2
125  gam = gamma
126  if (gam .le. 0.0d+00) method = 1
127  if ( gam .le. 3.0d+00) go to 9
128  method = 3
129  gam = gam - 3.0d+00
130  9 onemg3 = 1.0d+00 - gam/3.0d+00
131 c ------ loop over i ------
132  10 continue
133 c construct z(i) and zeta(i)
134  z = 0.5d+00
135  go to (19,11,12),method
136  11 if (s(i,4)*s(i+1,4) .lt. 0.0d+00) go to 19
137  12 temp = dabs(s(i+1,4))
138  denom = dabs(s(i,4)) + temp
139  if (denom .eq. 0.0d+00) go to 19
140  z = temp/denom
141  if (dabs(z - 0.5d+00) .le. sixth) z = 0.5d+00
142  19 s(i,5) = z
143 c ******set up part of the i-th equation which depends on
144 c the i-th interval
145  if (z - 0.5d+00) 21,22,23
146  21 zeta = gam*z
147  onemzt = 1.0d+00 - zeta
148  zt2 = zeta**2
149  alpha = alph(onemzt)
150  factor = zeta/(alpha*(zt2-1.0d+00) + 1.0d+00)
151  s(i,6) = zeta*factor/6.0d+00
152  s(i,2) = s(i,2) + s(i,1)
153  & *((1.0d+00-alpha*onemzt)*factor/2.0d+00 - s(i,6))
154 c if z = 0 and the previous z = 1, then d(i) = 0. since then
155 c also u(i-1) = l(i+1) = 0, its value does not matter. reset
156 c d(i) = 1 to insure nonzero pivot in elimination.
157  if (s(i,2) .le. 0.0d+00) s(i,2) = 1.0d+00
158  s(i,3) = s(i,1)/6.0d+00
159  go to 25
160  22 s(i,2) = s(i,2) + s(i,1)/3.0d+00
161  s(i,3) = s(i,1)/6.0d+00
162  go to 25
163  23 onemzt = gam*(1.0d+00 - z)
164  zeta = 1.0d+00 - onemzt
165  alpha = alph(zeta)
166  factor = onemzt/(1.0d+00 - alpha*zeta*(1.0d+00+onemzt))
167  s(i,6) = onemzt*factor/6.0d+00
168  s(i,2) = s(i,2) + s(i,1)/3.
169  s(i,3) = s(i,6)*s(i,1)
170  25 if (i .gt. 2) go to 30
171  s(1,5) = 0.5d+00
172 c ******the first two equations enforce continuity of the first and of
173 c the third derivative across tau(2).
174  s(1,2) = s(1,1)/6.0d+00
175  s(1,3) = s(2,2)
176  entry3 = s(2,3)
177  if (z - 0.5d+00) 26,27,28
178  26 factr2 = zeta*(alpha*(zt2-1.0d+00)
179  & + 1.0d+00)/(alpha*(zeta*zt2-1.0d+00)+1.0d+00)
180  ratio = factr2*s(2,1)/s(1,2)
181  s(2,2) = factr2*s(2,1) + s(1,1)
182  s(2,3) = -factr2*s(1,1)
183  go to 29
184  27 ratio = s(2,1)/s(1,2)
185  s(2,2) = s(2,1) + s(1,1)
186  s(2,3) = -s(1,1)
187  go to 29
188  28 ratio = s(2,1)/s(1,2)
189  s(2,2) = s(2,1) + s(1,1)
190  s(2,3) = -s(1,1)*6.0d+00*alpha*s(2,6)
191 c at this point, the first two equations read
192 c diag(1)*x1 + u(1)*x2 + entry3*x3 = r(2)
193 c -ratio*diag(1)*x1 + diag(2)*x2 + u(2)*x3 = 0.0D+00
194 c eliminate first unknown from second equation
195  29 s(2,2) = ratio*s(1,3) + s(2,2)
196  s(2,3) = ratio*entry3 + s(2,3)
197  s(1,4) = s(2,4)
198  s(2,4) = ratio*s(1,4)
199  go to 35
200  30 continue
201 c ******the i-th equation enforces continuity of the first derivative
202 c across tau(i). it has been set up in statements 35 up to 40
203 c and 21 up to 25 and reads now
204 c -ratio*diag(i-1)*xi-1 + diag(i)*xi + u(i)*xi+1 = r(i) .
205 c eliminate (i-1)st unknown from this equation
206  s(i,2) = ratio*s(i-1,3) + s(i,2)
207  s(i,4) = ratio*s(i-1,4) + s(i,4)
208 c
209 c ******set up the part of the next equation which depends on the
210 c i-th interval.
211  35 if (z - 0.5d+00) 36,37,38
212  36 ratio = -s(i,6)*s(i,1)/s(i,2)
213  s(i+1,2) = s(i,1)/3.0d+00
214  go to 40
215  37 ratio = -(s(i,1)/6.0d+00)/s(i,2)
216  s(i+1,2) = s(i,1)/3.0d+00
217  go to 40
218  38 ratio = -(s(i,1)/6.0d+00)/s(i,2)
219  s(i+1,2) = s(i,1)*((1.0d+00-zeta*alpha)*factor/2. - s(i,6))
220 c ------ end of i loop ------
221  40 i = i+1
222  if (i .lt. ntaum1) go to 10
223  s(i,5) = 0.5d+00
224 c
225 c ------ last two equations ------
226 c the last two equations enforce continuity of third derivative and
227 c of first derivative across tau(ntau-1).
228  entry = ratio*s(i-1,3) + s(i,2) + s(i,1)/3.0d+00
229  s(i+1,2) = s(i,1)/6.0d+00
230  s(i+1,4) = ratio*s(i-1,4) + s(i,4)
231  if (z - 0.5d+00) 41,42,43
232  41 ratio = s(i,1)*6.0d+00*s(i-1,6)*alpha/s(i-1,2)
233  s(i,2) = ratio*s(i-1,3) + s(i,1) + s(i-1,1)
234  s(i,3) = -s(i-1,1)
235  go to 45
236  42 ratio = s(i,1)/s(i-1,2)
237  s(i,2) = ratio*s(i-1,3) + s(i,1) + s(i-1,1)
238  s(i,3) = -s(i-1,1)
239  go to 45
240  43 factr2 = onemzt*(alpha*(onemzt**2-1.0d+00)+1.0d+00)/
241  * (alpha*(onemzt**3-1.0d+00)+1.0d+00)
242  ratio = factr2*s(i,1)/s(i-1,2)
243  s(i,2) = ratio*s(i-1,3) + factr2*s(i-1,1) + s(i,1)
244  s(i,3) = -factr2*s(i-1,1)
245 c at this point, the last two equations read
246 c diag(i)*xi + u(i)*xi+1 = r(i)
247 c -ratio*diag(i)*xi + diag(i+1)*xi+1 = r(i+1)
248 c eliminate xi from last equation
249  45 s(i,4) = ratio*s(i-1,4)
250  ratio = -entry/s(i,2)
251  s(i+1,2) = ratio*s(i,3) + s(i+1,2)
252  s(i+1,4) = ratio*s(i,4) + s(i+1,4)
253 c
254 c ------ back substitution ------
255 c
256  s(ntau,4) = s(ntau,4)/s(ntau,2)
257  50 s(i,4) = (s(i,4) - s(i,3)*s(i+1,4))/s(i,2)
258  i = i - 1
259  if (i .gt. 1) go to 50
260  s(1,4) = (s(1,4)-s(1,3)*s(2,4)-entry3*s(3,4))/s(1,2)
261 c
262 c ------ construct polynomial pieces ------
263 c
264  break(1) = tau(1)
265  l = 1
266  do 70 i=1,ntaum1
267  coef(1,l) = gtau(i)
268  coef(3,l) = s(i,4)
269  divdif = (gtau(i+1)-gtau(i))/s(i,1)
270  z = s(i,5)
271  if (z - 0.5d+00) 61,62,63
272  61 if (z .eq. 0.0d+00) go to 65
273  zeta = gam*z
274  onemzt = 1.0d+00 - zeta
275  c = s(i+1,4)/6.0d+00
276  d = s(i,4)*s(i,6)
277  l = l + 1
278  del = zeta*s(i,1)
279  break(l) = tau(i) + del
280  zt2 = zeta**2
281  alpha = alph(onemzt)
282  factor = onemzt**2*alpha
283  coef(1,l) = gtau(i) + divdif*del
284  & + s(i,1)**2*(d*onemzt*(factor-1.0d+00)
285  & +c*zeta*(zt2-1.0d+00))
286  coef(2,l) = divdif + s(i,1)*(d*(1.0d+00-3.0d+00*factor)
287  & +c*(3.0d+00*zt2-1.0d+00))
288  coef(3,l) = 6.0d+00*(d*alpha*onemzt + c*zeta)
289  coef(4,l) = 6.0d+00*(c - d*alpha)/s(i,1)
290  coef(4,l-1) = coef(4,l) - 6.0d+00*d*(1.0d+00-alpha)/(del*zt2)
291  coef(2,l-1) = coef(2,l) - del*(coef(3,l)
292  & -(del/2.0d+00)*coef(4,l-1))
293  go to 68
294  62 coef(2,l) = divdif - s(i,1)*(2.0d+00*s(i,4) + s(i+1,4))/6.0d+00
295  coef(4,l) = (s(i+1,4)-s(i,4))/s(i,1)
296  go to 68
297  63 onemzt = gam*(1.0d+00 - z)
298  if (onemzt .eq. 0.0d+00) go to 65
299  zeta = 1.0d+00 - onemzt
300  alpha = alph(zeta)
301  c = s(i+1,4)*s(i,6)
302  d = s(i,4)/6.0d+00
303  del = zeta*s(i,1)
304  break(l+1) = tau(i) + del
305  coef(2,l) = divdif - s(i,1)*(2.0d+00*d + c)
306  coef(4,l) = 6.0d+00*(c*alpha - d)/s(i,1)
307  l = l + 1
308  coef(4,l) = coef(4,l-1)
309  & + 6.0d+00*(1.0d+00-alpha)*c/(s(i,1)*onemzt**3)
310  coef(3,l) = coef(3,l-1) + del*coef(4,l-1)
311  coef(2,l) = coef(2,l-1)
312  & +del*(coef(3,l-1)+(del/2.0d+00)*coef(4,l-1))
313  coef(1,l) = coef(1,l-1)
314  & +del*(coef(2,l-1)+(del/2.0d+00)*(coef(3,l-1)
315  & +(del/3.0d+00)*coef(4,l-1)))
316  go to 68
317  65 coef(2,l) = divdif
318  coef(3,l) = 0.0d+00
319  coef(4,l) = 0.0d+00
320  68 l = l + 1
321  70 break(l) = tau(i+1)
322  l = l - 1
323  k = 4
324  iflag = 1
325  return
326  999 iflag = 2
327  return
328  end
float * x
subroutine tautsp(tau, gtau, ntau, gamma, s, break, coef, l, k, iflag)
Definition: tautsp.f:3
gtkIOStream: /tmp/gtkiostream/src/deBoor/tautsp.f Source File
GTK+ IOStream  Beta