1
subroutine fpclos(iopt,idim,m,u,mx,x,w,k,s,nest,tol,maxit,k1,k2,
2
* n,t,nc,c,fp,fpint,z,a1,a2,b,g1,g2,q,nrdata,ier)
6
integer iopt,idim,m,mx,k,nest,maxit,k1,k2,n,nc,ier
8
real*8 u(m),x(mx),w(m),t(nest),c(nc),fpint(nest),z(nc),a1(nest,k1)
10
* a2(nest,k),b(nest,k2),g1(nest,k2),g2(nest,k1),q(m,k1)
13
real*8 acc,cos,d1,fac,fpart,fpms,fpold,fp0,f1,f2,f3,p,per,pinv,piv
15
* p1,p2,p3,sin,store,term,ui,wi,rn,one,con1,con4,con9,half
16
integer i,ich1,ich3,ij,ik,it,iter,i1,i2,i3,j,jj,jk,jper,j1,j2,kk,
17
* kk1,k3,l,l0,l1,l5,mm,m1,new,nk1,nk2,nmax,nmin,nplus,npl1,
20
real*8 h(6),h1(7),h2(6),xi(10)
21
c ..function references..
24
c ..subroutine references..
25
c fpbacp,fpbspl,fpgivs,fpdisc,fpknot,fprota
33
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
34
c part 1: determination of the number of knots and their position c
35
c ************************************************************** c
36
c given a set of knots we compute the least-squares closed curve c
37
c sinf(u). if the sum f(p=inf) <= s we accept the choice of knots. c
38
c if iopt=-1 sinf(u) is the requested curve c
39
c if iopt=0 or iopt=1 we check whether we can accept the knots: c
40
c if fp <=s we will continue with the current set of knots. c
41
c if fp > s we will increase the number of knots and compute the c
42
c corresponding least-squares curve until finally fp<=s. c
43
c the initial choice of knots depends on the value of s and iopt. c
44
c if s=0 we have spline interpolation; in that case the number of c
45
c knots equals nmax = m+2*k. c
47
c iopt=0 we first compute the least-squares polynomial curve of c
48
c degree k; n = nmin = 2*k+2. since s(u) must be periodic we c
49
c find that s(u) reduces to a fixed point. c
50
c iopt=1 we start with the set of knots found at the last c
51
c call of the routine, except for the case that s > fp0; then c
52
c we compute directly the least-squares polynomial curve. c
53
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
59
c determine the length of the period of the splines.
61
if(iopt.lt.0) go to 50
62
c calculation of acc, the absolute tolerance for the root of f(p)=s.
64
c determine nmax, the number of knots for periodic spline interpolation
66
if(s.gt.0. .or. nmax.eq.nmin) go to 30
67
c if s=0, s(u) is an interpolating curve.
69
c test whether the required storage space exceeds the available one.
70
if(n.gt.nest) go to 620
71
c find the position of the interior knots in case of interpolation.
72
5 if((k/2)*2 .eq.k) go to 20
108
t(j) = (u(i)+u(i-1))*half
111
c if s > 0 our initial choice depends on the value of iopt.
112
c if iopt=0 or iopt=1 and s>=fp0, we start computing the least-squares
113
c polynomial curve. (i.e. a constant point).
114
c if iopt=1 and fp0>s we start computing the least-squares closed
115
c curve according the set of knots found at the last call of the
117
30 if(iopt.eq.0) go to 35
118
if(n.eq.nmin) go to 35
122
if(fp0.gt.s) go to 50
123
c the case that s(u) is a fixed point is treated separetely.
124
c fp0 denotes the corresponding sum of squared residuals.
133
call fpgivs(wi,d1,cos,sin)
137
call fprota(cos,sin,fac,z(j))
144
c test whether that fixed point is a solution of our problem.
146
if(fpms.lt.acc .or. nmax.eq.nmin) go to 640
148
c test whether the required storage space exceeds the available one.
149
if(n.ge.nest) go to 620
150
c start computing the least-squares closed curve with one
158
c main loop for the different sets of knots. m is a save upper
159
c bound for the number of trials.
161
c find nrint, the number of knot intervals.
163
c find the position of the additional knots which are needed for
164
c the b-spline representation of s(u). if we take
165
c t(k+1) = u(1), t(n-k) = u(m)
166
c t(k+1-j) = t(n-k-j) - per, j=1,2,...k
167
c t(n-k+j) = t(k+1+j) + per, j=1,2,...k
168
c then s(u) will be a smooth closed curve if the b-spline
169
c coefficients satisfy the following conditions
170
c c((i-1)*n+n7+j) = c((i-1)*n+j), j=1,...k,i=1,2,...,idim (**)
184
c compute the b-spline coefficients of the least-squares closed curve
185
c sinf(u). the observation matrix a is built up row by row while
186
c taking into account condition (**) and is reduced to triangular
187
c form by givens transformations .
188
c at the same time fp=f(p=inf) is computed.
189
c the n7 x n7 triangularised upper matrix a has the form
193
c with a2 a n7 x k matrix and a1 a n10 x n10 upper triangular
194
c matrix of bandwith k+1 ( n10 = n7-k).
210
c fetch the current data point u(it),x(it)
217
c search for knot interval t(l) <= ui < t(l+1).
218
80 if(ui.lt.t(l+1)) go to 85
221
c evaluate the (k+1) non-zero b-splines at ui and store them in q.
222
85 call fpbspl(t,n,k,ui,l,h)
228
c test whether the b-splines nj,k+1(u),j=1+n7,...nk1 are all zero at ui
229
if(l5.lt.n10) go to 285
230
if(jper.ne.0) go to 160
231
c initialize the matrix a2.
240
if(ik.le.0) go to 105
247
c if one of the b-splines nj,k+1(u),j=n7+1,...nk1 is not zero at ui
248
c we take account of condition (**) for setting up the new row
249
c of the observation matrix a. this row is stored in the arrays h1
250
c (the part with respect to a1) and h2 (the part with
262
if(l1.le.0) go to 200
263
if(l1.le.n10) go to 190
268
200 h2(l0) = h2(l0)+h(i)
270
c rotate the new row of the observation matrix into triangle
271
c by givens transformations.
272
if(n10.le.0) go to 250
273
c rotation with the rows 1,2,...n10 of matrix a.
276
if(piv.ne.0.) go to 214
282
c calculate the parameters of the givens transformation.
283
214 call fpgivs(piv,a1(j,1),cos,sin)
284
c transformation to the right hand side.
287
call fprota(cos,sin,xi(j2),z(j1))
290
c transformations to the left hand side with respect to a2.
292
call fprota(cos,sin,h2(i),a2(j,i))
294
if(j.eq.n10) go to 250
296
c transformations to the left hand side with respect to a1.
299
call fprota(cos,sin,h1(i1),a1(j,i1))
304
c rotation with the rows n10+1,...n7 of matrix a.
307
if(ij.le.0) go to 270
309
if(piv.eq.0.) go to 270
310
c calculate the parameters of the givens transformation.
311
call fpgivs(piv,a2(ij,j),cos,sin)
312
c transformations to right hand side.
315
call fprota(cos,sin,xi(j2),z(j1))
318
if(j.eq.kk) go to 280
320
c transformations to left hand side.
322
call fprota(cos,sin,h2(i),a2(ij,i))
325
c add contribution of this row to the sum of squares of residual
331
c rotation of the new row of the observation matrix into
332
c triangle in case the b-splines nj,k+1(u),j=n7+1,...n-k-1 are all zero
338
if(piv.eq.0.) go to 140
339
c calculate the parameters of the givens transformation.
340
call fpgivs(piv,a1(j,1),cos,sin)
341
c transformations to right hand side.
344
call fprota(cos,sin,xi(j2),z(j1))
347
if(i.eq.kk1) go to 150
350
c transformations to left hand side.
353
call fprota(cos,sin,h(i1),a1(j,i2))
356
c add contribution of this row to the sum of squares of residual
365
c backward substitution to obtain the b-spline coefficients .
368
call fpbacp(a1,a2,z(j1),n7,kk,c(j1),kk1,nest)
371
c calculate from condition (**) the remaining coefficients.
380
if(iopt.lt.0) go to 660
381
c test whether the approximation sinf(u) is an acceptable solution.
383
if(abs(fpms).lt.acc) go to 660
384
c if f(p=inf) < s accept the choice of knots.
385
if(fpms.lt.0.) go to 350
386
c if n=nmax, sinf(u) is an interpolating curve.
387
if(n.eq.nmax) go to 630
388
c increase the number of knots.
389
c if n=nest we cannot increase the number of knots because of the
390
c storage capacity limitation.
391
if(n.eq.nest) go to 620
392
c determine the number of knots nplus we are going to add.
395
if(fpold-fp.gt.acc) npl1 = rn*fpms/(fpold-fp)
396
nplus = min0(nplus*2,max0(npl1,nplus/2,1))
398
c compute the sum of squared residuals for each knot interval
399
c t(j+k) <= ui <= t(j+k+1) and store it in fpint(j),j=1,2,...nrint.
405
if(u(it).lt.t(l)) go to 300
415
fac = fac+c(j1)*q(it,j)
418
term = term+(w(it)*(fac-x(jj)))**2
422
if(new.eq.0) go to 320
423
if(l.gt.k2) go to 315
427
315 store = term*half
428
fpint(i) = fpart-store
433
fpint(nrint) = fpint(nrint)+fpart
436
call fpknot(u,m,t,n,fpint,nrdata,nrint,nest,1)
437
c if n=nmax we locate the knots as for interpolation
438
if(n.eq.nmax) go to 5
439
c test whether we cannot further increase the number of knots.
440
if(n.eq.nest) go to 340
442
c restart the computations with the new set of knots.
444
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
445
c part 2: determination of the smoothing closed curve sp(u). c
446
c ********************************************************** c
447
c we have determined the number of knots and their position. c
448
c we now compute the b-spline coefficients of the smoothing curve c
449
c sp(u). the observation matrix a is extended by the rows of matrix c
450
c b expressing that the kth derivative discontinuities of sp(u) at c
451
c the interior knots t(k+2),...t(n-k-1) must be zero. the corres- c
452
c ponding weights of these additional rows are set to 1/p. c
453
c iteratively we then have to determine the value of p such that f(p),c
454
c the sum of squared residuals be = s. we already know that the least-c
455
c squares polynomial curve corresponds to p=0, and that the least- c
456
c squares periodic spline curve corresponds to p=infinity. the c
457
c iteration process which is proposed here, makes use of rational c
458
c interpolation. since f(p) is a convex and strictly decreasing c
459
c function of p, it can be approximated by a rational function c
460
c r(p) = (u*p+v)/(p+w). three values of p(p1,p2,p3) with correspond- c
461
c ing values of f(p) (f1=f(p1)-s,f2=f(p2)-s,f3=f(p3)-s) are used c
462
c to calculate the new value of p such that r(p)=s. convergence is c
463
c guaranteed by taking f1>0 and f3<0. c
464
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
465
c evaluate the discontinuity jump of the kth derivative of the
466
c b-splines at the knots t(l),l=k+2,...n-k-1 and store in b.
467
350 call fpdisc(t,n,k2,b,nest)
468
c initial value for p.
490
c iteration process to find the root of f(p) = s.
492
c form the matrix g as the matrix a extended by the rows of matrix b.
493
c the rows of matrix b with weight 1/p are rotated into
494
c the triangularised observation matrix a.
495
c after triangularisation our n7 x n7 matrix g takes the form
499
c with g2 a n7 x (k+1) matrix and g1 a n11 x n11 upper triangular
500
c matrix of bandwidth k+2. ( n11 = n7-k-1)
502
c store matrix a into g
521
c fetch a new row of matrix b and store it in the arrays h1 (the part
522
c with respect to g1) and h2 (the part with respect to g2).
531
if(it.gt.n11) go to 420
535
if(l0.eq.n10) go to 400
542
h2(l0) = b(it,l1)*pinv
552
if(l1.le.0) go to 450
553
if(l1.le.n11) go to 440
556
440 h1(l1) = b(it,j)*pinv
558
450 h2(l0) = h2(l0)+b(it,j)*pinv
560
if(n11.le.0) go to 510
561
c rotate this row into triangle by givens transformations
562
c rotation with the rows l,l+1,...n11.
565
c calculate the parameters of the givens transformation.
566
call fpgivs(piv,g1(j,1),cos,sin)
567
c transformation to right hand side.
570
call fprota(cos,sin,xi(j2),c(j1))
573
c transformation to the left hand side with respect to g2.
575
call fprota(cos,sin,h2(i),g2(j,i))
577
if(j.eq.n11) go to 510
579
c transformation to the left hand side with respect to g1.
582
call fprota(cos,sin,h1(i1),g1(j,i1))
587
c rotation with the rows n11+1,...n7
590
if(ij.le.0) go to 530
592
c calculate the parameters of the givens transformation
593
call fpgivs(piv,g2(ij,j),cos,sin)
594
c transformation to the right hand side.
597
call fprota(cos,sin,xi(j2),c(j1))
600
if(j.eq.k1) go to 540
602
c transformation to the left hand side.
604
call fprota(cos,sin,h2(i),g2(ij,i))
608
c backward substitution to obtain the b-spline coefficients
611
call fpbacp(g1,g2,c(j1),n7,k1,c(j1),k2,nest)
614
c calculate from condition (**) the remaining b-spline coefficients.
623
c computation of f(p).
628
if(u(it).lt.t(l)) go to 550
637
fac = fac+c(j1)*q(it,j)
640
term = term+(fac-x(jj))**2
643
fp = fp+term*w(it)**2
645
c test whether the approximation sp(u) is an acceptable solution.
647
if(abs(fpms).lt.acc) go to 660
648
c test whether the maximal number of iterations is reached.
649
if(iter.eq.maxit) go to 600
650
c carry out one more step of the iteration process.
653
if(ich3.ne.0) go to 580
654
if((f2-f3) .gt. acc) go to 575
655
c our initial choice of p is too large.
659
if(p.le.p1) p = p1*con9 +p2*con1
661
575 if(f2.lt.0.) ich3 = 1
662
580 if(ich1.ne.0) go to 590
663
if((f1-f2) .gt. acc) go to 585
664
c our initial choice of p is too small
668
if(p3.lt.0.) go to 595
669
if(p.ge.p3) p = p2*con1 +p3*con9
671
585 if(f2.gt.0.) ich1 = 1
672
c test whether the iteration process proceeds as theoretically
674
590 if(f2.ge.f1 .or. f2.le.f3) go to 610
675
c find the new value for p.
676
p = fprati(p1,f1,p2,f2,p3,f3)
678
c error codes and messages.
688
c the point (z(1),z(2),...,z(idim)) is a solution of our problem.
689
c a constant function is a spline of degree k with all b-spline
690
c coefficients equal to that constant.