[go: up one dir, main page]

File: avas.f

package info (click to toggle)
acepack 1.3.3.3-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 240 kB
  • ctags: 349
  • sloc: fortran: 1,349; makefile: 1
file content (704 lines) | stat: -rw-r--r-- 17,669 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
      subroutine avas(p,n,x,y,w,l,delrsq,tx,ty,rsq,ierr,m,z,yspan,iter,
     1 iters)
      integer p,pp1,pp2,m(n,*),l(*)
      double precision y(n),x(n,p),w(n),ty(n),tx(n,p),z(n,17),ct(10)
      double precision iters(100,2), delrsq, rsq, yspan, rss
      common /parms/ itape,maxit,nterm,span,alpha
      double precision sm,sv,sw,svx
      ierr = 0
      pp1 = p+1
      pp2 = p + 2
      sm = 0.0
      sv = sm
      sw = sv
      np = 0
      do 23000 i = 1,p
      if(.not.(l(i).gt.0))goto 23002
      np = np+1
23002 continue
23000 continue
      do 23004 j = 1,n
      sm = sm+w(j)*y(j)
      sv = sv+w(j)*y(j)**2
      sw = sw+w(j)
      m(j,pp1) = j
      z(j,2) = y(j)
23004 continue
      sm = sm/sw
      sv = sv/sw-sm**2
      sv = 1.0/dsqrt(sv)
      do 23006 j = 1,n
      z(j,1) = (y(j)-sm)*sv
23006 continue
      call sort(z(1,2),m(1,pp1),1,n)
      do 23008 i = 1,p
      if(.not.(l(i) .gt. 0))goto 23010
      sm=0
      do 23012 j=1,n
      sm=sm+w(j)*x(j,i)
23012 continue
      sm=sm/sw
      do 23014 j = 1,n
      m(j,i) = j
      z(j,2) = x(j,i)
23014 continue
      call sort(z(1,2),m(1,i),1,n)
23010 continue
23008 continue
      rsq = 0.0
      iter = 0
      nterm = min0(nterm,10)
      nt = 0
      do 23016 i = 1,nterm
      ct(i) = 100.0
23016 continue
      do 23018 j=1,n
      ty(j)=z(j,1)
23018 continue
      do 23020 j = 1,n
      z(j,9)=ty(j)
23020 continue
      call bakfit(iter,delrsq,rsq,sw,l,z,m,x,z(1,9),tx,w,n,p,np)
      sumlog=0
23022 continue
      iter=iter +1
      if(.not.(l(pp1).eq.4))goto 23025
      go to 992
23025 continue
      call calcmu(n,p,l,z,tx)
      do 23027 j=1,n
      tres=(ty(j)-z(j,10))
      if(.not.(abs(tres).lt.1e-10))goto 23029
      tres=1e-10
23029 continue
      z(j,2)=log(sqrt(tres**2))
      m(j,pp2)=j
23027 continue
      call sort(z(1,10),m(1,pp2),1,n)
      do 23031 j=1,n
      k=m(j,pp2)
      z(j,4)=z(k,2)
      z(j,5)=w(k)
23031 continue
c NB: rss is double precision, dof is not.
      call rlsmo(z(1,10),z(1,4),z(1,5),yspan,dof,n,z(1,6),rss,z(1,7))
      do 23033 j=1,n
      k=m(j,pp2)
      z(j,7)=exp(-z(j,6))
      sumlog=sumlog+n*(w(j)/sw)*2*z(j,6)
      z(j,8)=ty(k)
23033 continue
      call ctsub(n,z(1,10),z(1,7),z(1,8),z(1,9))
      sm=0
      do 23035 j=1,n
      sm=sm+w(j)*z(j,9)
23035 continue
      do 23037 j=1,n
      k=m(j,pp2)
      ty(k)=z(j,9)-sm/sw
23037 continue
      sv=0
      svx=0
      do 23039 j=1,n
      sv=sv+(w(j)/sw)*ty(j)*ty(j)
      svx=svx+(w(j)/sw)*z(j,10)*z(j,10)
