home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / lang / fortran / 4305 < prev    next >
Encoding:
Internet Message Format  |  1992-11-12  |  5.1 KB

  1. Path: sparky!uunet!walter!att-out!pacbell.com!ames!sun-barr!cs.utexas.edu!usc!sol.ctr.columbia.edu!hamblin.math.byu.edu!yvax.byu.edu!cunyvm!psuvm!hdk
  2. Newsgroups: comp.lang.fortran
  3. Subject: Re: ALGAMA function
  4. Message-ID: <92317.150302HDK@psuvm.psu.edu>
  5. From: H. D. Knoble <HDK@psuvm.psu.edu>
  6. Date: Thu, 12 Nov 1992 15:03:02 EST
  7. References: <1992Nov11.043558.12534@wam.umd.edu>
  8. Organization: Penn State University
  9. Lines: 156
  10.  
  11. C===Sample (interactive) driver to test accompanying DGAMMA/DLOGAM function.
  12. * AT PSU to run this in VS Fortran issue: FVCG GAMMA FOR
  13. *                  in CMS WATFOR77 issue: WATFOR77 GAMMA FOR
  14. *             in MSDOS WATFOR77, change constants in statement
  15. *                beginning DATA MAXZ/ in Subroutine DGAMMA, then
  16. *                issue: WATFOR77 d:\path\GAMMA.FOR
  17. * My intent is that this program be used only for peaceful (possibly
  18. * commercial) purposes.                               HDK - 3/6/89.
  19. *
  20.       DOUBLE PRECISION X,DGAMMA,VAL,ARG
  21.       REAL Y
  22.       LOGICAL ERROR
  23.       EXTERNAL DGAMMA
  24.       DO 1 I=1,999999999
  25.         WRITE(6,*) 'Give argument of GAMMA (or CR) to quit:'
  26.         READ(5,*,END=88) ARG
  27.         VAL=ARG
  28.         X=DGAMMA(VAL,15,ERROR)
  29.         IF(ERROR) THEN
  30.           WRITE(6,*) '$$GAMMA Argument ',ARG,' is <= 0 or > 57.'
  31. C--IBMPC--WRITE(6,*) '$$GAMMA Argument ',ARG,' is <= 0 or > 171.'
  32.         ELSE
  33.           WRITE(6,*) 'GAMMA(',ARG,')=',X
  34.         ENDIF
  35. 1     CONTINUE
  36. 88    STOP
  37.       END
  38.       DOUBLE PRECISION FUNCTION DGAMMA(Z,MSIZE,ERROR)
  39. C=== ACM CALGO Algorithm 309, Double Precision Gamma Function.
  40. C    Z is the argument; must be > 0 and < 57 for IBM mainframes, or
  41. C                                       < 171 for IBM PC.
  42. C    MSIZE is the number of decimal digits representable; 15 for both.
  43. C    ERROR is returned LOGICAL; .TRUE. if argument was out of range, or
  44. C                               .FALSE. otherwise (i.e. no error).
  45. C    Translated from Algol 68, March 6, 1989, HDK.
  46. C
  47.       DOUBLE PRECISION X,Y,Z,PI, DELTA,EX,DECIMA,MAXZ,ARGUND,MAXEXP
  48.       DOUBLE PRECISION DLOGAM
  49.       INTEGER MSIZE,PARITY,ENTIER
  50.       LOGICAL ERROR
  51. C---IBM Mainframes:
  52.       DATA MAXZ/57.D0/, ARGUND/-1.D-74/, MAXEXP/174.D0/
  53. C---IBM PC.
  54. C     DATA MAXZ/171.D0/, ARGUND/-1.D-307/, MAXEXP/702.D0/
  55.       DATA PI/3.1415926535897932384626433832795028841971693993751D0/
  56. C     ENTIER(Z)=FLOOR(Z)
  57.       ENTIER(X)=DNINT(X)-DMOD(2.D0+DSIGN(1.D0,X),3.D0)
  58.       PARITY(Z)=MOD(ENTIER(Z),2)
  59.       DECIMA(Z)=DABS(Z-IDINT(Z))
  60.       IF(Z.GT.MAXZ) THEN
  61.         GOTO 99
  62.       ELSE
  63.         IF(Z.EQ.ENTIER(Z)) THEN
  64.           IF(Z.LE.0) THEN
  65.             GOTO 99
  66.           ELSE
  67.             Y=1.D0
  68.             IF(Z.GT.2.D0) THEN
  69. 1             Z=Z-1
  70.               Y=Y*Z
  71.               IF(Z.GT.2.D0) GOTO 1
  72.             ENDIF
  73.           ENDIF
  74.         ELSE
  75.           IF(DABS(Z).LT.10**(-MSIZE)) THEN
  76.             Y=1.D0/Z
  77.           ELSE
  78.             IF(Z.LT.0) THEN
  79.               IF(Z.LT.ARGUND) THEN
  80.                 Y=0
  81.               ELSE
  82.                 DELTA=DECIMA(Z)*PI
  83.                 IF(DELTA.LT.10**(-MSIZE*0.5D0)) THEN
  84.                   EX=-DLOG(DECIMA(Z))
  85.                 ELSE
  86.                   EX=DLOG(PI/DSIN(DELTA)) - DLOGAM(1.D0-Z)
  87.                 ENDIF
  88.                 IF(DABS(EX).GT.MAXEXP) THEN
  89.                   Y=0
  90.                 ELSE
  91.                   IF(PARITY(Z).EQ.1) THEN
  92.                     Y=DEXP(EX)
  93.                   ELSE
  94.                     Y=-DEXP(EX)
  95.                   ENDIF
  96.                 ENDIF
  97.               ENDIF
  98.             ELSE
  99.               Y=DEXP(DLOGAM(Z,MSIZE))
  100.             ENDIF
  101.           ENDIF
  102.         ENDIF
  103.       ENDIF
  104.       ERROR=.FALSE.
  105.       DGAMMA=Y
  106.       RETURN
  107. 99    ERROR=.TRUE.
  108.       DGAMMA=0
  109.       RETURN
  110.       END
  111.       DOUBLE PRECISION FUNCTION DLOGAM(T,MSIZE)
  112. C===Log base e of GAMMA(T). See DGAMMA.
  113.       DOUBLE PRECISION F,T,DLGM
  114.       INTEGER TMIN,MSIZE
  115.       TMIN=7
  116.       IF(MSIZE.GT.18) TMIN=MSIZE-10
  117.       IF(T.GT.TMIN) THEN
  118.         DLOGAM=DLGM(T)
  119.       ELSE
  120.         F=T
  121. 1       T=T+1
  122.         IF(T.LT.TMIN) THEN
  123.           F=F*T
  124.           GOTO 1
  125.         ENDIF
  126.         DLOGAM=DLGM(T)-DLOG(F)
  127.       ENDIF
  128.       RETURN
  129.       END
  130.       DOUBLE PRECISION FUNCTION DLGM(W)
  131. C===Companion function for DGAMMA and DLOGAM.
  132.       DOUBLE PRECISION C(20), W,W2,PRESUM,CONST,DEN,SUM
  133.       INTEGER I
  134.       C(1)=1.D0/12.D0
  135.       C(2)=-1.D0/360.D0
  136.       C(3)=1.D0/1260.D0
  137.       C(4)=-1.D0/1680.D0
  138.       C(5)=1.D0/1188.D0
  139.       C(6)=-691.D0/360360.D0
  140.       C(7)=1.D0/156.D0
  141.       C(8)=-3617.D0/122400.D0
  142.       C(9)=43867.D0/244188.D0
  143.       C(10)=-174611.D0/125400.D0
  144.       C(11)=77683.D0/5796.D0
  145.       C(12)=-236364091.D0/1506960.D0
  146.       C(13)=657931.D0/300.D0
  147.       C(14)=-3392780147.D0/93960.D0
  148.       C(15)=1723168255201.D0/2492028.D0
  149.       C(16)=-7709321041217.D0/505920.D0
  150.       C(17)=1516286977551.D0/396.D0
  151.       C(18)=-26315271553053477373.D0/2418179400.D0
  152.       C(19)=1542102059911661.D0/444.D0
  153.       C(20)=-261082718496449122051.D0/21106800.D0
  154.       CONST=.91893853320467274178032973640561763986139747363778D0
  155. C---CONST=DLOG(SQRT(2*PI))
  156.       DEN=W
  157.       W2=W*W
  158.       PRESUM=(W-.5D0)*DLOG(W)-W+CONST
  159.       DO 1 I=1,20
  160.         SUM=PRESUM+C(I)/DEN
  161.         IF(SUM.EQ.PRESUM) GOTO 2
  162.         DEN=DEN*W2
  163. 1     PRESUM=SUM
  164. 2     DLGM=SUM
  165.       RETURN
  166.       END
  167.