gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
splopt.f
Go to the documentation of this file.
1  subroutine splopt ( tau, n, k, scrtch, t, iflag )
2 
3 c*********************************************************************72
4 c
5 cc SPLOPT computes the knots for an optimal recovery scheme.
6 c
7 c from * a practical guide to splines * by c. de boor
8 calls bsplvb, banfac/slv
9 computes the knots t for the optimal recovery scheme of order k
10 c for data at tau(i), i=1,...,n .
11 c
12 c****** i n p u t ******
13 c tau.....array of length n , containing the interpolation points.
14 c a s s u m e d to be nondecreasing, with tau(i).lt.tau(i+k),all i.
15 c n.....number of data points .
16 c k.....order of the optimal recovery scheme to be used .
17 c
18 c****** w o r k a r r a y *****
19 c scrtch.....array of length (n-k)(2k+3) + 5k + 3 . the various
20 c contents are specified in the text below .
21 c
22 c****** o u t p u t ******
23 c iflag.....integer indicating success (=1) or failure (=2) .
24 c if iflag = 1, then
25 c t.....array of length n+k containing the optimal knots ready for
26 c use in optimal recovery. specifically, t(1) = ... = t(k) =
27 c tau(1) and t(n+1) = ... = t(n+k) = tau(n) , while the n-k
28 c interior knots t(k+1), ..., t(n) are calculated as described
29 c below under *method* .
30 c if iflag = 2, then
31 c k .lt. 3, or n .lt. k, or a certain linear system was found to
32 c be singular.
33 c
34 c****** p r i n t e d o u t p u t ******
35 c a comment will be printed in case iflag = 2 or newton iterations
36 c failed to converge in n e w t m x iterations .
37 c
38 c****** m e t h o d ******
39 c the (interior) knots t(k+1), ..., t(n) are determined by newtons
40 c method in such a way that the signum function which changes sign at
41 c t(k+1), ..., t(n) and nowhere else in (tau(1),tau(n)) is orthogon-
42 c al to the spline space spline( k , tau ) on that interval .
43 c let xi(j) be the current guess for t(k+j), j=1,...,n-k. then
44 c the next newton iterate is of the form
45 c xi(j) + (-)**(n-k-j)*x(j) , j=1,...,n-k,
46 c with x the solution of the linear system
47 c c*x = d .
48 c here, c(i,j) = b(i)(xi(j)), all j, with b(i) the i-th b-spline of
49 c order k for the knot sequence tau , all i, and d is the vector
50 c given by d(i) = sum( -a(j) , j=i,...,n )*(tau(i+k)-tau(i))/k, all i,
51 c with a(i) = sum ( (-)**(n-k-j)*b(i,k+1,tau)(xi(j)) , j=1,...,n-k )
52 c for i=1,...,n-1, and a(n) = -.5 .
53 c (see chapter xiii of text and references there for a derivation)
54 c the first guess for t(k+j) is (tau(j+1)+...+tau(j+k-1))/(k-1) .
55 c iteration terminates if max(abs(x(j))) .lt. t o l , with
56 c t o l = t o l r t e *(tau(n)-tau(1))/(n-k) ,
57 c or else after n e w t m x iterations , currently,
58 c newtmx, tolrte / 10, .000001
59 c
60  implicit none
61 
62  integer iflag,k,n, i,id,index,j,km1,kpk,kpkm1,kpn,kp1,l,left
63  &,leftmk,lenw,ll,llmax,llmin,na,nb,nc,nd,newtmx,newton,nmk,nmkm1,nx
64  double precision scrtch(1),t(1),tau(n),
65  & del,delmax,floatk,sign,signst,sum
66  & ,tol,tolrte,xij
67 c dimension scrtch((n-k)*(2*k+3)+5*k+3), t(n+k)
68 current fortran standard makes it impossible to specify the precise dim-
69 c ensions of scrtch and t without the introduction of otherwise
70 c superfluous additional arguments .
71  data newtmx,tolrte / 10,0.000001d+00/
72  nmk = n-k
73  if (nmk) 1,56,2
74  1 print 601,n,k
75  601 format(13h argument n =,i4,29h in splopt is less than k =,i3)
76  go to 999
77  2 if (k .gt. 2) go to 3
78  print 602,k
79  602 format(13h argument k =,i3,27h in splopt is less than 3)
80  go to 999
81  3 nmkm1 = nmk - 1
82  floatk = k
83  kpk = k+k
84  kp1 = k+1
85  km1 = k-1
86  kpkm1 = kpk-1
87  kpn = k+n
88  signst = -1.0d+00
89  if (nmk .gt. (nmk/2)*2) signst = 1.0d+00
90 c scrtch(i) = tau-extended(i), i=1,...,n+k+k
91  nx = n+kpk+1
92 c scrtch(i+nx) = xi(i),i=0,...,n-k+1
93  na = nx + nmk + 1
94 c scrtch(i+na) = -a(i), i=1,...,n
95  nd = na + n
96 c scrtch(i+nd) = x(i) or d(i), i=1,...,n-k
97  nb = nd + nmk
98 c scrtch(i+nb) = biatx(i),i=1,...,k+1
99  nc = nb + kp1
100 c scrtch(i+(j-1)*(2k-1) + nc) = w(i,j) = c(i-k+j,j), i=j-k,...,j+k,
101 c j=1,...,n-k.
102  lenw = kpkm1*nmk
103 c extend tau to a knot sequence and store in scrtch.
104  do 5 j=1,k
105  scrtch(j) = tau(1)
106  5 scrtch(kpn+j) = tau(n)
107  do 6 j=1,n
108  6 scrtch(k+j) = tau(j)
109 c first guess for scrtch (.+nx) = xi .
110  scrtch(nx) = tau(1)
111  scrtch(nmk+1+nx) = tau(n)
112  do 10 j=1,nmk
113  sum = 0.0d+00
114  do 9 l=1,km1
115  9 sum = sum + tau(j+l)
116  10 scrtch(j+nx) = sum/dble(km1)
117 c last entry of scrtch (.+na) = - a is always ...
118  scrtch(n+na) = .5
119 c start newton iteration.
120  newton = 1
121  tol = tolrte*(tau(n) - tau(1))/dble(nmk)
122 c start newton step
123 compute the 2k-1 bands of the matrix c and store in scrtch(.+nc),
124 c and compute the vector scrtch(.+na) = -a.
125  20 do 21 i=1,lenw
126  21 scrtch(i+nc) = 0.0d+00
127  do 22 i=2,n
128  22 scrtch(i-1+na) = 0.0d+00
129  sign = signst
130  left = kp1
131  do 28 j=1,nmk
132  xij = scrtch(j+nx)
133  23 if (xij .lt. scrtch(left+1))go to 25
134  left = left + 1
135  if (left .lt. kpn) go to 23
136  left = left - 1
137  25 call bsplvb(scrtch,k,1,xij,left,scrtch(1+nb))
138 c the tau sequence in scrtch is preceded by k additional knots
139 c therefore, scrtch(ll+nb) now contains b(left-2k+ll)(xij)
140 c which is destined for c(left-2k+ll,j), and therefore for
141 c w(left-k-j+ll,j)= scrtch(left-k-j+ll + (j-1)*kpkm1 + nc)
142 c since we store the 2k-1 bands of c in the 2k-1 r o w s of
143 c the work array w, and w in turn is stored in s c r t c h ,
144 c with w(1,1) = scrtch(1 + nc) .
145 c also, c being of order n-k, we would want 1 .le.
146 c left-2k+ll .le. n-k or
147 c llmin = 2k-left .le. ll .le. n-left+k = llmax .
148  leftmk = left-k
149  index = leftmk-j + (j-1)*kpkm1 + nc
150  llmin = max0(1,k-leftmk)
151  llmax = min0(k,n-leftmk)
152  do 26 ll=llmin,llmax
153  26 scrtch(ll+index) = scrtch(ll+nb)
154  call bsplvb(scrtch,kp1,2,xij,left,scrtch(1+nb))
155  id = max0(0,leftmk-kp1)
156  llmin = 1 - min0(0,leftmk-kp1)
157  do 27 ll=llmin,kp1
158  id = id + 1
159  27 scrtch(id+na) = scrtch(id+na) - sign*scrtch(ll+nb)
160  28 sign = -sign
161  call banfac(scrtch(1+nc),kpkm1,nmk,km1,km1,iflag)
162  go to (45,44),iflag
163  44 print 644
164  644 format(32h c in splopt is not invertible)
165  return
166 compute scrtch (.+nd) = d from scrtch (.+na) = - a .
167  45 i=n
168  46 scrtch(i-1+na) = scrtch(i-1+na) + scrtch(i+na)
169  i = i-1
170  if (i .gt. 1) go to 46
171  do 49 i=1,nmk
172  49 scrtch(i+nd) = scrtch(i+na)*(tau(i+k)-tau(i))/floatk
173 compute scrtch (.+nd) = x .
174  call banslv(scrtch(1+nc),kpkm1,nmk,km1,km1,scrtch(1+nd))
175 compute scrtch (.+nd) = change in xi . modify, if necessary, to
176 c prevent new xi from moving more than 1/3 of the way to its
177 c neighbors. then add to xi to obtain new xi in scrtch(.+nx).
178  delmax = 0.0d+00
179  sign = signst
180  do 53 i=1,nmk
181  del = sign*scrtch(i+nd)
182  delmax = dmax1(delmax,dabs(del))
183  if (del .gt. 0.0d+00) go to 51
184  del = dmax1(del,(scrtch(i-1+nx)-scrtch(i+nx))/3.0d+00)
185  go to 52
186  51 del = dmin1(del,(scrtch(i+1+nx)-scrtch(i+nx))/3.0d+00)
187  52 sign = -sign
188  53 scrtch(i+nx) = scrtch(i+nx) + del
189 call it a day in case change in xi was small enough or too many
190 c steps were taken.
191  if (delmax .lt. tol) go to 54
192  newton = newton + 1
193  if (newton .le. newtmx) go to 20
194  print 653,newtmx
195  653 format(33h no convergence in splopt after,i3,14h newton steps.)
196  54 do 55 i=1,nmk
197  55 t(k+i) = scrtch(i+nx)
198  56 do 57 i=1,k
199  t(i) = tau(1)
200  57 t(n+i) = tau(n)
201  return
202  999 iflag = 2
203  return
204  end
subroutine banslv(w, nroww, nrow, nbandl, nbandu, b)
Definition: banslv.f:2
subroutine banfac(w, nroww, nrow, nbandl, nbandu, iflag)
Definition: banfac.f:2
subroutine bsplvb(t, jhigh, index, x, left, biatx)
Definition: bsplvb.f:2
subroutine splopt(tau, n, k, scrtch, t, iflag)
Definition: splopt.f:2
gtkIOStream: /tmp/gtkiostream/src/deBoor/splopt.f Source File
GTK+ IOStream  Beta