cot.f 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. *DECK COT
  2. FUNCTION COT (X)
  3. C***BEGIN PROLOGUE COT
  4. C***PURPOSE Compute the cotangent.
  5. C***LIBRARY SLATEC (FNLIB)
  6. C***CATEGORY C4A
  7. C***TYPE SINGLE 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 COT(X) calculates the cotangent of the real argument X. X is in
  13. C units of radians.
  14. C
  15. C Series for COT on the interval 0. to 6.25000D-02
  16. C with weighted error 3.76E-17
  17. C log weighted error 16.42
  18. C significant figures required 15.51
  19. C decimal places required 16.88
  20. C
  21. C***REFERENCES (NONE)
  22. C***ROUTINES CALLED CSEVL, INITS, R1MACH, 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 COT
  31. DIMENSION COTCS(8)
  32. LOGICAL FIRST
  33. SAVE COTCS, PI2REC, NTERMS, XMAX, XSML, XMIN, SQEPS, FIRST
  34. DATA COTCS( 1) / .2402591609 8295630E0 /
  35. DATA COTCS( 2) / -.0165330316 01500228E0 /
  36. DATA COTCS( 3) / -.0000429983 91931724E0 /
  37. DATA COTCS( 4) / -.0000001592 83223327E0 /
  38. DATA COTCS( 5) / -.0000000006 19109313E0 /
  39. DATA COTCS( 6) / -.0000000000 02430197E0 /
  40. DATA COTCS( 7) / -.0000000000 00009560E0 /
  41. DATA COTCS( 8) / -.0000000000 00000037E0 /
  42. DATA PI2REC / .01161977236 75813430 E0 /
  43. DATA FIRST /.TRUE./
  44. C***FIRST EXECUTABLE STATEMENT COT
  45. IF (FIRST) THEN
  46. NTERMS = INITS (COTCS, 8, 0.1*R1MACH(3))
  47. XMAX = 1.0/R1MACH(4)
  48. XSML = SQRT (3.0*R1MACH(3))
  49. XMIN = EXP ( MAX(LOG(R1MACH(1)), -LOG(R1MACH(2))) + 0.01)
  50. SQEPS = SQRT (R1MACH(4))
  51. ENDIF
  52. FIRST = .FALSE.
  53. C
  54. Y = ABS(X)
  55. IF (ABS(X) .LT. XMIN) CALL XERMSG ('SLATEC', 'COT',
  56. + 'ABS(X) IS ZERO OR SO SMALL COT OVERFLOWS', 2, 2)
  57. IF (Y .GT. XMAX) CALL XERMSG ('SLATEC', 'COT',
  58. + 'NO PRECISION BECAUSE ABS(X) IS TOO BIG', 3, 2)
  59. C
  60. C CAREFULLY COMPUTE Y * (2/PI) = (AINT(Y) + REM(Y)) * (.625 + PI2REC)
  61. C = AINT(.625*Y) + REM(.625*Y) + Y*PI2REC = AINT(.625*Y) + Z
  62. C = AINT(.625*Y) + AINT(Z) + REM(Z)
  63. C
  64. AINTY = AINT (Y)
  65. YREM = Y - AINTY
  66. PRODBG = 0.625*AINTY
  67. AINTY = AINT (PRODBG)
  68. Y = (PRODBG-AINTY) + 0.625*YREM + Y*PI2REC
  69. AINTY2 = AINT (Y)
  70. AINTY = AINTY + AINTY2
  71. Y = Y - AINTY2
  72. C
  73. IFN = MOD (AINTY, 2.)
  74. IF (IFN.EQ.1) Y = 1.0 - Y
  75. C
  76. IF (ABS(X) .GT. 0.5 .AND. Y .LT. ABS(X)*SQEPS) CALL XERMSG
  77. + ('SLATEC', 'COT',
  78. + 'ANSWER LT HALF PRECISION, ABS(X) TOO BIG OR X NEAR N*PI ' //
  79. + '(N.NE.0)' , 1, 1)
  80. C
  81. IF (Y.GT.0.25) GO TO 20
  82. COT = 1.0/X
  83. IF (Y.GT.XSML) COT = (0.5 + CSEVL (32.0*Y*Y-1., COTCS, NTERMS)) /Y
  84. GO TO 40
  85. C
  86. 20 IF (Y.GT.0.5) GO TO 30
  87. COT = (0.5 + CSEVL (8.0*Y*Y-1., COTCS, NTERMS)) / (0.5*Y)
  88. COT = (COT**2 - 1.0) * 0.5 / COT
  89. GO TO 40
  90. C
  91. 30 COT = (0.5 + CSEVL (2.0*Y*Y-1., COTCS, NTERMS)) / (0.25*Y)
  92. COT = (COT**2 - 1.0) * 0.5 / COT
  93. COT = (COT**2 - 1.0) * 0.5 / COT
  94. C
  95. 40 IF (X.NE.0.) COT = SIGN (COT, X)
  96. IF (IFN.EQ.1) COT = -COT
  97. C
  98. RETURN
  99. END