program adaptive_quadrature implicit none integer :: fun_eval real :: a, b, integral, tol, f, f_a, f_b, adapt_trap external f write(*,*) 'Input endpoints a,b & error tolerance tol:' read*, a, b, tol f_a=f(a) f_b=f(b) write(*,*) ' a b' integral = adapt_trap(f,a,b,f_a,f_b,tol,fun_eval) fun_eval = fun_eval+2 write(*,*) 'Integral = ', integral write(*,*) 'Number of function evaluations = ', fun_eval stop end program adaptive_quadrature !==================================================== function f(x) result(f_result) ! Integrand. implicit none real, intent (in) :: x real :: f_result !f_result=4./(1.+x**2) if (x==0.0) then f_result = 0.0 else f_result=sqrt(x)*log(x) endif return end function f !===================================================================== recursive function adapt_trap(f,a,b,f_a,f_b,tol,fun_eval) result(trap) implicit none real, intent (in):: a, b, tol, f_a, f_b real :: f, h, mid, f_mid real :: T2, T3, error_T3 real :: trap, trap_left, trap_right integer :: fun_eval, fun_eval_left, fun_eval_right external f write(*,*) a, b h=b-a mid=(a+b)/2.0 f_mid = f(mid) T2 = h*( f_a + f_b )/2.0 T3 = h*( f_a + 2.0*f_mid + f_b )/4.0 error_T3 = (T3-T2)/3.0 if (abs(error_T3) < tol) then trap = T3 + error_T3 fun_eval = 1 else trap_left = adapt_trap(f,a,mid,f_a,f_mid,tol/2.0,fun_eval_left) trap_right = adapt_trap(f,mid,b,f_mid,f_b,tol/2.0,fun_eval_right) trap = trap_left + trap_right fun_eval = fun_eval_left + fun_eval_right endif return end function adapt_trap