gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
smooth.f
Go to the documentation of this file.
1  double precision function smooth ( x, y, dy, npoint, s, v, a )
2 
3 c*********************************************************************72
4 c
5 cc SMOOTH constructs the cubic smoothing spline to given data.
6 c
7 c from * a practical guide to splines * by c. de boor
8 calls setupq, chol1d
9 c
10 c constructs the cubic smoothing spline f to given data (x(i),y(i)),
11 c i=1,...,npoint, which has as small a second derivative as possible
12 c while
13 c s(f) = sum( ((y(i)-f(x(i)))/dy(i))**2 , i=1,...,npoint ) .le. s .
14 c
15 c****** i n p u t ******
16 c x(1),...,x(npoint) data abscissae, a s s u m e d to be strictly
17 c increasing .
18 c y(1),...,y(npoint) corresponding data ordinates .
19 c dy(1),...,dy(npoint) estimate of uncertainty in data, a s s u m-
20 c e d to be positive .
21 c npoint.....number of data points, a s s u m e d .gt. 1
22 c s.....upper bound on the discrete weighted mean square distance of
23 c the approximation f from the data .
24 c
25 c****** w o r k a r r a y s *****
26 c v.....of size (npoint,7)
27 c a.....of size (npoint,4)
28 c
29 c***** o u t p u t *****
30 c a(.,1).....contains the sequence of smoothed ordinates .
31 c a(i,j) = f^(j-1)(x(i)), j=2,3,4, i=1,...,npoint-1 , i.e., the
32 c first three derivatives of the smoothing spline f at the
33 c left end of each of the data intervals .
34 c w a r n i n g . . . a would have to be transposed before it
35 c could be used in ppvalu .
36 c
37 c****** m e t h o d ******
38 c The matrices Q-transp*d and Q-transp*D**2*Q are constructed in
39 c s e t u p q from x and dy , as is the vector qty = Q-transp*y .
40 c Then, for given p , the vector u is determined in c h o l 1 d as
41 c the solution of the linear system
42 c (6(1-p)Q-transp*D**2*Q + p*Q)u = qty .
43 c From u , the smoothing spline f (for this choice of smoothing par-
44 c ameter p ) is obtained in the sense that
45 c f(x(.)) = y - 6(1-p)D**2*Q*u and
46 c f''(x(.)) = 6*p*u .
47 c The smoothing parameter p is found (if possible) so that
48 c sf(p) = s ,
49 c with sf(p) = s(f) , where f is the smoothing spline as it depends
50 c on p . if s = 0, then p = 1 . if sf(0) .le. s , then p = 0 .
51 c Otherwise, the secant method is used to locate an appropriate p in
52 c the open interval (0,1) . However, straightforward application of
53 c the secant method, as done in the original version of this program,
54 c can be very slow and is influenced by the units in which x and y
55 c are measured, as C. Reinsch has pointed out. Instead, on recommend-
56 c ation from C. Reinsch, the secant method is applied to the function
57 c g:q |--> 1/sqrt{sfq(q)} - 1/sqrt{s} ,
58 c with sfq(q) := sf(q/(1+q)), since 1/sqrt{sfq} is monotone increasing
59 c and close to linear for larger q . One starts at q = 0 with a
60 c Newton step, i.e.,
61 c q_0 = 0, q_1 = -g(0)/g'(0)
62 c with g'(0) = -(1/2) sfq(0)^{-3/2} dsfq, where dsfq = -12*u-transp*r*u ,
63 c and u as obtained for p = 0 . Iteration terminates as soon as
64 c abs(sf - s) .le. .01*s .
65 c
66  implicit none
67 c
68 c logical test
69 c parameter (test = .true.)
70 c integer itercnt
71  integer npoint, i,npm1
72  double precision a(npoint,4),dy(npoint),s,v(npoint,7),
73  & x(npoint),y(npoint)
74  & ,change,ooss,oosf,p,prevsf,prevq,q,sfq,sixp,six1mp,utru
75  call setupq(x,dy,y,npoint,v,a(1,4))
76  if (s .gt. 0.0d+00) go to 20
77  10 p = 1.0d+00
78  call chol1d(p,v,a(1,4),npoint,1,a(1,3),a(1,1))
79  sfq = 0.0d+00
80  go to 60
81  20 p = 0.0d+00
82  call chol1d(p,v,a(1,4),npoint,1,a(1,3),a(1,1))
83  sfq = 0.0d+00
84  do 21 i=1,npoint
85  21 sfq = sfq + (a(i,1)*dy(i))**2
86  sfq = sfq*36.0d+00
87  if (sfq .le. s) go to 60
88  utru = 0.0d+00
89  do 25 i=2,npoint
90  25 utru = utru + v(i-1,4)*(a(i-1,3)*(a(i-1,3)+a(i,3))+a(i,3)**2)
91  ooss = 1.0d+00/dsqrt(s)
92  oosf = 1.0d+00/dsqrt(sfq)
93  q = -(oosf-ooss)*sfq/(6.0d+00*utru*oosf)
94 c secant iteration for the determination of p starts here.
95 c itercnt = 0
96  prevq = 0.0d+00
97  prevsf = oosf
98  30 call chol1d(q/(1.0d+00+q),v,a(1,4),npoint,1,a(1,3),a(1,1))
99  sfq = 0.0d+00
100  do 35 i=1,npoint
101  35 sfq = sfq + (a(i,1)*dy(i))**2
102  sfq = sfq*36.0d+00/(1.0d+00+q)**2
103  if (dabs(sfq-s) .le. 0.01d+00*s) go to 59
104  oosf = 1.0d+00/dsqrt(sfq)
105  change = (q-prevq)/(oosf-prevsf)*(oosf-ooss)
106  prevq = q
107  q = q - change
108  prevsf = oosf
109 c itercnt = itercnt + 1
110  go to 30
111  59 p = q/(1.0d+00+q)
112 correct value of p has been found.
113 compute pol.coefficients from Q*u (in a(.,1)).
114  60 smooth = sfq
115 c if (test) then
116 c print *, 'number of iterations = ', itercnt
117 c end if
118 c six1mp = 6./(1.0D+00+q)
119  do 61 i=1,npoint
120 c 61 a(i,1) = y(i) - six1mp*dy(i)**2*a(i,1)
121  61 a(i,1) = y(i) - 6.0d+00 * ( 1.0d+00 - p ) *dy(i)**2*a(i,1)
122  sixp = 6.0d+00*p
123  do 62 i=1,npoint
124  62 a(i,3) = a(i,3)*sixp
125  npm1 = npoint - 1
126  do 63 i=1,npm1
127  a(i,4) = (a(i+1,3)-a(i,3))/v(i,4)
128  63 a(i,2) = (a(i+1,1)-a(i,1))/v(i,4)
129  & - (a(i,3)+a(i,4)/3.0d+00*v(i,4))/2.0d+00*v(i,4)
130  return
131  end
float * x
double precision function smooth(x, y, dy, npoint, s, v, a)
Definition: smooth.f:2
subroutine chol1d(p, v, qty, npoint, ncol, u, qu)
Definition: chol1d.f:2
float p
subroutine setupq(x, dx, y, npoint, v, qty)
Definition: setupq.f:2
float * y
gtkIOStream: /tmp/gtkiostream/src/deBoor/smooth.f Source File
GTK+ IOStream  Beta