Advertisement
Guest User

Untitled

a guest
Dec 5th, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.       subroutine quanc8(fun,a,b,abserr,relerr,result,errest,nofun,flag)
  2. c
  3.       double precision fun, a, b, abserr, relerr, result, errest, flag
  4.       integer nofun
  5. c
  6. c   estimate the integral of fun(x) from a to b
  7. c   to a user provided tolerance.
  8. c   an automatic adaptive routine based on
  9. c   the 8-panel newton-cotes rule.
  10. c
  11. c   input ..
  12. c
  13. c   fun     the name of the integrand function subprogram fun(x).
  14. c   a       the lower limit of integration.
  15. c   b       the upper limit of integration.(b may be less than a.)
  16. c   relerr  a relative error tolerance. (should be non-negative)
  17. c   abserr  an absolute error tolerance. (should be non-negative)
  18. c
  19. c   output ..
  20. c
  21. c   result  an approximation to the integral hopefully satisfying the
  22. c           least stringent of the two error tolerances.
  23. c   errest  an estimate of the magnitude of the actual error.
  24. c   nofun   the number of function values used in calculation of result.
  25. c   flag    a reliability indicator.  if flag is zero, then result
  26. c           probably satisfies the error tolerance.  if flag is
  27. c           xxx.yyy , then  xxx = the number of intervals which have
  28. c           not converged and  0.yyy = the fraction of the interval
  29. c           left to do when the limit on  nofun  was approached.
  30. c
  31.       double precision w0,w1,w2,w3,w4,area,x0,f0,stone,step,cor11,temp
  32.       double precision qprev,qnow,qdiff,qleft,esterr,tolerr
  33.       double precision qright(31),f(16),x(16),fsave(8,30),xsave(8,30)
  34.       double precision dabs,dmax1
  35.       integer levmin,levmax,levout,nomax,nofin,lev,nim,i,j
  36. c
  37. c   ***   stage 1 ***   general initialization
  38. c   set constants.
  39. c
  40.       levmin = 1
  41.       levmax = 30
  42.       levout = 6
  43.       nomax = 5000
  44.       nofin = nomax - 8*(levmax-levout+2**(levout+1))
  45. c
  46. c   trouble when nofun reaches nofin
  47. c
  48.       w0 =   3956.0d0 / 14175.0d0
  49.       w1 =  23552.0d0 / 14175.0d0
  50.       w2 =  -3712.0d0 / 14175.0d0
  51.       w3 =  41984.0d0 / 14175.0d0
  52.       w4 = -18160.0d0 / 14175.0d0
  53. c
  54. c   initialize running sums to zero.
  55. c
  56.       flag = 0.0d0
  57.       result = 0.0d0
  58.       cor11  = 0.0d0
  59.       errest = 0.0d0
  60.       area   = 0.0d0
  61.       nofun = 0
  62.       if (a .eq. b) return
  63. c
  64. c   ***   stage 2 ***   initialization for first interval
  65. c
  66.       lev = 0
  67.       nim = 1
  68.       x0 = a
  69.       x(16) = b
  70.       qprev  = 0.0d0
  71.       f0 = fun(x0)
  72.       stone = (b - a) / 16.0d0
  73.       x(8)  =  (x0  + x(16)) / 2.0d0
  74.       x(4)  =  (x0  + x(8))  / 2.0d0
  75.       x(12) =  (x(8)  + x(16)) / 2.0d0
  76.       x(2)  =  (x0  + x(4))  / 2.0d0
  77.       x(6)  =  (x(4)  + x(8))  / 2.0d0
  78.       x(10) =  (x(8)  + x(12)) / 2.0d0
  79.       x(14) =  (x(12) + x(16)) / 2.0d0
  80.       do 25 j = 2, 16, 2
  81.          f(j) = fun(x(j))
  82.    25 continue
  83.       nofun = 9
  84. c
  85. c   ***   stage 3 ***   central calculation
  86. c   requires qprev,x0,x2,x4,...,x16,f0,f2,f4,...,f16.
  87. c   calculates x1,x3,...x15, f1,f3,...f15,qleft,qright,qnow,qdiff,area.
  88. c
  89.    30 x(1) = (x0 + x(2)) / 2.0d0
  90.       f(1) = fun(x(1))
  91.       do 35 j = 3, 15, 2
  92.          x(j) = (x(j-1) + x(j+1)) / 2.0d0
  93.          f(j) = fun(x(j))
  94.    35 continue
  95.       nofun = nofun + 8
  96.       step = (x(16) - x0) / 16.0d0
  97.       qleft  =  (w0*(f0 + f(8))  + w1*(f(1)+f(7))  + w2*(f(2)+f(6))
  98.      1  + w3*(f(3)+f(5))  +  w4*f(4)) * step
  99.       qright(lev+1)=(w0*(f(8)+f(16))+w1*(f(9)+f(15))+w2*(f(10)+f(14))
  100.      1  + w3*(f(11)+f(13)) + w4*f(12)) * step
  101.       qnow = qleft + qright(lev+1)
  102.       qdiff = qnow - qprev
  103.       area = area + qdiff
  104. c
  105. c   ***   stage 4 *** interval convergence test
  106. c
  107.       esterr = dabs(qdiff) / 1023.0d0
  108.       tolerr = dmax1(abserr,relerr*dabs(area)) * (step/stone)
  109.       if (lev .lt. levmin) go to 50
  110.       if (lev .ge. levmax) go to 62
  111.       if (nofun .gt. nofin) go to 60
  112.       if (esterr .le. tolerr) go to 70
  113. c
  114. c   ***   stage 5   ***   no convergence
  115. c   locate next interval.
  116. c
  117.    50 nim = 2*nim
  118.       lev = lev+1
  119. c
  120. c   store right hand elements for future use.
  121. c
  122.       do 52 i = 1, 8
  123.          fsave(i,lev) = f(i+8)
  124.          xsave(i,lev) = x(i+8)
  125.    52 continue
  126. c
  127. c   assemble left hand elements for immediate use.
  128. c
  129.       qprev = qleft
  130.       do 55 i = 1, 8
  131.          j = -i
  132.          f(2*j+18) = f(j+9)
  133.          x(2*j+18) = x(j+9)
  134.    55 continue
  135.       go to 30
  136. c
  137. c   ***   stage 6   ***   trouble section
  138. c   number of function values is about to exceed limit.
  139. c
  140.    60 nofin = 2*nofin
  141.       levmax = levout
  142.       flag = flag + (b - x0) / (b - a)
  143.       go to 70
  144. c
  145. c   current level is levmax.
  146. c
  147.    62 flag = flag + 1.0d0
  148. c
  149. c   ***   stage 7   ***   interval converged
  150. c   add contributions into running sums.
  151. c
  152.    70 result = result + qnow
  153.       errest = errest + esterr
  154.       cor11  = cor11  + qdiff / 1023.0d0
  155. c
  156. c   locate next interval.
  157. c
  158.    72 if (nim .eq. 2*(nim/2)) go to 75
  159.       nim = nim/2
  160.       lev = lev-1
  161.       go to 72
  162.    75 nim = nim + 1
  163.       if (lev .le. 0) go to 80
  164. c
  165. c   assemble elements required for the next interval.
  166. c
  167.       qprev = qright(lev)
  168.       x0 = x(16)
  169.       f0 = f(16)
  170.       do 78 i = 1, 8
  171.          f(2*i) = fsave(i,lev)
  172.          x(2*i) = xsave(i,lev)
  173.    78 continue
  174.       go to 30
  175. c
  176. c   ***   stage 8   ***   finalize and return
  177. c
  178.    80 result = result + cor11
  179. c
  180. c   make sure errest not less than roundoff level.
  181. c
  182.       if (errest .eq. 0.0d0) return
  183.    82 temp = dabs(result) + errest
  184.       if (temp .ne. dabs(result)) return
  185.       errest = 2.0d0*errest
  186.       go to 82
  187.       end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement