File: epsalg.f

package info (click to toggle)
scilab 4.0-12
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 100,640 kB
  • ctags: 57,333
  • sloc: ansic: 377,889; fortran: 242,862; xml: 179,819; tcl: 42,062; sh: 10,593; ml: 9,441; makefile: 4,377; cpp: 1,354; java: 621; csh: 260; yacc: 247; perl: 130; lex: 126; asm: 72; lisp: 30
file content (178 lines) | stat: -rw-r--r-- 5,727 bytes parent folder | download | duplicates (7)
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
C/MEMBR ADD NAME=EPSALG,SSI=0
      subroutine epsalg(n, epstab, result, abserr, res3la, nres)
c
c     based on quadpack routine epsalg
c     ******************************************************
c
c           purpose
c              the routine transforms a given sequence of
c              approximations, by means of the epsilon
c              algorithm of p. wynn.
c
c              an estimate of the absolute error is also given.
c              the condensed epsilon table is computed. only those
c              elements needed for the computation of the
c              next diagonal are preserved.
c
c           calling sequence
c              call epsalg (n,epstab,result,abserr,res3la,nres)
c
c           parameters
c              n      - epstab(n) contains the new element in the
c                       first column of the epsilon table.
c
c              epstab - one dimensional array containing the
c                       elements of the two lower diagonals of
c                       the triangular epsilon table.
c                       the elements are numbered starting at the
c                       right-hand corner of the triangle.
c                       the dimension should be at least n+2.
c
c              result - resulting approximation to the integral
c
c              abserr - estimate of the absolute error computed from
c                       result and the 3 previous /results/
c
c              res3la - array containing the last 3 /results/
c
c              nres   - number of calls to the routine
c                       (should be zero at first call)
c
c     ******************************************************
c     .. scalar arguments ..
      double precision abserr, result
      integer n, nres
c     .. array arguments ..
      double precision epstab(52), res3la(3)
c     ..
c     .. local scalars ..
      double precision delta1, delta2, delta3, e0, e1, e1abs, e2, e3,
     * epmach,epsinf, err1, err2, err3, error, oflow, res, ss, tol1,
     * tol2,tol3
      integer i, ib2, ib, ie, ind, k1, k2, k3, limexp, newelm, num
c     .. function references ..
      double precision dlamch
c     ..
c
c            machine dependent constants
c             -------------------------
c            /limexp/ is the maximum number of elements the epsilon
c            table can contain. if this number is reached, the upper
c            diagonal of the epsilon table is deleted.
c
      data limexp /50/
      epmach=dlamch('p')
      oflow=dlamch('o')
c
c           list of major variables
c           -----------------------
c           e0     - the 4 elements on which the
c           e1       computation of a new element in
c           e2       the epsilon table is based
c           e3                 e0
c                        e3    e1    new
c                              e2
c           newelm - number of elements to be computed in the new
c                    diagonal
c           error  - error = abs(e1-e0)+abs(e2-e1)+abs(new-e2)
c           result - the element in the new diagonal with least
c                    error
c
      nres = nres + 1
      abserr = oflow
      result = epstab(n)
      if (n.lt.3) go to 200
      epstab(n+2) = epstab(n)
      newelm = (n-1)/2
      epstab(n) = oflow
      num = n
      k1 = n
      do 80 i=1,newelm
         k2 = k1 - 1
         k3 = k1 - 2
         res = epstab(k1+2)
         e0 = epstab(k3)
         e1 = epstab(k2)
         e2 = res
         e1abs = abs(e1)
         delta2 = e2 - e1
         err2 = abs(delta2)
         tol2 = max(abs(e2),e1abs)*epmach
         delta3 = e1 - e0
         err3 = abs(delta3)
         tol3 = max(e1abs,abs(e0))*epmach
         if (err2.gt.tol2 .or. err3.gt.tol3) go to 20
c
c           if e0, e1 and e2 are equal to within machine
c           accuracy, convergence is assumed
c           result = e2
c           abserr = abs(e1-e0)+abs(e2-e1)
c
         result = res
         abserr = err2 + err3
         go to 200
   20    e3 = epstab(k1)
         epstab(k1) = e1
         delta1 = e1 - e3
         err1 = abs(delta1)
         tol1 = max(e1abs,abs(e3))*epmach
c
c           if two elements are very close to each other, omit
c           a part of the table by adjusting the value of n
c
         if (err1.lt.tol1 .or. err2.lt.tol2 .or. err3.lt.tol3) goto 40
         ss = 0.10d+01/delta1 + 0.10d+01/delta2 - 0.10d+01/delta3
         epsinf = abs(ss*e1)
c
c           test to detect irregular behaviour in the table, and
c           eventually omit a part of the table adjusting the value
c           of n
c
         if (epsinf.gt.0.10d-03) go to 60
   40    n = i + i - 1
         go to 100
c
c           compute a new element and eventually adjust
c           the value of result
c
   60    res = e1 + 0.10d+01/ss
         epstab(k1) = res
         k1 = k1 - 2
         error = err2 + abs(res-e2) + err3
         if (error.gt.abserr) go to 80
         abserr = error
         result = res
   80 continue
c
c           shift the table
c
  100 if (n.eq.limexp) n = 2*(limexp/2) - 1
      ib = 1
      if ((num/2)*2.eq.num) ib = 2
      ie = newelm + 1
      do 120 i=1,ie
         ib2 = ib + 2
         epstab(ib) = epstab(ib2)
         ib = ib2
  120 continue
      if (num.eq.n) go to 160
      ind = num - n + 1
      do 140 i=1,n
         epstab(i) = epstab(ind)
         ind = ind + 1
  140 continue
  160 if (nres.ge.4) go to 180
      res3la(nres) = result
      abserr = oflow
      go to 200
c
c           compute error estimate
c
  180 abserr = abs(result-res3la(3)) + abs(result-res3la(2)) +
     *abs(result-res3la(1))
      res3la(1) = res3la(2)
      res3la(2) = res3la(3)
      res3la(3) = result
  200 abserr = max(abserr,5.0d+00*epmach*abs(result))
      return
      end