~ubuntu-branches/ubuntu/oneiric/python-scipy/oneiric-proposed

« back to all changes in this revision

Viewing changes to Lib/sandbox/spline/fitpack/pogrid.f

  • Committer: Bazaar Package Importer
  • Author(s): Ondrej Certik
  • Date: 2008-06-16 22:58:01 UTC
  • mfrom: (2.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080616225801-irdhrpcwiocfbcmt
Tags: 0.6.0-12
* The description updated to match the current SciPy (Closes: #489149).
* Standards-Version bumped to 3.8.0 (no action needed)
* Build-Depends: netcdf-dev changed to libnetcdf-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
      subroutine pogrid(iopt,ider,mu,u,mv,v,z,z0,r,s,nuest,nvest,
2
 
     * nu,tu,nv,tv,c,fp,wrk,lwrk,iwrk,kwrk,ier)
3
 
c  subroutine pogrid fits a function f(x,y) to a set of data points
4
 
c  z(i,j) given at the nodes (x,y)=(u(i)*cos(v(j)),u(i)*sin(v(j))),
5
 
c  i=1,...,mu ; j=1,...,mv , of a radius-angle grid over a disc
6
 
c    x ** 2  +  y ** 2  <=  r ** 2 .
7
 
c
8
 
c  this approximation problem is reduced to the determination of a
9
 
c  bicubic spline s(u,v) smoothing the data (u(i),v(j),z(i,j)) on the
10
 
c  rectangle 0<=u<=r, v(1)<=v<=v(1)+2*pi
11
 
c  in order to have continuous partial derivatives
12
 
c              i+j
13
 
c             d   f(0,0)
14
 
c    g(i,j) = ----------
15
 
c                i   j
16
 
c              dx  dy
17
 
c
18
 
c  s(u,v)=f(x,y) must satisfy the following conditions
19
 
c
20
 
c    (1) s(0,v) = g(0,0)   v(1)<=v<= v(1)+2*pi
21
 
c
22
 
c        d s(0,v)
23
 
c    (2) -------- = cos(v)*g(1,0)+sin(v)*g(0,1)  v(1)<=v<= v(1)+2*pi
24
 
c        d u
25
 
c
26
 
c  moreover, s(u,v) must be periodic in the variable v, i.e.
27
 
c
28
 
c         j            j
29
 
c        d s(u,vb)   d s(u,ve)
30
 
c    (3) ---------- = ---------   0 <=u<= r, j=0,1,2 , vb=v(1),
31
 
c           j            j                             ve=vb+2*pi
32
 
c        d v          d v
33
 
c
34
 
c  the number of knots of s(u,v) and their position tu(i),i=1,2,...,nu;
35
 
c  tv(j),j=1,2,...,nv, is chosen automatically by the routine. the
36
 
c  smoothness of s(u,v) is achieved by minimalizing the discontinuity
37
 
c  jumps of the derivatives of the spline at the knots. the amount of
38
 
c  smoothness of s(u,v) is determined by the condition that
39
 
c  fp=sumi=1,mu(sumj=1,mv((z(i,j)-s(u(i),v(j)))**2))+(z0-g(0,0))**2<=s,
40
 
c  with s a given non-negative constant.
41
 
c  the fit s(u,v) is given in its b-spline representation and can be
42
 
c  evaluated by means of routine bispev. f(x,y) = s(u,v) can also be
43
 
c  evaluated by means of function program evapol.
44
 
c
45
 
c calling sequence:
46
 
c     call pogrid(iopt,ider,mu,u,mv,v,z,z0,r,s,nuest,nvest,nu,tu,
47
 
c    *  ,nv,tv,c,fp,wrk,lwrk,iwrk,kwrk,ier)
48
 
c
49
 
c parameters:
50
 
c  iopt  : integer array of dimension 3, specifying different options.
51
 
c          unchanged on exit.
52
 
c  iopt(1):on entry iopt(1) must specify whether a least-squares spline
53
 
c          (iopt(1)=-1) or a smoothing spline (iopt(1)=0 or 1) must be
54
 
c          determined.
55
 
c          if iopt(1)=0 the routine will start with an initial set of
56
 
c          knots tu(i)=0,tu(i+4)=r,i=1,...,4;tv(i)=v(1)+(i-4)*2*pi,i=1,.
57
 
c          ...,8.
58
 
c          if iopt(1)=1 the routine will continue with the set of knots
59
 
c          found at the last call of the routine.
60
 
c          attention: a call with iopt(1)=1 must always be immediately
61
 
c          preceded by another call with iopt(1) = 1 or iopt(1) = 0.
62
 
c  iopt(2):on entry iopt(2) must specify the requested order of conti-
63
 
c          nuity for f(x,y) at the origin.
64
 
c          if iopt(2)=0 only condition (1) must be fulfilled and
65
 
c          if iopt(2)=1 conditions (1)+(2) must be fulfilled.
66
 
c  iopt(3):on entry iopt(3) must specify whether (iopt(3)=1) or not
67
 
c          (iopt(3)=0) the approximation f(x,y) must vanish at the
68
 
c          boundary of the approximation domain.
69
 
c  ider  : integer array of dimension 2, specifying different options.
70
 
c          unchanged on exit.
71
 
c  ider(1):on entry ider(1) must specify whether (ider(1)=0 or 1) or not
72
 
c          (ider(1)=-1) there is a data value z0 at the origin.
73
 
c          if ider(1)=1, z0 will be considered to be the right function
74
 
c          value, and it will be fitted exactly (g(0,0)=z0=c(1)).
75
 
c          if ider(1)=0, z0 will be considered to be a data value just
76
 
c          like the other data values z(i,j).
77
 
c  ider(2):on entry ider(2) must specify whether (ider(2)=1) or not
78
 
c          (ider(2)=0) f(x,y) must have vanishing partial derivatives
79
 
c          g(1,0) and g(0,1) at the origin. (in case iopt(2)=1)
80
 
c  mu    : integer. on entry mu must specify the number of grid points
81
 
c          along the u-axis. unchanged on exit.
82
 
c          mu >= mumin where mumin=4-iopt(3)-ider(2) if ider(1)<0
83
 
c                                 =3-iopt(3)-ider(2) if ider(1)>=0
84
 
c  u     : real array of dimension at least (mu). before entry, u(i)
85
 
c          must be set to the u-co-ordinate of the i-th grid point
86
 
c          along the u-axis, for i=1,2,...,mu. these values must be
87
 
c          positive and supplied in strictly ascending order.
88
 
c          unchanged on exit.
89
 
c  mv    : integer. on entry mv must specify the number of grid points
90
 
c          along the v-axis. mv > 3 . unchanged on exit.
91
 
c  v     : real array of dimension at least (mv). before entry, v(j)
92
 
c          must be set to the v-co-ordinate of the j-th grid point
93
 
c          along the v-axis, for j=1,2,...,mv. these values must be
94
 
c          supplied in strictly ascending order. unchanged on exit.
95
 
c          -pi <= v(1) < pi , v(mv) < v(1)+2*pi.
96
 
c  z     : real array of dimension at least (mu*mv).
97
 
c          before entry, z(mv*(i-1)+j) must be set to the data value at
98
 
c          the grid point (u(i),v(j)) for i=1,...,mu and j=1,...,mv.
99
 
c          unchanged on exit.
100
 
c  z0    : real value. on entry (if ider(1) >=0 ) z0 must specify the
101
 
c          data value at the origin. unchanged on exit.
102
 
c  r     : real value. on entry r must specify the radius of the disk.
103
 
c          r>=u(mu) (>u(mu) if iopt(3)=1). unchanged on exit.
104
 
c  s     : real. on entry (if iopt(1)>=0) s must specify the smoothing
105
 
c          factor. s >=0. unchanged on exit.
106
 
c          for advice on the choice of s see further comments
107
 
c  nuest : integer. unchanged on exit.
108
 
c  nvest : integer. unchanged on exit.
109
 
c          on entry, nuest and nvest must specify an upper bound for the
110
 
c          number of knots required in the u- and v-directions respect.
111
 
c          these numbers will also determine the storage space needed by
112
 
c          the routine. nuest >= 8, nvest >= 8.
113
 
c          in most practical situation nuest = mu/2, nvest=mv/2, will
114
 
c          be sufficient. always large enough are nuest=mu+5+iopt(2)+
115
 
c          iopt(3), nvest = mv+7, the number of knots needed for
116
 
c          interpolation (s=0). see also further comments.
117
 
c  nu    : integer.
118
 
c          unless ier=10 (in case iopt(1)>=0), nu will contain the total
119
 
c          number of knots with respect to the u-variable, of the spline
120
 
c          approximation returned. if the computation mode iopt(1)=1 is
121
 
c          used, the value of nu should be left unchanged between sub-
122
 
c          sequent calls. in case iopt(1)=-1, the value of nu should be
123
 
c          specified on entry.
124
 
c  tu    : real array of dimension at least (nuest).
125
 
c          on succesful exit, this array will contain the knots of the
126
 
c          spline with respect to the u-variable, i.e. the position of
127
 
c          the interior knots tu(5),...,tu(nu-4) as well as the position
128
 
c          of the additional knots tu(1)=...=tu(4)=0 and tu(nu-3)=...=
129
 
c          tu(nu)=r needed for the b-spline representation.
130
 
c          if the computation mode iopt(1)=1 is used,the values of tu(1)
131
 
c          ...,tu(nu) should be left unchanged between subsequent calls.
132
 
c          if the computation mode iopt(1)=-1 is used, the values tu(5),
133
 
c          ...tu(nu-4) must be supplied by the user, before entry.
134
 
c          see also the restrictions (ier=10).
135
 
c  nv    : integer.
136
 
c          unless ier=10 (in case iopt(1)>=0), nv will contain the total
137
 
c          number of knots with respect to the v-variable, of the spline
138
 
c          approximation returned. if the computation mode iopt(1)=1 is
139
 
c          used, the value of nv should be left unchanged between sub-
140
 
c          sequent calls. in case iopt(1) = -1, the value of nv should
141
 
c          be specified on entry.
142
 
c  tv    : real array of dimension at least (nvest).
143
 
c          on succesful exit, this array will contain the knots of the
144
 
c          spline with respect to the v-variable, i.e. the position of
145
 
c          the interior knots tv(5),...,tv(nv-4) as well as the position
146
 
c          of the additional knots tv(1),...,tv(4) and tv(nv-3),...,
147
 
c          tv(nv) needed for the b-spline representation.
148
 
c          if the computation mode iopt(1)=1 is used,the values of tv(1)
149
 
c          ...,tv(nv) should be left unchanged between subsequent calls.
150
 
c          if the computation mode iopt(1)=-1 is used, the values tv(5),
151
 
c          ...tv(nv-4) must be supplied by the user, before entry.
152
 
c          see also the restrictions (ier=10).
153
 
c  c     : real array of dimension at least (nuest-4)*(nvest-4).
154
 
c          on succesful exit, c contains the coefficients of the spline
155
 
c          approximation s(u,v)
156
 
c  fp    : real. unless ier=10, fp contains the sum of squared
157
 
c          residuals of the spline approximation returned.
158
 
c  wrk   : real array of dimension (lwrk). used as workspace.
159
 
c          if the computation mode iopt(1)=1 is used the values of
160
 
c          wrk(1),...,wrk(8) should be left unchanged between subsequent
161
 
c          calls.
162
 
c  lwrk  : integer. on entry lwrk must specify the actual dimension of
163
 
c          the array wrk as declared in the calling (sub)program.
164
 
c          lwrk must not be too small.
165
 
c           lwrk >= 8+nuest*(mv+nvest+3)+nvest*21+4*mu+6*mv+q
166
 
c           where q is the larger of (mv+nvest) and nuest.
167
 
c  iwrk  : integer array of dimension (kwrk). used as workspace.
168
 
c          if the computation mode iopt(1)=1 is used the values of
169
 
c          iwrk(1),.,iwrk(4) should be left unchanged between subsequent
170
 
c          calls.
171
 
c  kwrk  : integer. on entry kwrk must specify the actual dimension of
172
 
c          the array iwrk as declared in the calling (sub)program.
173
 
c          kwrk >= 4+mu+mv+nuest+nvest.
174
 
c  ier   : integer. unless the routine detects an error, ier contains a
175
 
c          non-positive value on exit, i.e.
176
 
c   ier=0  : normal return. the spline returned has a residual sum of
177
 
c            squares fp such that abs(fp-s)/s <= tol with tol a relat-
178
 
c            ive tolerance set to 0.001 by the program.
179
 
c   ier=-1 : normal return. the spline returned is an interpolating
180
 
c            spline (fp=0).
181
 
c   ier=-2 : normal return. the spline returned is the least-squares
182
 
c            constrained polynomial. in this extreme case fp gives the
183
 
c            upper bound for the smoothing factor s.
184
 
c   ier=1  : error. the required storage space exceeds the available
185
 
c            storage space, as specified by the parameters nuest and
186
 
c            nvest.
187
 
c            probably causes : nuest or nvest too small. if these param-
188
 
c            eters are already large, it may also indicate that s is
189
 
c            too small
190
 
c            the approximation returned is the least-squares spline
191
 
c            according to the current set of knots. the parameter fp
192
 
c            gives the corresponding sum of squared residuals (fp>s).
193
 
c   ier=2  : error. a theoretically impossible result was found during
194
 
c            the iteration proces for finding a smoothing spline with
195
 
c            fp = s. probably causes : s too small.
196
 
c            there is an approximation returned but the corresponding
197
 
c            sum of squared residuals does not satisfy the condition
198
 
c            abs(fp-s)/s < tol.
199
 
c   ier=3  : error. the maximal number of iterations maxit (set to 20
200
 
c            by the program) allowed for finding a smoothing spline
201
 
c            with fp=s has been reached. probably causes : s too small
202
 
c            there is an approximation returned but the corresponding
203
 
c            sum of squared residuals does not satisfy the condition
204
 
c            abs(fp-s)/s < tol.
205
 
c   ier=10 : error. on entry, the input data are controlled on validity
206
 
c            the following restrictions must be satisfied.
207
 
c            -1<=iopt(1)<=1, 0<=iopt(2)<=1, 0<=iopt(3)<=1,
208
 
c            -1<=ider(1)<=1, 0<=ider(2)<=1, ider(2)=0 if iopt(2)=0.
209
 
c            mu >= mumin (see above), mv >= 4, nuest >=8, nvest >= 8,
210
 
c            kwrk>=4+mu+mv+nuest+nvest,
211
 
c            lwrk >= 8+nuest*(mv+nvest+3)+nvest*21+4*mu+6*mv+
212
 
c             max(nuest,mv+nvest)
213
 
c            0< u(i-1)<u(i)<=r,i=2,..,mu, (< r if iopt(3)=1)
214
 
c            -pi<=v(1)< pi, v(1)<v(i-1)<v(i)<v(1)+2*pi, i=3,...,mv
215
 
c            if iopt(1)=-1: 8<=nu<=min(nuest,mu+5+iopt(2)+iopt(3))
216
 
c                           0<tu(5)<tu(6)<...<tu(nu-4)<r
217
 
c                           8<=nv<=min(nvest,mv+7)
218
 
c                           v(1)<tv(5)<tv(6)<...<tv(nv-4)<v(1)+2*pi
219
 
c                    the schoenberg-whitney conditions, i.e. there must
220
 
c                    be subset of grid co-ordinates uu(p) and vv(q) such
221
 
c                    that   tu(p) < uu(p) < tu(p+4) ,p=1,...,nu-4
222
 
c                     (iopt(2)=1 and iopt(3)=1 also count for a uu-value
223
 
c                           tv(q) < vv(q) < tv(q+4) ,q=1,...,nv-4
224
 
c                     (vv(q) is either a value v(j) or v(j)+2*pi)
225
 
c            if iopt(1)>=0: s>=0
226
 
c                       if s=0: nuest>=mu+5+iopt(2)+iopt(3), nvest>=mv+7
227
 
c            if one of these conditions is found to be violated,control
228
 
c            is immediately repassed to the calling program. in that
229
 
c            case there is no approximation returned.
230
 
c
231
 
c further comments:
232
 
c   pogrid does not allow individual weighting of the data-values.
233
 
c   so, if these were determined to widely different accuracies, then
234
 
c   perhaps the general data set routine polar should rather be used
235
 
c   in spite of efficiency.
236
 
c   by means of the parameter s, the user can control the tradeoff
237
 
c   between closeness of fit and smoothness of fit of the approximation.
238
 
c   if s is too large, the spline will be too smooth and signal will be
239
 
c   lost ; if s is too small the spline will pick up too much noise. in
240
 
c   the extreme cases the program will return an interpolating spline if
241
 
c   s=0 and the constrained least-squares polynomial(degrees 3,0)if s is
242
 
c   very large. between these extremes, a properly chosen s will result
243
 
c   in a good compromise between closeness of fit and smoothness of fit.
244
 
c   to decide whether an approximation, corresponding to a certain s is
245
 
c   satisfactory the user is highly recommended to inspect the fits
246
 
c   graphically.
247
 
c   recommended values for s depend on the accuracy of the data values.
248
 
c   if the user has an idea of the statistical errors on the data, he
249
 
c   can also find a proper estimate for s. for, by assuming that, if he
250
 
c   specifies the right s, pogrid will return a spline s(u,v) which
251
 
c   exactly reproduces the function underlying the data he can evaluate
252
 
c   the sum((z(i,j)-s(u(i),v(j)))**2) to find a good estimate for this s
253
 
c   for example, if he knows that the statistical errors on his z(i,j)-
254
 
c   values is not greater than 0.1, he may expect that a good s should
255
 
c   have a value not larger than mu*mv*(0.1)**2.
256
 
c   if nothing is known about the statistical error in z(i,j), s must
257
 
c   be determined by trial and error, taking account of the comments
258
 
c   above. the best is then to start with a very large value of s (to
259
 
c   determine the least-squares polynomial and the corresponding upper
260
 
c   bound fp0 for s) and then to progressively decrease the value of s
261
 
c   ( say by a factor 10 in the beginning, i.e. s=fp0/10,fp0/100,...
262
 
c   and more carefully as the approximation shows more detail) to
263
 
c   obtain closer fits.
264
 
c   to economize the search for a good s-value the program provides with
265
 
c   different modes of computation. at the first call of the routine, or
266
 
c   whenever he wants to restart with the initial set of knots the user
267
 
c   must set iopt(1)=0.
268
 
c   if iopt(1) = 1 the program will continue with the knots found at
269
 
c   the last call of the routine. this will save a lot of computation
270
 
c   time if pogrid is called repeatedly for different values of s.
271
 
c   the number of knots of the spline returned and their location will
272
 
c   depend on the value of s and on the complexity of the shape of the
273
 
c   function underlying the data. if the computation mode iopt(1) = 1
274
 
c   is used, the knots returned may also depend on the s-values at
275
 
c   previous calls (if these were smaller). therefore, if after a number
276
 
c   of trials with different s-values and iopt(1)=1,the user can finally
277
 
c   accept a fit as satisfactory, it may be worthwhile for him to call
278
 
c   pogrid once more with the chosen value for s but now with iopt(1)=0.
279
 
c   indeed, pogrid may then return an approximation of the same quality
280
 
c   of fit but with fewer knots and therefore better if data reduction
281
 
c   is also an important objective for the user.
282
 
c   the number of knots may also depend on the upper bounds nuest and
283
 
c   nvest. indeed, if at a certain stage in pogrid the number of knots
284
 
c   in one direction (say nu) has reached the value of its upper bound
285
 
c   (nuest), then from that moment on all subsequent knots are added
286
 
c   in the other (v) direction. this may indicate that the value of
287
 
c   nuest is too small. on the other hand, it gives the user the option
288
 
c   of limiting the number of knots the routine locates in any direction
289
 
c   for example, by setting nuest=8 (the lowest allowable value for
290
 
c   nuest), the user can indicate that he wants an approximation which
291
 
c   is a simple cubic polynomial in the variable u.
292
 
c
293
 
c  other subroutines required:
294
 
c    fppogr,fpchec,fpchep,fpknot,fpopdi,fprati,fpgrdi,fpsysy,fpback,
295
 
c    fpbacp,fpbspl,fpcyt1,fpcyt2,fpdisc,fpgivs,fprota
296
 
c
297
 
c  references:
298
 
c   dierckx p. : fast algorithms for smoothing data over a disc or a
299
 
c                sphere using tensor product splines, in "algorithms
300
 
c                for approximation", ed. j.c.mason and m.g.cox,
301
 
c                clarendon press oxford, 1987, pp. 51-65
302
 
c   dierckx p. : fast algorithms for smoothing data over a disc or a
303
 
c                sphere using tensor product splines, report tw73, dept.
304
 
c                computer science,k.u.leuven, 1985.
305
 
c   dierckx p. : curve and surface fitting with splines, monographs on
306
 
c                numerical analysis, oxford university press, 1993.
307
 
c
308
 
c  author:
309
 
c    p.dierckx
310
 
c    dept. computer science, k.u. leuven
311
 
c    celestijnenlaan 200a, b-3001 heverlee, belgium.
312
 
c    e-mail : Paul.Dierckx@cs.kuleuven.ac.be
313
 
c
314
 
c  creation date : july 1985
315
 
c  latest update : march 1989
316
 
c
317
 
c  ..
318
 
c  ..scalar arguments..
319
 
      real*8 z0,r,s,fp
320
 
      integer mu,mv,nuest,nvest,nu,nv,lwrk,kwrk,ier
321
 
c  ..array arguments..
322
 
      integer iopt(3),ider(2),iwrk(kwrk)
323
 
      real*8 u(mu),v(mv),z(mu*mv),c((nuest-4)*(nvest-4)),tu(nuest),
324
 
     * tv(nvest),wrk(lwrk)
325
 
c  ..local scalars..
326
 
      real*8 per,pi,tol,uu,ve,zmax,zmin,one,half,rn,zb
327
 
      integer i,i1,i2,j,jwrk,j1,j2,kndu,kndv,knru,knrv,kwest,l,
328
 
     * ldz,lfpu,lfpv,lwest,lww,m,maxit,mumin,muu,nc
329
 
c  ..function references..
330
 
      real*8 datan2
331
 
      integer max0
332
 
c  ..subroutine references..
333
 
c    fpchec,fpchep,fppogr
334
 
c  ..
335
 
c  set constants
336
 
      one = 1d0
337
 
      half = 0.5e0
338
 
      pi = datan2(0d0,-one)
339
 
      per = pi+pi
340
 
      ve = v(1)+per
341
 
c  we set up the parameters tol and maxit.
342
 
      maxit = 20
343
 
      tol = 0.1e-02
344
 
c  before starting computations, a data check is made. if the input data
345
 
c  are invalid, control is immediately repassed to the calling program.
346
 
      ier = 10
347
 
      if(iopt(1).lt.(-1) .or. iopt(1).gt.1) go to 200
348
 
      if(iopt(2).lt.0 .or. iopt(2).gt.1) go to 200
349
 
      if(iopt(3).lt.0 .or. iopt(3).gt.1) go to 200
350
 
      if(ider(1).lt.(-1) .or. ider(1).gt.1) go to 200
351
 
      if(ider(2).lt.0 .or. ider(2).gt.1) go to 200
352
 
      if(ider(2).eq.1 .and. iopt(2).eq.0) go to 200
353
 
      mumin = 4-iopt(3)-ider(2)
354
 
      if(ider(1).ge.0) mumin = mumin-1
355
 
      if(mu.lt.mumin .or. mv.lt.4) go to 200
356
 
      if(nuest.lt.8 .or. nvest.lt.8) go to 200
357
 
      m = mu*mv
358
 
      nc = (nuest-4)*(nvest-4)
359
 
      lwest = 8+nuest*(mv+nvest+3)+21*nvest+4*mu+6*mv+
360
 
     * max0(nuest,mv+nvest)
361
 
      kwest = 4+mu+mv+nuest+nvest
362
 
      if(lwrk.lt.lwest .or. kwrk.lt.kwest) go to 200
363
 
      if(u(1).le.0. .or. u(mu).gt.r) go to 200
364
 
      if(iopt(3).eq.0) go to 10
365
 
      if(u(mu).eq.r) go to 200
366
 
  10  if(mu.eq.1) go to 30
367
 
      do 20 i=2,mu
368
 
        if(u(i-1).ge.u(i)) go to 200
369
 
  20  continue
370
 
  30  if(v(1).lt. (-pi) .or. v(1).ge.pi ) go to 200
371
 
      if(v(mv).ge.v(1)+per) go to 200
372
 
      do 40 i=2,mv
373
 
        if(v(i-1).ge.v(i)) go to 200
374
 
  40  continue
375
 
      if(iopt(1).gt.0) go to 140
376
 
c  if not given, we compute an estimate for z0.
377
 
      if(ider(1).lt.0) go to 50
378
 
      zb = z0
379
 
      go to 70
380
 
  50  zb = 0.
381
 
      do 60 i=1,mv
382
 
         zb = zb+z(i)
383
 
  60  continue
384
 
      rn = mv
385
 
      zb = zb/rn
386
 
c  we determine the range of z-values.
387
 
  70  zmin = zb
388
 
      zmax = zb
389
 
      do 80 i=1,m
390
 
         if(z(i).lt.zmin) zmin = z(i)
391
 
         if(z(i).gt.zmax) zmax = z(i)
392
 
  80  continue
393
 
      wrk(5) = zb
394
 
      wrk(6) = 0.
395
 
      wrk(7) = 0.
396
 
      wrk(8) = zmax -zmin
397
 
      iwrk(4) = mu
398
 
      if(iopt(1).eq.0) go to 140
399
 
      if(nu.lt.8 .or. nu.gt.nuest) go to 200
400
 
      if(nv.lt.11 .or. nv.gt.nvest) go to 200
401
 
      j = nu
402
 
      do 90 i=1,4
403
 
        tu(i) = 0.
404
 
        tu(j) = r
405
 
        j = j-1
406
 
  90  continue
407
 
      l = 9
408
 
      wrk(l) = 0.
409
 
      if(iopt(2).eq.0) go to 100
410
 
      l = l+1
411
 
      uu = u(1)
412
 
      if(uu.gt.tu(5)) uu = tu(5)
413
 
      wrk(l) = uu*half
414
 
 100  do 110 i=1,mu
415
 
        l = l+1
416
 
        wrk(l) = u(i)
417
 
 110  continue
418
 
      if(iopt(3).eq.0) go to 120
419
 
      l = l+1
420
 
      wrk(l) = r
421
 
 120  muu = l-8
422
 
      call fpchec(wrk(9),muu,tu,nu,3,ier)
423
 
      if(ier.ne.0) go to 200
424
 
      j1 = 4
425
 
      tv(j1) = v(1)
426
 
      i1 = nv-3
427
 
      tv(i1) = ve
428
 
      j2 = j1
429
 
      i2 = i1
430
 
      do 130 i=1,3
431
 
        i1 = i1+1
432
 
        i2 = i2-1
433
 
        j1 = j1+1
434
 
        j2 = j2-1
435
 
        tv(j2) = tv(i2)-per
436
 
        tv(i1) = tv(j1)+per
437
 
 130  continue
438
 
      l = 9
439
 
      do 135 i=1,mv
440
 
        wrk(l) = v(i)
441
 
        l = l+1
442
 
 135  continue
443
 
      wrk(l) = ve
444
 
      call fpchep(wrk(9),mv+1,tv,nv,3,ier)
445
 
      if (ier.eq.0) go to 150
446
 
      go to 200
447
 
 140  if(s.lt.0.) go to 200
448
 
      if(s.eq.0. .and. (nuest.lt.(mu+5+iopt(2)+iopt(3)) .or.
449
 
     * nvest.lt.(mv+7)) ) go to 200
450
 
c  we partition the working space and determine the spline approximation
451
 
 150  ldz = 5
452
 
      lfpu = 9
453
 
      lfpv = lfpu+nuest
454
 
      lww = lfpv+nvest
455
 
      jwrk = lwrk-8-nuest-nvest
456
 
      knru = 5
457
 
      knrv = knru+mu
458
 
      kndu = knrv+mv
459
 
      kndv = kndu+nuest
460
 
      call fppogr(iopt,ider,u,mu,v,mv,z,m,zb,r,s,nuest,nvest,tol,maxit,
461
 
     * nc,nu,tu,nv,tv,c,fp,wrk(1),wrk(2),wrk(3),wrk(4),wrk(lfpu),
462
 
     * wrk(lfpv),wrk(ldz),wrk(8),iwrk(1),iwrk(2),iwrk(3),iwrk(4),
463
 
     * iwrk(knru),iwrk(knrv),iwrk(kndu),iwrk(kndv),wrk(lww),jwrk,ier)
464
 
 200  return
465
 
      end
466