~ubuntu-branches/ubuntu/karmic/python-scipy/karmic

« back to all changes in this revision

Viewing changes to Lib/interpolate/fitpack/fpgrre.f

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T. Chen (new)
  • Date: 2005-03-16 02:15:29 UTC
  • Revision ID: james.westby@ubuntu.com-20050316021529-xrjlowsejs0cijig
Tags: upstream-0.3.2
ImportĀ upstreamĀ versionĀ 0.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
      subroutine fpgrre(ifsx,ifsy,ifbx,ifby,x,mx,y,my,z,mz,kx,ky,tx,nx,
 
2
     * ty,ny,p,c,nc,fp,fpx,fpy,mm,mynx,kx1,kx2,ky1,ky2,spx,spy,right,q,
 
3
     * ax,ay,bx,by,nrx,nry)
 
4
c  ..
 
5
c  ..scalar arguments..
 
6
      real*8 p,fp
 
7
      integer ifsx,ifsy,ifbx,ifby,mx,my,mz,kx,ky,nx,ny,nc,mm,mynx,
 
8
     * kx1,kx2,ky1,ky2
 
9
c  ..array arguments..
 
10
      real*8 x(mx),y(my),z(mz),tx(nx),ty(ny),c(nc),spx(mx,kx1),spy(my,ky
 
11
     *1)
 
12
     * ,right(mm),q(mynx),ax(nx,kx2),bx(nx,kx2),ay(ny,ky2),by(ny,ky2),
 
13
     * fpx(nx),fpy(ny)
 
14
      integer nrx(mx),nry(my)
 
15
c  ..local scalars..
 
16
      real*8 arg,cos,fac,pinv,piv,sin,term,one,half
 
17
      integer i,ibandx,ibandy,ic,iq,irot,it,iz,i1,i2,i3,j,k,k1,k2,l,
 
18
     * l1,l2,ncof,nk1x,nk1y,nrold,nroldx,nroldy,number,numx,numx1,
 
19
     * numy,numy1,n1
 
20
c  ..local arrays..
 
21
      real*8 h(7)
 
22
c  ..subroutine references..
 
23
c    fpback,fpbspl,fpgivs,fpdisc,fprota
 
24
c  ..
 
25
c  the b-spline coefficients of the smoothing spline are calculated as
 
26
c  the least-squares solution of the over-determined linear system of
 
27
c  equations  (ay) c (ax)' = q       where
 
28
c
 
29
c               |   (spx)    |            |   (spy)    |
 
30
c        (ax) = | ---------- |     (ay) = | ---------- |
 
31
c               | (1/p) (bx) |            | (1/p) (by) |
 
32
c
 
33
c                                | z  ' 0 |
 
34
c                            q = | ------ |
 
35
c                                | 0  ' 0 |
 
36
c
 
37
c  with c      : the (ny-ky-1) x (nx-kx-1) matrix which contains the
 
38
c                b-spline coefficients.
 
39
c       z      : the my x mx matrix which contains the function values.
 
40
c       spx,spy: the mx x (nx-kx-1) and  my x (ny-ky-1) observation
 
41
c                matrices according to the least-squares problems in
 
42
c                the x- and y-direction.
 
43
c       bx,by  : the (nx-2*kx-1) x (nx-kx-1) and (ny-2*ky-1) x (ny-ky-1)
 
44
c                matrices which contain the discontinuity jumps of the
 
45
c                derivatives of the b-splines in the x- and y-direction.
 
46
      one = 1
 
47
      half = 0.5
 
48
      nk1x = nx-kx1
 
49
      nk1y = ny-ky1
 
50
      if(p.gt.0.) pinv = one/p
 
51
c  it depends on the value of the flags ifsx,ifsy,ifbx and ifby and on
 
52
c  the value of p whether the matrices (spx),(spy),(bx) and (by) still
 
53
c  must be determined.
 
54
      if(ifsx.ne.0) go to 50
 
55
c  calculate the non-zero elements of the matrix (spx) which is the
 
56
c  observation matrix according to the least-squares spline approximat-
 