23039 continue
      do 23041 j=1,n
      ty(j)=ty(j)/dsqrt(sv)
      do 23043 i=1,p
      if(.not.( l(i) .gt. 0))goto 23045
      tx(j,i)=tx(j,i)/dsqrt(svx)
23045 continue
23043 continue
23041 continue
992   continue
      do 23047 j = 1,n
      z(j,9)=ty(j)
23047 continue
      call bakfit(iter,delrsq,rsq,sw,l,z,m,x,z(1,9),tx,w,n,p,np)
      sumlog=sumlog+n*dlog(sv)
      rr=0
      call calcmu(n,p,l,z,tx)
      do 23049 j=1,n
      rr=rr+(w(j)/sw)*(ty(j)-z(j,10))**2
23049 continue
      rsq=1-rr
      rnew=sumlog+rr
      iters(iter,1)=iter
      iters(iter,2)=rsq
      nt = mod(nt,nterm)+1
      ct(nt) = rsq
      cmn = 100.0
      cmx = -100.0
      do 23051 i = 1,nterm
      cmn = min(cmn,ct(i))
      cmx = max(cmx,ct(i))
23051 continue
      if(.not.(cmx-cmn.le.delrsq.or.iter.ge.maxit.or.l(pp1).eq.4))
     1 goto 23053
      return
23053 continue
23023 goto 23022
      return
      end
      subroutine calcmu(n,p,l,z,tx)
      integer p, l(*)
      double precision z(n,17),tx(n,p)
      do 23055 j=1,n
      z(j,10)=0
      do 23057 i=1,p
      if(.not.(l(i) .gt. 0))goto 23059
      z(j,10)=z(j,10)+tx(j,i)
23059 continue
23057 continue
23055 continue
      return
      end
      subroutine bakfit(iter,delrsq,rsq,sw,l,z,m,x,ty,tx,w,n,p,np)
      integer l(*),m(n,*),p
      double precision z(n,17),ty(n),tx(n,p),x(n,p),w(n)
      double precision sm,sv,sw, delrsq, rsq
      common /parms/ itape,maxit,nterm,span,alpha
      call calcmu(n,p,l,z,tx)
      do 23061 j=1,n
      ty(j)=ty(j)-z(j,10)
23061 continue
      nit=0
23063 continue
      rsqi = rsq
      nit = nit+1
      do 23066 i = 1,p
      if(.not.(l(i).gt.0))goto 23068
      do 23070 j = 1,n
      k = m(j,i)
      z(j,1) = ty(k)+tx(k,i)
      z(j,2) = x(k,i)
      z(j,7) = w(k)
23070 continue
      call smothr(l(i),n,z(1,2),z,z(1,7),z(1,6),z(1,11))
      sm = 0.0
      do 23072 j = 1,n
      sm = sm+z(j,7)*z(j,6)
23072 continue
      sm = sm/sw
      do 23074 j = 1,n
      z(j,6) = z(j,6)-sm
23074 continue
      sv = 0.0
      do 23076 j = 1,n
      sv = sv+z(j,7)*(z(j,1)-z(j,6))**2
23076 continue
      sv = 1.0-sv/sw
      rsq = sv
      do 23078 j = 1,n
      k = m(j,i)
      tx(k,i) = z(j,6)
      ty(k) = z(j,1)-z(j,6)
23078 continue
23068 continue
23066 continue
23064 if(.not.(np.eq.1.or.abs(rsq-rsqi).le.delrsq.or.nit.ge.maxit))
     1 goto 23063
      if(.not.(rsq.eq.0.0.and.iter.eq.0))goto 23080
      do 23082 i = 1,p
      if(.not.(l(i).gt.0))goto 23084
      do 23086 j = 1,n
      tx(j,i) = x(j,i)
23086 continue
23084 continue
23082 continue
23080 continue
      return
      end
      subroutine ctsub(n,u,v,y,ty)
      double precision u(*),v(*),y(*),ty(*)
      i=1
23088 if(.not.(i.le.n))goto 23090
      if(.not.(y(i).le.u(1)))goto 23091
      ty(i)=(y(i)-u(1))*v(1)
      goto 23092
23091 continue
      j=1
      ty(i)=0
