dcot.f 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. *DECK DCOT
  2. DOUBLE PRECISION FUNCTION DCOT (X)
  3. C***BEGIN PROLOGUE DCOT
  4. C***PURPOSE Compute the cotangent.
  5. C***LIBRARY SLATEC (FNLIB)
  6. C***CATEGORY C4A
  7. C***TYPE DOUBLE PRECISION (COT-S, DCOT-D, CCOT-C)
  8. C***KEYWORDS COTANGENT, ELEMENTARY FUNCTIONS, FNLIB, TRIGONOMETRIC
  9. C***AUTHOR Fullerton, W., (LANL)
  10. C***DESCRIPTION
  11. C
  12. C DCOT(X) calculates the double precision trigonometric cotangent
  13. C for double precision argument X. X is in units of radians.
  14. C
  15. C Series for COT on the interval 0. to 6.25000E-02
  16. C with weighted error 5.52E-34
  17. C log weighted error 33.26
  18. C significant figures required 32.34
  19. C decimal places required 33.85
  20. C
  21. C***REFERENCES (NONE)
  22. C***ROUTINES CALLED D1MACH, DCSEVL, INITDS, XERMSG
  23. C***REVISION HISTORY (YYMMDD)
  24. C 770601 DATE WRITTEN
  25. C 890531 Changed all specific intrinsics to generic. (WRB)
  26. C 890531 REVISION DATE from Version 3.2
  27. C 891214 Prologue converted to Version 4.0 format. (BAB)
  28. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  29. C 920618 Removed space from variable names. (RWC, WRB)
  30. C***END PROLOGUE DCOT
  31. DOUBLE PRECISION X, COTCS(15), AINTY, AINTY2, PI2REC, SQEPS,
  32. 1 XMAX, XMIN, XSML, Y, YREM, PRODBG, DCSEVL, D1MACH
  33. LOGICAL FIRST
  34. SAVE COTCS, PI2REC, NTERMS, XMAX, XSML, XMIN, SQEPS, FIRST
  35. DATA COTCS( 1) / +.2402591609 8295630250 9553617744 970 D+0 /
  36. DATA COTCS( 2) / -.1653303160 1500227845 4746025255 758 D-1 /
  37. DATA COTCS( 3) / -.4299839193 1724018935 6476228239 895 D-4 /
  38. DATA COTCS( 4) / -.1592832233 2754104602 3490851122 445 D-6 /
  39. DATA COTCS( 5) / -.6191093135 1293487258 8620579343 187 D-9 /
  40. DATA COTCS( 6) / -.2430197415 0726460433 1702590579 575 D-11 /
  41. DATA COTCS( 7) / -.9560936758 8000809842 7062083100 000 D-14 /
  42. DATA COTCS( 8) / -.3763537981 9458058041 6291539706 666 D-16 /
  43. DATA COTCS( 9) / -.1481665746 4674657885 2176794666 666 D-18 /
  44. DATA COTCS( 10) / -.5833356589 0366657947 7984000000 000 D-21 /
  45. DATA COTCS( 11) / -.2296626469 6464577392 8533333333 333 D-23 /
  46. DATA COTCS( 12) / -.9041970573 0748332671 9999999999 999 D-26 /
  47. DATA COTCS( 13) / -.3559885519 2060006400 0000000000 000 D-28 /
  48. DATA COTCS( 14) / -.1401551398 2429866666 6666666666 666 D-30 /
  49. DATA COTCS( 15) / -.5518004368 7253333333 3333333333 333 D-33 /
  50. DATA PI2REC / .01161977236 7581343075 5350534900 57 D0 /
  51. DATA FIRST /.TRUE./
  52. C***FIRST EXECUTABLE STATEMENT DCOT
  53. IF (FIRST) THEN
  54. NTERMS = INITDS (COTCS, 15, 0.1*REAL(D1MACH(3)) )
  55. XMAX = 1.0D0/D1MACH(4)
  56. XSML = SQRT(3.0D0*D1MACH(3))
  57. XMIN = EXP (MAX(LOG(D1MACH(1)), -LOG(D1MACH(2))) + 0.01D0)
  58. SQEPS = SQRT(D1MACH(4))
  59. ENDIF
  60. FIRST = .FALSE.
  61. C
  62. Y = ABS(X)
  63. IF (Y .LT. XMIN) CALL XERMSG ('SLATEC', 'DCOT',
  64. + 'ABS(X) IS ZERO OR SO SMALL DCOT OVERFLOWS', 2, 2)
  65. IF (Y .GT. XMAX) CALL XERMSG ('SLATEC', 'DCOT',
  66. + 'NO PRECISION BECAUSE ABS(X) IS TOO BIG', 3, 2)
  67. C
  68. C CAREFULLY COMPUTE Y * (2/PI) = (AINT(Y) + REM(Y)) * (.625 + PI2REC)
  69. C = AINT(.625*Y) + REM(.625*Y) + Y*PI2REC = AINT(.625*Y) + Z
  70. C = AINT(.625*Y) + AINT(Z) + REM(Z)
  71. C
  72. AINTY = AINT (Y)
  73. YREM = Y - AINTY
  74. PRODBG = 0.625D0*AINTY
  75. AINTY = AINT (PRODBG)
  76. Y = (PRODBG-AINTY) + 0.625D0*YREM + PI2REC*Y
  77. AINTY2 = AINT (Y)
  78. AINTY = AINTY + AINTY2
  79. Y = Y - AINTY2
  80. C
  81. IFN = MOD (AINTY, 2.0D0)
  82. IF (IFN.EQ.1) Y = 1.0D0 - Y
  83. C
  84. IF (ABS(X) .GT. 0.5D0 .AND. Y .LT. ABS(X)*SQEPS) CALL XERMSG
  85. + ('SLATEC', 'DCOT',
  86. + 'ANSWER LT HALF PRECISION, ABS(X) TOO BIG OR X NEAR N*PI ' //
  87. + '(N.NE.0)', 1, 1)
  88. C
  89. IF (Y.GT.0.25D0) GO TO 20
  90. DCOT = 1.0D0/X
  91. IF (Y.GT.XSML) DCOT = (0.5D0 + DCSEVL (32.0D0*Y*Y-1.D0, COTCS,
  92. 1 NTERMS)) / Y
  93. GO TO 40
  94. C
  95. 20 IF (Y.GT.0.5D0) GO TO 30
  96. DCOT = (0.5D0 + DCSEVL (8.D0*Y*Y-1.D0, COTCS, NTERMS))/(0.5D0*Y)
  97. DCOT = (DCOT*DCOT-1.D0)*0.5D0/DCOT
  98. GO TO 40
  99. C
  100. 30 DCOT = (0.5D0 + DCSEVL (2.D0*Y*Y-1.D0, COTCS, NTERMS))/(.25D0*Y)
  101. DCOT = (DCOT*DCOT-1.D0)*0.5D0/DCOT
  102. DCOT = (DCOT*DCOT-1.D0)*0.5D0/DCOT
  103. C
  104. 40 IF (X.NE.0.D0) DCOT = SIGN (DCOT, X)
  105. IF (IFN.EQ.1) DCOT = -DCOT
  106. C
  107. RETURN
  108. END