57
c  ion problem in the x-direction.
 
58
      l = kx1
 
59
      l1 = kx2
 
60
      number = 0
 
61
      do 40 it=1,mx
 
62
        arg = x(it)
 
63
  10    if(arg.lt.tx(l1) .or. l.eq.nk1x) go to 20
 
64
        l = l1
 
65
        l1 = l+1
 
66
        number = number+1
 
67
        go to 10
 
68
  20    call fpbspl(tx,nx,kx,arg,l,h)
 
69
        do 30 i=1,kx1
 
70
          spx(it,i) = h(i)
 
71
  30    continue
 
72
        nrx(it) = number
 
73
  40  continue
 
74
      ifsx = 1
 
75
  50  if(ifsy.ne.0) go to 100
 
76
c  calculate the non-zero elements of the matrix (spy) which is the
 
77
c  observation matrix according to the least-squares spline approximat-
 
78
c  ion problem in the y-direction.
 
79
      l = ky1
 
80
      l1 = ky2
 
81
      number = 0
 
82
      do 90 it=1,my
 
83
        arg = y(it)
 
84
  60    if(arg.lt.ty(l1) .or. l.eq.nk1y) go to 70
 
85
        l = l1
 
86
        l1 = l+1
 
87
        number = number+1
 
88
        go to 60
 
89
  70    call fpbspl(ty,ny,ky,arg,l,h)
 
90
        do 80 i=1,ky1
 
91
          spy(it,i) = h(i)
 
92
  80    continue
 
93
        nry(it) = number
 
94
  90  continue
 
95
      ifsy = 1
 
96
 100  if(p.le.0.) go to 120
 
97
c  calculate the non-zero elements of the matrix (bx).
 
98
      if(ifbx.ne.0 .or. nx.eq.2*kx1) go to 110
 
99
      call fpdisc(tx,nx,kx2,bx,nx)
 
100
      ifbx = 1
 
101
c  calculate the non-zero elements of the matrix (by).
 
102
 110  if(ifby.ne.0 .or. ny.eq.2*ky1) go to 120
 
103
      call fpdisc(ty,ny,ky2,by,ny)
 
104
      ifby = 1
 
105
c  reduce the matrix (ax) to upper triangular form (rx) using givens
 
106
c  rotations. apply the same transformations to the rows of matrix q
 
107
c  to obtain the my x (nx-kx-1) matrix g.
 
108
c  store matrix (rx) into (ax) and g into q.
 
109
 120  l = my*nk1x
 
110
c  initialization.
 
111
      do 130 i=1,l
 
112
        q(i) = 0.
 
113
 130  continue
 
114
      do 140 i=1,nk1x
 
115
        do 140 j=1,kx2
 
116
          ax(i,j) = 0.
 
117
 140  continue
 
118
      l = 0
 
119
      nrold = 0
 
120
c  ibandx denotes the bandwidth of the matrices (ax) and (rx).
 
121
      ibandx = kx1
 
122
      do 270 it=1,mx
 
123
        number = nrx(it)
 
124
 150    if(nrold.eq.number) go to 180
 
125
        if(p.le.0.) go to 260
 
126
        ibandx = kx2
 
127
c  fetch a new row of matrix (bx).
 
128
        n1 = nrold+1
 
129
        do 160 j=1,kx2
 
130
          h(j) = bx(n1,j)*pinv
 
131
 160    continue
 
132
c  find the appropriate column of q.
 
133
        do 170 j=1,my
 
134
          right(j) = 0.
 
135
 170    continue
 
136
        irot = nrold
 
137
        go to 210
 
138
c  fetch a new row of matrix (spx).
 
139
 180    h(ibandx) = 0.
 
140
        do 190 j=1,kx1
 
141
          h(j) = spx(it,j)
 
142
 190    continue
 
143
c  find the appropriate column of q.
 
144
        do 200 j=1,my
 
145
          l = l+1
 
146
          right(j) = z(l)
 
147
 200    continue
 
148
        irot = number
 
149
c  rotate the new row of matrix (ax) into triangle.
 
