Annotation of 41BSD/cmd/efl/efltest/Buram.out, revision 1.1.1.1

1.1       root        1:       subroutine buram(npts, mesh, fn, m, n, p, q, delk)
                      2:       integer npts
                      3:       integer m, n
                      4:       real mesh(npts), fn(npts), p(1), q(1), delk
                      5:       common /dfccom/ nitr
                      6:       integer nitr
                      7:       integer ier, maxitr, nerror, i, itol
                      8:       real fnmin, fnmax
                      9:       logical smonor
                     10: c    Buram is a double precision subroutine which finds a
                     11: c   a rational function which is the best approximation,
                     12: c   in the uniform or minimax sense, to a given discrete
                     13: c   function.  The rational function is represented as
                     14: c   the quotient of two polynomials each expanded in terms
                     15: c   of Tchebychev polynomials.  This routine is a shell
                     16: c   which in turn calls the routine  Burm1 with certain
                     17: c   default values for the initial approximation and  for
                     18: c   the stopping criteria.
                     19: c   Input:
                     20: c   npts   - the number of mesh points.
                     21: c   mesh   - the array of mesh points.
                     22: c   fn     - the array of function values.
                     23: c   m      - the degree of the desired numerator polynomial.
                     24: c   n      - the degree of the desired denominator polynomial.
                     25: c   Output:
                     26: c   p      - the array of coefficients for the numerator polynomial.
                     27: c   q      - the array of coefficients for the denominator polynomial.
                     28: c   delk   - the maximum error in the approximation.
                     29: c   Error States (asterisk indicates recoverable):
                     30: c   1  - invalid degree
                     31: c   2  - too few mesh points
                     32: c   3  - mesh is not strictly monotone
                     33: c   4* - approximation equals function
                     34: c   5* - no improvement in approximation
                     35: c   6* - reached 50 iterations
                     36:       call enter(1)
                     37:       if (m .lt. 0 .or. n .lt. 0) call seterr(
                     38:      1   23h Buram - invalid degree, 23, 1, 2)
                     39:       if (npts .lt. m+n+2) call seterr(28h Buram - too few mesh points
                     40:      1   , 28, 2, 2)
                     41:       if (.not. smonor(mesh, npts, 1)) call seterr(
                     42:      1   38h Buram - mesh is not strictly monotone, 38, 3, 2)
                     43: c   Initialize the numerator and demoninator polynomials.
                     44:       fnmax = fn(1)
                     45:       fnmin = fn(1)
                     46:       do  3 i = 2, npts
                     47:          if (fnmax .ge. fn(i)) goto 1
                     48:             fnmax = fn(i)
                     49:             goto  2
                     50:    1        if (fn(i) .lt. fnmin) fnmin = fn(i)
                     51:    2     continue
                     52:    3     continue
                     53:       call setr(m+1, 0.0e0, p)
                     54:       p(1) = 0.5e0*(fnmax+fnmin)
                     55:       call setr(n+1, 0.0e0, q)
                     56:       q(1) = 1.0e0
                     57:       delk = fnmax-p(1)
                     58:       nitr = 0
                     59:       if (m .eq. 0 .and. n .eq. 0) goto 11
                     60:          maxitr = 50
                     61:          itol = 2
                     62:          call burm1(npts, mesh, fn, maxitr, itol, m, n, p, q, delk)
                     63:          if (nerror(ier) .eq. 0) goto 10
                     64:             if (ier .ne. 7) goto 4
                     65:                call newerr(38h Buram - approximation equals function, 
                     66:      1            39, 4, 1)
                     67:                goto  9
                     68:    4           if (ier .ne. 8) goto 5
                     69:                   call newerr(
                     70:      1               40h Buram - no improvement in approximation, 40, 5,
                     71:      2               1)
                     72:                   goto  8
                     73:    5              if (ier .ne. 9) goto 6
                     74:                      call newerr(30h Buram - reached 50 iterations, 30
                     75:      1                  , 6, 1)
                     76:                      goto  7
                     77:    6                 call eprint
                     78:    7           continue
                     79:    8        continue
                     80:    9        continue
                     81:   10     continue
                     82:   11  call leave
                     83:       return
                     84:       end
                     85:       subroutine burm1(npts, mesh, fn, maxitr, itol, m, n, p, q, 
                     86:      1   delk)
                     87:       integer npts
                     88:       integer maxitr, itol, m, n
                     89:       real mesh(npts), fn(npts), p(1), q(1), delk
                     90:       common /cstak/ dstak
                     91:       double precision dstak(500)
                     92:       integer istkgt, iexptr, j, idig, iflr, istak(1000)
                     93:       integer enptr, qkptr, i1mach, npptr, nqptr
                     94:       real abs, qlrg, float, ws(1000), r1mach
                     95:       logical smonor
                     96:       equivalence (dstak, istak)
                     97:       equivalence (dstak, ws)
                     98: c    Burm1 is a double precision subroutine which finds a
                     99: c   a rational function which is the best approximation,
                    100: c   in the uniform or minimax sense, to a given discrete
                    101: c   function.  The rational function is represented as
                    102: c   the quotient of two polynomials each expanded in terms
                    103: c   of Tchebychev polynomials.  This routine starts from an
                    104: c   initial approximation and terminates for one of four
                    105: c   reasons: (1) the error curve equioscillates and the
                    106: c   alternating extrema match to ITOL digits, (2) the number
                    107: c   of iterations exceeds MAXITR, (3) the approximation
                    108: c   cannot be improved, or (4) the approximation is essentially
                    109: c   equal to the given discrete function.
                    110: c   Input:
                    111: c   npts   - the number of mesh points.
                    112: c   mesh   - the array of mesh points.
                    113: c   fn     - the array of function values.
                    114: c   maxitr - the maximum number of iterations.
                    115: c   itol   - the number of digits to which the extrema should match.
                    116: c   m      - the degree of the desired numerator polynomial.
                    117: c   n      - the degree of the desired denominator polynomial.
                    118: c   p      - the array of coefficients for the initial numerator.
                    119: c   q      - the array of coefficients for the initial denominator.
                    120: c   Output:
                    121: c   p      - the array of coefficients for the numerator polynomial.
                    122: c   q      - the array of coefficients for the denominator polynomial.
                    123: c   delk   - the maximum error in the approximation.
                    124: c   Error States (asterisk indicates recoverable):
                    125: c   1  - invalid degree
                    126: c   2  - too few mesh points
                    127: c   3  - mesh is not strictly monotone
                    128: c   4  - maxitr .lt. 0
                    129: c   5  - invalid accuracy request
                    130: c   6  - denominator is nonpositive
                    131: c   7* - approximation equals function
                    132: c   8* - no improvement in approximation
                    133: c   9* - reached maximum no. of iterations
                    134:       call enter(1)
                    135:       if (m .lt. 0 .or. n .lt. 0) call seterr(
                    136:      1   23h Burm1 - invalid degree, 23, 1, 2)
                    137:       if (npts .lt. m+n+2) call seterr(28h Burm1 - too few mesh points
                    138:      1   , 28, 2, 2)
                    139:       if (.not. smonor(mesh, npts, 1)) call seterr(
                    140:      1   38h Burm1 - mesh is not strictly monotone, 38, 3, 2)
                    141:       if (maxitr .lt. 0) call seterr(22h Burm1 - maxitr .lt. 0, 22, 4, 2
                    142:      1   )
                    143:       idig = iflr(r1mach(5)*float(i1mach(11)))
                    144:       if (itol .lt. 1 .or. idig .lt. itol) call seterr(
                    145:      1   33h Burm1 - invalid accuracy request, 36, 5, 2)
                    146:       qlrg = abs(q(1))
                    147:       j = 2
                    148:          goto  2
                    149:    1     j = j+1
                    150:    2     if (j .gt. n+1) goto  3
                    151:          if (qlrg .lt. abs(q(j))) qlrg = abs(q(j))
                    152:          goto  1
                    153:    3  if (qlrg .ne. 0.e0) goto 4
                    154:          call seterr(35h Burm1 - denominator is nonpositive, 35, 6, 2)
                    155:          goto  11
                    156:    4     j = 1
                    157:             goto  6
                    158:    5        j = j+1
                    159:    6        if (j .gt. n+1) goto  7
                    160:             q(j) = q(j)/qlrg
                    161:             goto  5
                    162:    7     j = 1
                    163:             goto  9
                    164:    8        j = j+1
                    165:    9        if (j .gt. m+1) goto  10
                    166:             p(j) = p(j)/qlrg
                    167:             goto  8
                    168:   10     continue
                    169:   11  npptr = istkgt(m+1, 3)
                    170:       nqptr = istkgt(n+1, 3)
                    171:       enptr = istkgt(npts, 3)
                    172:       qkptr = istkgt(npts, 3)
                    173:       iexptr = istkgt(npts, 2)
                    174:       call b1rm1(npts, mesh, fn, maxitr, itol, m, n, p, q, delk, ws(
                    175:      1   npptr), ws(nqptr), ws(enptr), ws(qkptr), istak(iexptr))
                    176:       call leave
                    177:       return
                    178:       end
                    179:       subroutine b1rm1(npts, x, fn, maxitr, itol, m, n, p, q, 
                    180:      1   delk, newp, newq, en, qk, iext)
                    181:       integer npts
                    182:       integer maxitr, itol, m, n, iext(npts)
                    183:       real x(npts), fn(npts), p(1), q(1), delk, newp(1)
                    184:       real newq(1), en(npts), qk(npts)
                    185:       common /dfccom/ nitr
                    186:       integer nitr
                    187:       integer ier, nex, nerror, i, imin, imax
                    188:       integer ilrg, lrgex
                    189:       real bnd, abs, eps, delnew, r1mach
                    190:       eps = r1mach(4)*10.0e0**itol
                    191:       call extrmr(npts, fn, nex, iext, imax, imin, ilrg)
                    192:       bnd = abs(fn(ilrg))*eps
                    193:       call enqk(npts, x, fn, m, n, p, q, qk, en)
                    194:       do  1 i = 1, npts
                    195:          if (qk(i) .le. 0.0e0) call seterr(
                    196:      1      35h Burm1 - denominator is nonpositive, 35, 6, 2)
                    197:    1     continue
                    198:       call extrmr(npts, en, nex, iext, imax, imin, ilrg)
                    199:       delk = abs(en(ilrg))
                    200:       delnew = delk
                    201:       call movefr(m+1, p, newp)
                    202:       call movefr(n+1, q, newq)
                    203:       nitr = 0
                    204:          goto  3
                    205:    2     nitr = nitr+1
                    206:    3     if (nitr .ge. maxitr) goto  6
                    207: c   call Outpt3 (x,npts,p,q,delk,m,n,en,iext,nex)
                    208:          if (delk .gt. bnd) goto 4
                    209:             call seterr(38h Burm1 - approximation equals function, 39, 7
                    210:      1         , 1)
                    211:             return
                    212: c   Test for optimal solution.
                    213:    4     if (lrgex(npts, en, nex, iext, ilrg, itol) .ge. m+n+2) return
                    214:          call lpstp(npts, x, fn, qk, delnew, m, n, newp, newq)
                    215:          if (nerror(ier) .ne. 0) call erroff
                    216:          call enqk(npts, x, fn, m, n, newp, newq, qk, en)
                    217:          call extrmr(npts, en, nex, iext, imax, imin, ilrg)
                    218:          delnew = abs(en(ilrg))
                    219:          if (delk .gt. delnew) goto 5
                    220:             call seterr(40h Burm1 - no improvement in approximation, 40,
                    221:      1         8, 1)
                    222:             return
                    223:    5     call movefr(m+1, newp, p)
                    224:          call movefr(n+1, newq, q)
                    225:          delk = delnew
                    226:          goto  2
                    227:    6  call seterr(42h Burm1 - reached maximum no. of iterations, 42, 9
                    228:      1   , 1)
                    229:       return
                    230:       end
                    231:       subroutine enqk(npts, x, fn, m, n, p, q, qk, en)
                    232:       integer npts
                    233:       integer m, n
                    234:       real x(npts), fn(npts), p(1), q(1), qk(npts), en(npts)
                    235:       integer i
                    236:       real pk, tchbp
                    237: c
                    238: c   Subroutine  Enqk computes en & Qk.
                    239: c   en=error values at mesh points.
                    240: c   Qk=value of denominator polynomial at mesh points.
                    241: c
                    242:       if (npts .le. 0 .or. m .lt. 0 .or. n .lt. 0) call seterr(
                    243:      1   22henQk-invalid dimension, 22, 1, 2)
                    244:       do  1 i = 1, npts
                    245:          qk(i) = tchbp(n, q, x(i), x(1), x(npts))
                    246:          if (qk(i) .eq. 0.e0) call seterr(20henQk-divisor .eq. 0., 20, 2
                    247:      1      , 2)
                    248:          pk = tchbp(m, p, x(i), x(1), x(npts))
                    249:          en(i) = (fn(i)*qk(i)-pk)/qk(i)
                    250:    1     continue
                    251:       return
                    252:       end
                    253:       integer function lrgex(npts, en, nex, iext, ilrg, tol)
                    254:       integer nex, npts
                    255:       integer iext(nex), ilrg, tol
                    256:       real en(npts)
                    257:       integer j, k, l
                    258:       real abs, hold
                    259: c
                    260: c    Function Lrgex  finds the no. of error extrema with magnitudes
                    261: c    within tolerance of magnitude of largest error.
                    262: c
                    263:       if (npts .le. 0) call seterr(24hLrgex -invalid dimension, 24, 1, 2
                    264:      1   )
                    265:       if (nex .le. 0 .or. ilrg .le. 0) call seterr(
                    266:      1   20hLrgex -invalid index, 20, 2, 2)
                    267:       k = 0
                    268:       do  1 j = 1, nex
                    269:          l = iext(j)
                    270:          hold = abs(en(ilrg))-abs(en(l))
                    271:          if (hold .le. 10.**(-tol)*abs(en(ilrg))) k = k+1
                    272:    1     continue
                    273:       lrgex = k
                    274:       return
                    275:       end
                    276:       subroutine lpstp(npts, mesh, fn, qk, delk, m, n, p, q)
                    277:       integer npts
                    278:       integer m, n
                    279:       real mesh(npts), fn(npts), qk(npts), delk, p(1), q(1)
                    280:       common /cstak/ dstak
                    281:       double precision dstak(500)
                    282:       integer istkgt, aptr, bptr, cptr, xptr, istak(1000)
                    283:       real ws(1000)
                    284:       equivalence (dstak, istak)
                    285:       equivalence (dstak, ws)
                    286: c    Lpstp defines the linear programming subproblem of the
                    287: c   Differential Correction algorithm.  It also provides
                    288: c   the interface to the general purpose linear programming
                    289: c   package.
                    290: c   Input:
                    291: c   npts   - the number of mesh points.
                    292: c   mesh   - the array of mesh points.
                    293: c   fn     - the array of function values.
                    294: c   Qk     - the array of current denominator values.
                    295: c   delk   - the current minimax error.
                    296: c   m      - the degree of the numerator polynomial.
                    297: c   n      - the degree of the denominator polynomial.
                    298: c   p      - the current numerator polynomial.
                    299: c   q      - the current denominator polynomial.
                    300: c   Output:
                    301: c   p      - the array of coefficients for the numerator polynomial.
                    302: c   q      - the array of coefficients for the denominator polynomial.
                    303: c   Error States (asterisk indicates fatal):
                    304: c   1* - invalid degree
                    305: c   2* - too few mesh points
                    306: c   3* - nonpositive delk
                    307: c   4  - no improvement in the lp subproblem
                    308:       call enter(1)
                    309:       if (m .lt. 0 .or. n .lt. 0) call seterr(
                    310:      1   23h Lpstp - invalid degree, 23, 1, 2)
                    311:       if (npts .lt. m+n+2) call seterr(28h Lpstp - too few mesh points
                    312:      1   , 28, 2, 2)
                    313:       aptr = istkgt(3*npts+1, 3)
                    314:       bptr = istkgt(2*(npts+n+1), 3)
                    315:       cptr = istkgt(m+n+3, 3)
                    316:       xptr = istkgt(m+n+3, 3)
                    317:       call l9stp(npts, mesh, fn, qk, delk, m, n, p, q, ws(aptr), ws(
                    318:      1   bptr), ws(cptr), ws(xptr))
                    319:       call leave
                    320:       return
                    321:       end
                    322:       subroutine l9stp(npts, mesh, fn, qk, delk, m, n, p, q, a, b,
                    323:      1   c, x)
                    324:       integer npts
                    325:       integer m, n
                    326:       real mesh(npts), fn(npts), qk(npts), delk, p(1), q(1)
                    327:       real a(1), b(1), c(1), x(1)
                    328:       common /difcom/ nptsc, mc, nc, i1, i2, i3, i4
                    329:       integer nptsc, mc, nc, i1, i2, i3
                    330:       integer i4
                    331:       external difmt
                    332:       integer ier, nerror, i, j, ierr, mm
                    333:       integer nn
                    334:       real abs, ctx, ctxnew, qlrg, float, r1mach
                    335:       nptsc = npts
                    336:       mc = m
                    337:       nc = n
                    338:       i1 = npts
                    339:       i2 = i1+npts
                    340:       i3 = i2+n+1
                    341:       i4 = i3+n+1
                    342:       mm = i4
                    343:       nn = m+n+3
                    344:       call movefr(n+1, q, x)
                    345:       call movefr(m+1, p, x(n+2))
                    346:       x(nn) = 0.e0
                    347:       call setr(i2, 0.0e0, b)
                    348:       call setr(i4-i2, -1.0e0, b(i2+1))
                    349:       call setr(nn, 0.0e0, c)
                    350:       c(nn) = -1.0e0
                    351:       call movefr(npts, mesh, a)
                    352:       call movefr(npts, fn, a(npts+1))
                    353:       call movefr(npts, qk, a(2*npts+1))
                    354:       if (delk .le. 0.0e0) call seterr(25h Lpstp - nonpositive delk, 25,
                    355:      1   3, 2)
                    356:       a(3*npts+1) = delk
                    357:       ctx = 0.0e0
                    358: c   Solve the LP problem: max C(T)X subject to AX >= B.
                    359: c   The subroutine  Difmt derives the matrix A from
                    360: c   the data stored in the array A.
                    361:       call lpph2(a, mm, nn, difmt, b, c, x, 4*mm, ctxnew)
                    362:       if (nerror(ier) .ne. 0) call erroff
                    363:       if (ctx .ge. ctxnew) goto 10
                    364:          qlrg = 0.0e0
                    365:          j = 1
                    366:             goto  2
                    367:    1        j = j+1
                    368:    2        if (j .gt. n+1) goto  3
                    369:             if (qlrg .lt. abs(x(j))) qlrg = abs(x(j))
                    370:             goto  1
                    371:    3     j = 1
                    372:             goto  5
                    373:    4        j = j+1
                    374:    5        if (j .gt. n+1) goto  6
                    375:             q(j) = x(j)/qlrg
                    376:             goto  4
                    377:    6     i = 0
                    378:          j = n+2
                    379:             goto  8
                    380:    7        j = j+1
                    381:    8        if (j .gt. m+n+2) goto  9
                    382:             i = i+1
                    383:             p(i) = x(j)/qlrg
                    384:             goto  7
                    385:    9     continue
                    386:          goto  11
                    387:   10     call seterr(44h Lpstp - no improvement in the lp subproblem, 
                    388:      1      44, 4, 1)
                    389:   11  return
                    390:       end
                    391:       subroutine difmt(inprod, a, mm, nn, irow, x, dinprd)
                    392:       integer nn
                    393:       integer mm, irow
                    394:       real a(1), x(nn), dinprd
                    395:       logical inprod
                    396:       common /difcom/ npts, m, n, i1, i2, i3, i4
                    397:       integer npts, m, n, i1, i2, i3
                    398:       integer i4
                    399:       integer max0, irm1, irm2, irm3, j, zptr
                    400:       integer jp, maxmn, fnptr, qzptr
                    401:       real fct, delk, z, fn, fdelk, tchbp
                    402:       real qz
                    403: c    Difmt handles references by the LP routine to
                    404: c   the matrix for the linear programming subproblem.
                    405:       call enter(1)
                    406:       if (mm .ne. i4 .or. nn .ne. m+n+3) call seterr(
                    407:      1   26h Difmt - invalid dimension, 26, 1, 2)
                    408:       if (irow .lt. 0 .or. mm .lt. irow) call seterr(
                    409:      1   22h Difmt - invalid index, 22, 2, 2)
                    410:       irm1 = irow-i1
                    411:       irm2 = irow-i2
                    412:       irm3 = irow-i3
                    413:       if ((.not. inprod) .or. i2 .ge. irow) goto 3
                    414:          if (i3 .ge. irow) goto 1
                    415:             dinprd = -x(irm3)
                    416:             goto  2
                    417:    1        dinprd = x(irm2)
                    418:    2     continue
                    419:          goto  18
                    420:    3     if (i2 .ge. irow) goto 6
                    421:             call setr(nn, 0.0e0, x)
                    422:             if (i3 .ge. irow) goto 4
                    423:                x(irm3) = -1.0e0
                    424:                goto  5
                    425:    4           x(irm2) = 1.0e0
                    426:    5        continue
                    427:             goto  17
                    428:    6        if (i1 .ge. irow) goto 7
                    429:                fct = -1.0e0
                    430:                zptr = irm1
                    431:                goto  8
                    432:    7           fct = 1.0e0
                    433:                zptr = irow
                    434:    8        z = a(zptr)
                    435:             fnptr = zptr+npts
                    436:             fn = a(fnptr)
                    437:             qzptr = fnptr+npts
                    438:             qz = a(qzptr)
                    439:             delk = a(3*npts+1)
                    440:             fdelk = fct*fn+delk
                    441:             if (.not. inprod) goto 9
                    442:                dinprd = fdelk*tchbp(n, x, z, a(1), a(npts))-fct*tchbp(m,
                    443:      1            x(n+2), z, a(1), a(npts))+qz*x(nn)
                    444:                goto  16
                    445:    9           maxmn = max0(m, n)
                    446:                call tchcf(z, a(1), a(npts), maxmn, x)
                    447:                j = m+1
                    448:                   goto  11
                    449:   10              j = j-1
                    450:   11              if (1 .gt. j) goto  12
                    451:                   jp = j+n+1
                    452:                   x(jp) = (-fct)*x(j)
                    453:                   goto  10
                    454:   12           j = 1
                    455:                   goto  14
                    456:   13              j = j+1
                    457:   14              if (j .gt. n+1) goto  15
                    458:                   x(j) = fdelk*x(j)
                    459:                   goto  13
                    460:   15           x(nn) = qz
                    461:   16        continue
                    462:   17  continue
                    463:   18  call leave
                    464:       return
                    465:       end
                    466:       subroutine tchcf(x, a, b, deg, xx)
                    467:       integer deg
                    468:       real x, a, b, xx(1)
                    469:       integer i
                    470:       real twoxx
                    471: c
                    472: c    Subroutine  Tchcf computes the deg+1 Tchebycheff
                    473: c    coefficients of the point x.
                    474: c
                    475:       call enter(1)
                    476:       if (deg .lt. 0) call seterr(21h Tchcf-invalid degree, 21, 1, 2)
                    477:       xx(1) = 1.e0
                    478:       if (deg .le. 0) goto 3
                    479:          if (b .gt. a) goto 1
                    480:             call seterr(23h Tchcf-invalid interval, 23, 2, 2)
                    481:             goto  2
                    482:    1        xx(2) = 2.e0*(x-(a+b)/2.e0)/(b-a)
                    483: cscale x to the interval (-1.e0,1.e0)
                    484:    2  continue
                    485:    3  if (deg .gt. 1) twoxx = 2.e0*xx(2)
                    486:       i = 3
                    487:          goto  5
                    488:    4     i = i+1
                    489:    5     if (i .gt. deg+1) goto  6
                    490:          xx(i) = twoxx*xx(i-1)-xx(i-2)
                    491:          goto  4
                    492:    6  call leave
                    493:       return
                    494:       end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.