C ALGORITHM 439, COLLECTED ALGORITHMS FROM ACM. C THIS WORK PUBLISHED IN COMMUNICATIONS OF THE ACM C VOL. 15, NO. 12, December, 1972, P.1072. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # Fortran/ # Fortran/Dp/ # Fortran/Dp/Drivers/ # Fortran/Dp/Drivers/Makefile # Fortran/Dp/Drivers/driver.f # Fortran/Dp/Drivers/res # Fortran/Dp/Src/ # Fortran/Dp/Src/src.f # This archive created: Thu Dec 15 13:28:16 2005 export PATH; PATH=/bin:$PATH if test ! -d 'Fortran' then mkdir 'Fortran' fi cd 'Fortran' if test ! -d 'Dp' then mkdir 'Dp' fi cd 'Dp' if test ! -d 'Drivers' then mkdir 'Drivers' fi cd 'Drivers' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << "SHAR_EOF" > 'Makefile' all: Res src.o: src.f $(F77) $(F77OPTS) -c src.f driver.o: driver.f $(F77) $(F77OPTS) -c driver.f DRIVERS= driver RESULTS= Res Objs1= driver.o src.o driver: $(Objs1) $(F77) $(F77OPTS) -o driver $(Objs1) $(SRCLIBS) Res: driver ./driver >Res diffres:Res res echo "Differences in results from driver" $(DIFF) Res res clean: rm -rf *.o $(DRIVERS) $(CLEANUP) $(RESULTS) SHAR_EOF fi # end of overwriting check if test -f 'driver.f' then echo shar: will not over-write existing file "'driver.f'" else cat << "SHAR_EOF" > 'driver.f' program main c*********************************************************************** c cc TOMS439_PRB tests TOMS439. c implicit none write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'TOMS439_PRB' write ( *, '(a)' ) ' Test TOMS algorithm 439, product-type' write ( *, '(a)' ) ' three point Gauss-Legendre Simpson' write ( *, '(a)' ) ' integration.' call test01 call test02 write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'TOMS439_PRB' write ( *, '(a)' ) ' Normal end of execution.' stop end subroutine test01 c*********************************************************************** c cc TEST01 tests the rule with one factor equal to 1. c implicit none double precision a double precision b double precision exact double precision fn00, gn00 external fn00 external gn00 integer n double precision vint a = -4.0D+00 b = 4.0D+00 exact = 2.0D+00 * atan ( 4.0D+00 ) write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'TEST01' write ( *, '(a)' ) ' Integral of F(X) * G(X) from -1 to 1,' write ( *, '(a)' ) ' with F(X) = 1, G(X) = 1/(1+x**2 )' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' N VINT' write ( *, '(a)' ) ' ' do n = 1, 10 call p3pgs ( a, b, n, fn00, gn00, vint ) write ( *, '(2x,i6,2x,g14.6)' ) n, vint end do write ( *, '(a)' ) ' ' write ( *, '(a,g14.6)' ) ' Exact: ', exact return end subroutine test02 c*********************************************************************** c cc TEST02 tests the rule with factors exp(-x) and cos(x). c implicit none double precision a double precision b double precision exact double precision gn01, gn02 external gn01 external gn02 integer n double precision vint a = 0.0D+00 b = 3.141592653589793D+00 exact = 0.5 * exp ( -b ) * ( sin ( b ) - cos ( b ) ) & - ( 0.5 * exp ( -a ) * ( sin ( a ) - cos ( a ) ) ) write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'TEST02' write ( *, '(a)' ) ' Integral of F(X) * G(X) from 0 to PI,' write ( *, '(a)' ) ' with F(X) = EXP(-X), G(X) = COS(X)' write ( *, '(a)' ) ' ' write ( *, '(a)' ) ' N VINT' write ( *, '(a)' ) ' ' do n = 1, 10 call p3pgs ( a, b, n, gn01, gn02, vint ) write ( *, '(2x,i6,2x,g14.6)' ) n, vint end do write ( *, '(a)' ) ' ' write ( *, '(a,g14.6)' ) ' Exact: ', exact return end function fn00 ( x ) c*********************************************************************** c cc FN00 evaluates the function 1. c implicit none double precision fn00 double precision x fn00 = 1.0D+00 return end function fn01 ( x ) c*********************************************************************** c cc FN01 evaluates the function X. c implicit none integer n double precision fn01 double precision x fn01 = x return end function gn00 ( x ) c*********************************************************************** c cc GN00 evaluates the function 1/(1+X**2). c implicit none double precision gn00 double precision x gn00 = 1.0D+00 / ( 1.0D+00 + x * x ) return end function gn01 ( x ) c*********************************************************************** c cc GN01 evaluates the function exp(-x). c implicit none double precision gn01 double precision x gn01 = exp ( - x ) return end function gn02 ( x ) c*********************************************************************** c cc GN02 evaluates the function cos(x). c implicit none double precision gn02 double precision x gn02 = cos ( x ) return end SHAR_EOF fi # end of overwriting check if test -f 'res' then echo shar: will not over-write existing file "'res'" else cat << "SHAR_EOF" > 'res' TOMS439_PRB Test TOMS algorithm 439, product-type three point Gauss-Legendre Simpson integration. TEST01 Integral of F(X) * G(X) from -1 to 1, with F(X) = 1, G(X) = 1/(1+x**2 ) N VINT 1 5.49020 2 2.47843 3 2.90842 4 2.57255 5 2.69529 6 2.63329 7 2.66030 8 2.64773 9 2.65342 10 2.65082 Exact: 2.65164 TEST02 Integral of F(X) * G(X) from 0 to PI, with F(X) = EXP(-X), G(X) = COS(X) N VINT 1 0.432791 2 0.517389 3 0.520869 4 0.521385 5 0.521518 6 0.521565 7 0.521584 8 0.521594 9 0.521599 10 0.521602 Exact: 0.521607 TOMS439_PRB Normal end of execution. SHAR_EOF fi # end of overwriting check cd .. if test ! -d 'Src' then mkdir 'Src' fi cd 'Src' if test -f 'src.f' then echo shar: will not over-write existing file "'src.f'" else cat << "SHAR_EOF" > 'src.f' SUBROUTINE P3PGS ( A, B, N, FN, GN, VINT ) C C THIS SUBROUTINE USES THE PRODUCT TYPE THREE-POINT GAUSS- C LEGENDRE-SIMPSON RULE COMPOUNDED N TIMES TO APPROXIMATE C THE INTEGRAL FROM A TO B OF THE FUNCTION FN(X) * GN(X). C FN AND GN ARE FUNCTION SUBPROGRAMS WHICH MUST BE SUPPLIED C BY THE USER. THE RESULT IS STORED IN VINT. C INTEGER I, N, J, K DOUBLE PRECISION A, AG, AM(2,3), B, F(2), FN, G(3), & GN, H, VINT, X(2), Y(2) DATA AM(1,1), AM(2,3) / 2 * 1.718245836551854D0 /, & AM(1,2), AM(2,2) / 2 * 1.D0 /, AM(1,3), AM(2,1) & / 2 * -.2182458365518542D0 / H = ( B - A ) / DBLE ( FLOAT ( N ) ) X(1) = A + .1127016653792583D0 * H X(2) = A + .8872983346207417D0 * H Y(1) = A + H / 2.D0 Y(2) = A + H VINT = 0.D0 G(3) = GN ( A ) DO 4 I = 1, N AG = FN ( Y(1) ) G(1) = G(3) DO 1 J = 1, 2 F(J) = FN ( X(J) ) G(J+1) = GN ( Y(J) ) X(J) = X(J) + H Y(J) = Y(J) + H 1 CONTINUE VINT = VINT + AG * 4.D0 * G(2) DO 3 J = 1, 2 AG = 0.D0 DO 2 K = 1, 3 AG = AG + AM(J,K) * G(K) 2 CONTINUE VINT = VINT + F(J) * AG 3 CONTINUE 4 CONTINUE VINT = H * VINT / 9.D0 RETURN END SHAR_EOF fi # end of overwriting check cd .. cd .. cd .. # End of shell archive exit 0