150
 210    do 240 i=1,ibandx
 
151
          irot = irot+1
 
152
          piv = h(i)
 
153
          if(piv.eq.0.) go to 240
 
154
c  calculate the parameters of the givens transformation.
 
155
          call fpgivs(piv,ax(irot,1),cos,sin)
 
156
c  apply that transformation to the rows of matrix q.
 
157
          iq = (irot-1)*my
 
158
          do 220 j=1,my
 
159
            iq = iq+1
 
160
            call fprota(cos,sin,right(j),q(iq))
 
161
 220      continue
 
162
c  apply that transformation to the columns of (ax).
 
163
          if(i.eq.ibandx) go to 250
 
164
          i2 = 1
 
165
          i3 = i+1
 
166
          do 230 j=i3,ibandx
 
167
            i2 = i2+1
 
168
            call fprota(cos,sin,h(j),ax(irot,i2))
 
169
 230      continue
 
170
 240    continue
 
171
 250    if(nrold.eq.number) go to 270
 
172
 260    nrold = nrold+1
 
173
        go to 150
 
174
 270  continue
 
175
c  reduce the matrix (ay) to upper triangular form (ry) using givens
 
176
c  rotations. apply the same transformations to the columns of matrix g
 
177
c  to obtain the (ny-ky-1) x (nx-kx-1) matrix h.
 
178
c  store matrix (ry) into (ay) and h into c.
 
179
      ncof = nk1x*nk1y
 
180
c  initialization.
 
181
      do 280 i=1,ncof
 
182
        c(i) = 0.
 
183
 280  continue
 
184
      do 290 i=1,nk1y
 
185
        do 290 j=1,ky2
 
186
          ay(i,j) = 0.
 
187
 290  continue
 
188
      nrold = 0
 
189
c  ibandy denotes the bandwidth of the matrices (ay) and (ry).
 
190
      ibandy = ky1
 
191
      do 420 it=1,my
 
192
        number = nry(it)
 
193
 300    if(nrold.eq.number) go to 330
 
194
        if(p.le.0.) go to 410
 
195
        ibandy = ky2
 
196
c  fetch a new row of matrix (by).
 
197
        n1 = nrold+1
 
198
        do 310 j=1,ky2
 
199
          h(j) = by(n1,j)*pinv
 
200
 310    continue
 
201
c  find the appropiate row of g.
 
202
        do 320 j=1,nk1x
 
203
          right(j) = 0.
 
204
 320    continue
 
205
        irot = nrold
 
206
        go to 360
 
207
c  fetch a new row of matrix (spy)
 
208
 330    h(ibandy) = 0.
 
209
        do 340 j=1,ky1
 
210
          h(j) = spy(it,j)
 
211
 340    continue
 
212
c  find the appropiate row of g.
 
213
        l = it
 
214
        do 350 j=1,nk1x
 
215
          right(j) = q(l)
 
216
          l = l+my
 
217
 350    continue
 
218
        irot = number
 
219
c  rotate the new row of matrix (ay) into triangle.
 
220
 360    do 390 i=1,ibandy
 
221
          irot = irot+1
 
222
          piv = h(i)
 
223
          if(piv.eq.0.) go to 390
 
224
c  calculate the parameters of the givens transformation.
 
225
          call fpgivs(piv,ay(irot,1),cos,sin)
 
226
c  apply that transformation to the colums of matrix g.
 
227
          ic = irot
 
228
          do 370 j=1,nk1x
 
229
            call fprota(cos,sin,right(j),c(ic))
 
230
            ic = ic+nk1y
 
231
 370      continue
 
232
c  apply that transformation to the columns of matrix (ay).
 
233
          if(i.eq.ibandy) go to 400
 
234
          i2 = 1
 
235
          i3 = i+1
 
236
          do 380 j=i3,ibandy
 
237
            i2 = i2+1
 
238
            call fprota(cos,sin,h(j),ay(irot,i2))
 
239
 380      continue
 
240
 390    continue
 
241
 400    if(nrold.eq.number) go to 420
 