23093 if(.not.((j.le.n) .and. (y(i).gt.u(j)) ))goto 23094
      if(.not.(j .gt. 1))goto 23095
      ty(i)=ty(i)+(u(j)-u(j-1))*(v(j)+v(j-1))/2
23095 continue
      j=j+1
      goto 23093
23094 continue
      if(.not.(y(i).le.u(n)))goto 23097
      ty(i)=ty(i)+.5*(y(i)-u(j-1))*(2*v(j-1)+(y(i)-u(j-1))*(v(j)-v(j-1))
     1 /(u(j)-u(j-1)))
      goto 23098
23097 continue
      ty(i)=ty(i)+(y(i)-u(n))*v(n)
23098 continue
23092 continue
      i=i+1
      goto 23088
23090 continue
      return
      end
      block data avasdata
      common /parms/ itape,maxit,nterm,span,alpha
      common /spans/ spans(3) /consts/ big,sml,eps
c------------------------------------------------------------------
c
c these procedure parameters can be changed in the calling routine
c by defining the above labeled common and resetting the values with
c executable statements.
c
c itape : fortran file number for printer output.
c         (itape.le.0 => no printer output.)
c maxit : maximum number of iterations.
c nterm : number of consecutive iterations for which
c         rsq must change less than delcor for convergence.
c span, alpha : super smoother parameters.
c   (see - friedman and stuetzle, reference above.)
c
c------------------------------------------------------------------
      data itape,maxit,nterm,span,alpha /-6,20,3,0.0,5.0/
c---------------------------------------------------------------
c
c this sets the compile time (default) values for various
c internal parameters :
c
c spans : span values for the three running linear smoothers.
c spans(1) : tweeter span.
c spans(2) : midrange span.
c spans(3) : woofer span.
c (these span values should be changed only with care.)
c big : a large representable floating point number.
c sml : a small number. should be set so that (sml)**(10.0) does
c       not cause floating point underflow.
c eps : used to numerically stabilize slope calculations for
c       running linear fits.
c
c these parameter values can be changed by declaring the
c relevant labeled common in the main program and resetting
c them with executable statements.
c
c-----------------------------------------------------------------
      data spans,big,sml,eps /0.05,0.2,0.5,1.0e20,1.0e-4,1.0e-3/
      end
      subroutine smothr (l,n,x,y,w,smo,scr)
      double precision x(n),y(n),w(n),smo(n),scr(n,7)
      common /parms/ itape,maxit,nterm,span,alpha
      double precision sm,sw,a,b,d
      if (l.lt.5) go to 50
      j=1
 10   j0=j
      sm=w(j)*y(j)
      sw=w(j)
      if (j.ge.n) go to 30
 20   if (x(j+1).gt.x(j)) go to 30
      j=j+1
      sm=sm+w(j)*y(j)
      sw=sw+w(j)
      if (j.ge.n) go to 30
      go to 20
 30   sm=sm/sw
      do 40 i=j0,j
      smo(i)=sm
 40   continue
      j=j+1
      if (j.gt.n) go to 250
      go to 10
 50   if (l.ne.4) go to 80
      sm=0.0
      sw=sm
      b=sw
      d=b
      do 60 j=1,n
      sm=sm+w(j)*x(j)*y(j)
      sw=sw+w(j)*x(j)**2
      b=b+w(j)*x(j)
      d=d+w(j)
 60   continue
      a=sm/(sw-(b**2)/d)
      b=b/d
      do 70 j=1,n
      smo(j)=a*(x(j)-b)
 70   continue
      go to 250
 80   call supsmu (n,x,y,w,l,span,alpha,smo,scr)
      if (l.ne.3) go to 250
      do 90 j=1,n
      scr(j,1)=smo(j)
      scr(n-j+1,2)=scr(j,1)
 90   continue
      call montne (scr,n)
      call montne (scr(1,2),n)
      sm=0.0
      sw=sm
      do 100 j=1,n
      sm=sm+(smo(j)-scr(j,1))**2
      sw=sw+(smo(j)-scr(n-j+1,2))**2
 100  continue
      if (sm.ge.sw) go to 120
      do 110 j=1,n
      smo(j)=scr(j,1)
 110  continue
      go to 140
 120  do 130 j=1,n
      smo(j)=scr(n-j+1,2)
 130  continue
 140  j=1
 150  j0=j
      if (j.ge.n) go to 170
 160  if (smo(j+1).ne.smo(j)) go to 170
      j=j+1
      if (j.ge.n) go to 170
      go to 160
 170  if (j.le.j0) go to 190
      a=0.0
      if (j0.gt.1) a=0.5*(smo(j0)-smo(j0-1))
      b=0.0
      if (j.lt.n) b=0.5*(smo(j+1)-smo(j))
      d=(a+b)/(j-j0)
      if (a.eq.0.0.or.b.eq.0.0) d=2.0*d
      if (a.eq.0.0) a=b
      do 180 i=j0,j
      smo(i)=smo(i)-a+d*(i-j0)
 180  continue
 190  j=j+1
      if (j.gt.n) go to 200
      go to 150
 200  j=1
 210  j0=j
      sm=smo(j)
      if (j.ge.n) go to 230
 220  if (x(j+1).gt.x(j)) go to 230
      j=j+1
      sm=sm+smo(j)
      if (j.ge.n) go to 230
      go to 220
 230  sm=sm/(j-j0+1)
      do 240 i=j0,j
      smo(i)=sm
 240  continue
      j=j+1
      if (j.gt.n) go to 250
      go to 210
 250  return
      end
      subroutine montne (x,n)
      double precision x(n)
      integer bb,eb,br,er,bl,el
      bb=0
      eb=bb
 10   if (eb.ge.n) go to 110
      bb=eb+1
      eb=bb
 20   if (eb.ge.n) go to 30
      if (x(bb).ne.x(eb+1)) go to 30
      eb=eb+1
      go to 20
 30   if (eb.ge.n) go to 70
      if (x(eb).le.x(eb+1)) go to 70
      br=eb+1
      er=br
 40   if (er.ge.n) go to 50
      if (x(er+1).ne.x(br)) go to 50
      er=er+1
      go to 40
 50   pmn=(x(bb)*(eb-bb+1)+x(br)*(er-br+1))/(er-bb+1)
      eb=er
      do 60 i=bb,eb
      x(i)=pmn
 60   continue
 70   if (bb.le.1) go to 10
      if (x(bb-1).le.x(bb)) go to 10
      bl=bb-1
      el=bl
 80   if (bl.le.1) go to 90
      if (x(bl-1).ne.x(el)) go to 90
      bl=bl-1
      go to 80
 90   pmn=(x(bb)*(eb-bb+1)+x(bl)*(el-bl+1))/(eb-bl+1)
      bb=bl
      do 100 i=bb,eb
      x(i)=pmn
 100  continue
      go to 30
 110  return
      end
      subroutine sort (v,a,ii,jj)