242
 410    nrold = nrold+1
 
243
        go to 300
 
244
 420  continue
 
245
c  backward substitution to obtain the b-spline coefficients as the
 
246
c  solution of the linear system    (ry) c (rx)' = h.
 
247
c  first step: solve the system  (ry) (c1) = h.
 
248
      k = 1
 
249
      do 450 i=1,nk1x
 
250
        call fpback(ay,c(k),nk1y,ibandy,c(k),ny)
 
251
        k = k+nk1y
 
252
 450  continue
 
253
c  second step: solve the system  c (rx)' = (c1).
 
254
      k = 0
 
255
      do 480 j=1,nk1y
 
256
        k = k+1
 
257
        l = k
 
258
        do 460 i=1,nk1x
 
259
          right(i) = c(l)
 
260
          l = l+nk1y
 
261
 460    continue
 
262
        call fpback(ax,right,nk1x,ibandx,right,nx)
 
263
        l = k
 
264
        do 470 i=1,nk1x
 
265
          c(l) = right(i)
 
266
          l = l+nk1y
 
267
 470    continue
 
268
 480  continue
 
269
c  calculate the quantities
 
270
c    res(i,j) = (z(i,j) - s(x(i),y(j)))**2 , i=1,2,..,mx;j=1,2,..,my
 
271
c    fp = sumi=1,mx(sumj=1,my(res(i,j)))
 
272
c    fpx(r) = sum''i(sumj=1,my(res(i,j))) , r=1,2,...,nx-2*kx-1
 
273
c                  tx(r+kx) <= x(i) <= tx(r+kx+1)
 
274
c    fpy(r) = sumi=1,mx(sum''j(res(i,j))) , r=1,2,...,ny-2*ky-1
 
275
c                  ty(r+ky) <= y(j) <= ty(r+ky+1)
 
276
      fp = 0.
 
277
      do 490 i=1,nx
 
278
        fpx(i) = 0.
 
279
 490  continue
 
280
      do 500 i=1,ny
 
281
        fpy(i) = 0.
 
282
 500  continue
 
283
      nk1y = ny-ky1
 
284
      iz = 0
 
285
      nroldx = 0
 
286
c  main loop for the different grid points.
 
287
      do 550 i1=1,mx
 
288
        numx = nrx(i1)
 
289
        numx1 = numx+1
 
290
        nroldy = 0
 
291
        do 540 i2=1,my
 
292
          numy = nry(i2)
 
293
          numy1 = numy+1
 
294
          iz = iz+1
 
295
c  evaluate s(x,y) at the current grid point by making the sum of the
 
296
c  cross products of the non-zero b-splines at (x,y), multiplied with
 
297
c  the appropiate b-spline coefficients.
 
298
          term = 0.
 
299
          k1 = numx*nk1y+numy
 
300
          do 520 l1=1,kx1
 
301
            k2 = k1
 
302
            fac = spx(i1,l1)
 
303
            do 510 l2=1,ky1
 
304
              k2 = k2+1
 
305
              term = term+fac*spy(i2,l2)*c(k2)
 
306
 510        continue
 
307
            k1 = k1+nk1y
 
308
 520      continue
 
309
c  calculate the squared residual at the current grid point.
 
310
          term = (z(iz)-term)**2
 
311
c  adjust the different parameters.
 
312
          fp = fp+term
 
313
          fpx(numx1) = fpx(numx1)+term
 
314
          fpy(numy1) = fpy(numy1)+term
 
315
          fac = term*half
 
316
          if(numy.eq.nroldy) go to 530
 
317
          fpy(numy1) = fpy(numy1)-fac
 
318
          fpy(numy) = fpy(numy)+fac
 
319
 530      nroldy = numy
 
320
          if(numx.eq.nroldx) go to 540
 
321
          fpx(numx1) = fpx(numx1)-fac
 
322
          fpx(numx) = fpx(numx)+fac
 
323
 540    continue
 
324
        nroldx = numx
 
325
 550  continue
 
326
      return
 
327
      end
 
328