c
c     puts into a the permutation vector which sorts v into
c     increasing order.  only elements from ii to jj are considered.
c     arrays iu(k) and il(k) permit sorting up to 2**(k+1)-1 elements
c
c     this is a modification of cacm algorithm #347 by r. c. singleton,
c     which is a modified hoare quicksort.
c
      dimension a(jj),v(*)
      integer iu(20),il(20)
      integer t,tt
      integer a
      double precision v
      m=1
      i=ii
      j=jj
 10   if (i.ge.j) go to 80
 20   k=i
      ij=(j+i)/2
      t=a(ij)
      vt=v(ij)
      if (v(i).le.vt) go to 30
      a(ij)=a(i)
      a(i)=t
      t=a(ij)
      v(ij)=v(i)
      v(i)=vt
      vt=v(ij)
 30   l=j
      if (v(j).ge.vt) go to 50
      a(ij)=a(j)
      a(j)=t
      t=a(ij)
      v(ij)=v(j)
      v(j)=vt
      vt=v(ij)
      if (v(i).le.vt) go to 50
      a(ij)=a(i)
      a(i)=t
      t=a(ij)
      v(ij)=v(i)
      v(i)=vt
      vt=v(ij)
      go to 50
 40   a(l)=a(k)
      a(k)=tt
      v(l)=v(k)
      v(k)=vtt
 50   l=l-1
      if (v(l).gt.vt) go to 50
      tt=a(l)
      vtt=v(l)
 60   k=k+1
      if (v(k).lt.vt) go to 60
      if (k.le.l) go to 40
      if (l-i.le.j-k) go to 70
      il(m)=i
      iu(m)=l
      i=k
      m=m+1
      go to 90
 70   il(m)=k
      iu(m)=j
      j=l
      m=m+1
      go to 90
 80   m=m-1
      if (m.eq.0) return
      i=il(m)
      j=iu(m)
 90   if (j-i.gt.10) go to 20
      if (i.eq.ii) go to 10
      i=i-1
 100  i=i+1
      if (i.eq.j) go to 80
      t=a(i+1)
      vt=v(i+1)
      if (v(i).le.vt) go to 100
      k=i
 110  a(k+1)=a(k)
      v(k+1)=v(k)
      k=k-1
      if (vt.lt.v(k)) go to 110
      a(k+1)=t
      v(k+1)=vt
      go to 100
      end
      subroutine supsmu (n,x,y,w,iper,span,alpha,smo,sc)
c------------------------------------------------------------------
c
c super smoother (friedman and stuetzle, 1984).
c
c version 3/10/84
c
c coded by: j. h. friedman
c           department of statistics and
c           stanford linear accelerator center
c           stanford university
c           stanford ca. 94305
c
c input:
c    n : number of observations (x,y - pairs).
c    x(n) : ordered abscissa values.
c    y(n) : corresponding ordinate (response) values.
c    w(n) : weight for each (x,y) observation.
c    iper : periodic variable flag.
c       iper=1 => x is ordered interval variable.
c       iper=2 => x is a periodic variable with values
c                 in the range (0.0,1.0) and peroid 1.0.
c    span : smoother span (fraction of observations in window).
c           span=0.0 => automatic (variable) span selection.
c    alpha : controles high frequency (small span) penality
c            used with automatic span selection (base tone control).
c            (alpha.le.0.0 or alpha.gt.10.0 => no effect.)
c output:
c   smo(n) : smoothed ordinate (response) values.
c scratch:
c   sc(n,7) : internal working storage.
c
c note:
c    for small samples (n < 40) or if there are substantial serial
c    correlations between obserations close in x - value, then
c    a prespecified fixed span smoother (span > 0) should be
c    used. reasonable span values are 0.3 to 0.5.
c
c------------------------------------------------------------------
      double precision x(n),y(n),w(n),smo(n),sc(n,7)
      common /spans/ spans(3) /consts/ big,sml,eps
      double precision h(1)
      if (x(n).gt.x(1)) go to 30
      sy=0.0
      sw=sy
      do 10 j=1,n
      sy=sy+w(j)*y(j)
      sw=sw+w(j)
 10   continue
      a=sy/sw
      do 20 j=1,n
      smo(j)=a
 20   continue
      return
 30   i=n/4
      j=3*i
      scale=x(j)-x(i)
 40   if (scale.gt.0.0) go to 50
      if (j.lt.n) j=j+1
      if (i.gt.1) i=i-1
      scale=x(j)-x(i)
      go to 40
 50   vsmlsq=(eps*scale)**2
      jper=iper
      if (iper.eq.2.and.(x(1).lt.0.0.or.x(n).gt.1.0)) jper=1
      if (jper.lt.1.or.jper.gt.2) jper=1
      if (span.le.0.0) go to 60
      call smooth (n,x,y,w,span,jper,vsmlsq,smo,sc)
      return
 60   do 70 i=1,3
      call smooth (n,x,y,w,spans(i),jper,vsmlsq,sc(1,2*i-1),sc(1,7))
      call smooth (n,x,sc(1,7),w,spans(2),-jper,vsmlsq,sc(1,2*i),h)
 70   continue
      do 90 j=1,n
      resmin=big
      do 80 i=1,3
      if (sc(j,2*i).ge.resmin) go to 80
      resmin=sc(j,2*i)
      sc(j,7)=spans(i)
 80   continue
      if (alpha.gt.0.0.and.alpha.le.10.0.and.resmin.lt.sc(j,6)) sc(j,7)=
     1sc(j,7)+(spans(3)-sc(j,7))*max(sml,resmin/sc(j,6))**(10.0-alpha)
 90   continue
      call smooth (n,x,sc(1,7),w,spans(2),-jper,vsmlsq,sc(1,2),h)
      do 110 j=1,n
      if (sc(j,2).le.spans(1)) sc(j,2)=spans(1)
      if (sc(j,2).ge.spans(3)) sc(j,2)=spans(3)
      f=sc(j,2)-spans(2)
      if (f.ge.0.0) go to 100
      f=-f/(spans(2)-spans(1))
      sc(j,4)=(1.0-f)*sc(j,3)+f*sc(j,1)
      go to 110
 100  f=f/(spans(3)-spans(2))
      sc(j,4)=(1.0-f)*sc(j,3)+f*sc(j,5)
 110  continue
      call smooth (n,x,sc(1,4),w,spans(1),-jper,vsmlsq,smo,h)
      return
      end
      subroutine smooth (n,x,y,w,span,iper,vsmlsq,smo,acvr)
      double precision  x(n),y(n),w(n),smo(n),acvr(n)
      integer in,out
      xm=0.0
      ym=xm
      var=ym
      cvar=var
      fbw=cvar
      jper=iabs(iper)
      ibw=0.5*span*n+0.5
      if (ibw.lt.2) ibw=2
      it=2*ibw+1
      do 20 i=1,it
      j=i
      if (jper.eq.2) j=i-ibw-1
      xti=x(j)
      if (j.ge.1) go to 10
      j=n+j
      xti=x(j)-1.0
 10   wt=w(j)
      fbo=fbw
      fbw=fbw+wt
      xm=(fbo*xm+wt*xti)/fbw
      ym=(fbo*ym+wt*y(j))/fbw
      tmp=0.0
      if (fbo.gt.0.0) tmp=fbw*wt*(xti-xm)/fbo
      var=var+tmp*(xti-xm)
      cvar=cvar+tmp*(y(j)-ym)
 20   continue
      do 70 j=1,n
      out=j-ibw-1
      in=j+ibw
      if ((jper.ne.2).and.(out.lt.1.or.in.gt.n)) go to 60
      if (out.ge.1) go to 30
      out=n+out
      xto=x(out)-1.0
      xti=x(in)
      go to 50
 30   if (in.le.n) go to 40
      in=in-n
      xti=x(in)+1.0
      xto=x(out)
      go to 50
 40   xto=x(out)
      xti=x(in)
 50   wt=w(out)
      fbo=fbw
      fbw=fbw-wt
      tmp=0.0
      if (fbw.gt.0.0) tmp=fbo*wt*(xto-xm)/fbw
      var=var-tmp*(xto-xm)
      cvar=cvar-tmp*(y(out)-ym)
      xm=(fbo*xm-wt*xto)/fbw
      ym=(fbo*ym-wt*y(out))/fbw
      wt=w(in)
      fbo=fbw
      fbw=fbw+wt
      xm=(fbo*xm+wt*xti)/fbw
      ym=(fbo*ym+wt*y(in))/fbw
      tmp=0.0
      if (fbo.gt.0.0) tmp=fbw*wt*(xti-xm)/fbo
      var=var+tmp*(xti-xm)
      cvar=cvar+tmp*(y(in)-ym)
 60   a=0.0
      if (var.gt.vsmlsq) a=cvar/var
      smo(j)=a*(x(j)-xm)+ym
      if (iper.le.0) go to 70
      h=1.0/fbw
      if (var.gt.vsmlsq) h=h+(x(j)-xm)**2/var
      acvr(j)=abs(y(j)-smo(j))/(1.0-w(j)*h)
 70   continue
      j=1
 80   j0=j
      sy=smo(j)*w(j)
      fbw=w(j)
      if (j.ge.n) go to 100
 90   if (x(j+1).gt.x(j)) go to 100
      j=j+1
      sy=sy+w(j)*smo(j)
      fbw=fbw+w(j)
      if (j.ge.n) go to 100
      go to 90
 100  if (j.le.j0) go to 120
      sy=sy/fbw
      do 110 i=j0,j
      smo(i)=sy
 110  continue
 120  j=j+1
      if (j.gt.n) go to 130
      go to 80
 130  return
      end