home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / misc_programming / MATH / GEFPC.A < prev    next >
Text File  |  1990-08-14  |  43KB  |  1,319 lines

  1.  
  2. -- This body is specifically for Meridian Ada using their MATH_LIB
  3. -- This is not efficient. There are some inaccuracies. Just a sample to
  4. -- get the idea of one method of building the body based on an
  5. -- existing set SQRT, EXP, LN, SIN, COS, and ATAN
  6.  
  7. with MATH_LIB ;
  8.  
  9. package body GENERIC_ELEMENTARY_FUNCTIONS is
  10.  
  11.   PI      : constant := 3.14159_26535_89793_23846_26433_83279_50288_41972 ;
  12.   LOG_TWO : constant := 0.69314_71805_59945_30941_72321_21458_17656_80755 ;
  13.   TWO_PI : constant := 2.0 * PI ;
  14.   HALF_PI : constant := PI / 2.0 ;
  15.   FOURTH_PI : constant := PI / 4.0 ;
  16.   EPSILON : FLOAT_TYPE ;
  17.   SQUARE_ROOT_EPSILON : FLOAT_TYPE ;
  18.   HALF_LOG_EPSILON : FLOAT_TYPE ;
  19.   PREVIOUS : FLOAT_TYPE ;
  20.   LOG_LAST : FLOAT_TYPE ;
  21.   LOG_INVERSE_EPSILON : FLOAT_TYPE ;
  22.  
  23.   function EXACT_REMAINDER ( X , Y : FLOAT_TYPE ) return FLOAT_TYPE is
  24.     DENOMINATOR : FLOAT_TYPE := abs X ;
  25.     DIVISOR : FLOAT_TYPE := abs Y ;
  26.     REDUCER : FLOAT_TYPE ;
  27.     SIGN : FLOAT_TYPE := 1.0 ;
  28.   begin
  29.     if Y = 0.0 then
  30.       raise CONSTRAINT_ERROR ;
  31.     elsif X = 0.0 then
  32.       return 0.0 ;
  33.     elsif X = Y then
  34.       return 0.0 ;
  35.     elsif DENOMINATOR < DIVISOR then
  36.       return X ;
  37.     end if ;
  38.     while DENOMINATOR >= DIVISOR loop
  39.       -- put divisors mantissa with denominators exponent to make reducer
  40.       REDUCER := DIVISOR ;
  41.       begin
  42.         while REDUCER * 1_048_576.0 < DENOMINATOR loop
  43.           REDUCER := REDUCER * 1_048_576.0 ;
  44.         end loop ;
  45.       exception when others=> null ;
  46.       end;
  47.     begin
  48.       while REDUCER * 1_024.0 < DENOMINATOR loop
  49.         REDUCER := REDUCER * 1_024.0 ;
  50.       end loop ;
  51.     exception when others=> null ;
  52.     end;
  53.     begin
  54.       while REDUCER * 2.0 < DENOMINATOR loop
  55.           REDUCER := REDUCER * 2.0 ;
  56.         end loop ;
  57.       exception
  58.         when others=>
  59.           null ;
  60.       end;
  61.       DENOMINATOR := DENOMINATOR - REDUCER ;
  62.     end loop ;
  63.     if X < 0.0 then
  64.       return - DENOMINATOR ;
  65.     else
  66.       return DENOMINATOR ;
  67.     end if ;
  68.   end EXACT_REMAINDER ;
  69.  
  70.  
  71.   function LOCAL_ATAN ( Y : FLOAT_TYPE ;
  72.                         X : FLOAT_TYPE := 1.0 ) return FLOAT_TYPE is
  73.     Z : FLOAT_TYPE ;
  74.     RAW_ATAN : FLOAT_TYPE ;
  75.   begin
  76.     if abs Y > abs X then
  77.       Z := abs ( X / Y ) ;
  78.     else
  79.       Z := abs ( Y / X ) ;
  80.     end if;
  81.     if Z = 0.0 then
  82.       RAW_ATAN := 0.0 ;
  83.     elsif Z = 1.0 then
  84.       RAW_ATAN := FOURTH_PI ;
  85.     elsif Z < SQUARE_ROOT_EPSILON then
  86.       RAW_ATAN := Z ;
  87.     else
  88.       RAW_ATAN := FLOAT_TYPE ( MATH_LIB.ATAN ( FLOAT ( Z ) ) ) ;
  89.     end if ;
  90.     if abs Y > abs X then
  91.       RAW_ATAN := HALF_PI - RAW_ATAN ;
  92.     end if ;
  93.     if X > 0.0 then
  94.       if Y > 0.0 then
  95.         return RAW_ATAN ;
  96.       else -- Y < 0.0
  97.         return -RAW_ATAN ;
  98.       end if ;
  99.     else -- X < 0.0
  100.       if Y > 0.0 then
  101.         return PI - RAW_ATAN ;
  102.       else -- Y < 0.0
  103.         return - ( PI - RAW_ATAN ) ;
  104.       end if ;
  105.     end if ;
  106.   end LOCAL_ATAN ;
  107.  
  108.  
  109.  
  110.  
  111. -- SQRT
  112. -- Declaration:
  113. --   function SQRT (X : FLOAT_TYPE) return FLOAT_TYPE;
  114. -- Definition:
  115. --   SQRT(X) ~ sqrt(X)
  116. -- Usage:
  117. --   Z := SQRT(X);
  118. -- Domain:
  119. --   X >= 0.0
  120. -- Range:
  121. --   SQRT(X) >= 0.0
  122. -- Accuracy:
  123. --   (a) Maximum relative error = 2.0 * FLOAT_TYPE'BASE'EPSILON
  124. --   (b) SQRT(0.0) = 0.0
  125. -- Notes:
  126. --   (a) The upper bound of the reachable range of SQRT is approximately given
  127. --   by SQRT(X)<=sqrt(FLOAT_TYPE'SAFE_LARGE)
  128. --   (b) Other standards might impose additional constraints on SQRT. For
  129. --   example, the IEEE standards for binary and radix-independent
  130. --   floating-point arithmetic require greater accuracy in the result of SQRT
  131. --   than this standard requires, and they require that SQRT(-0.0)=-0.0.
  132. --   An implementation of SQRT in GENERIC_ELEMENTARY_FUNCTIONS that
  133. --   conforms to this standard will conform to those other standards if it
  134. --   satisfies their additional constraints.
  135.  
  136.   function SQRT ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  137.   begin
  138.     if X < 0.0 then
  139.       raise ARGUMENT_ERROR ;
  140.     elsif X = 0.0 then
  141.       return X ; -- may be +0.0 or -0.0
  142.     elsif X = 1.0 then
  143.       return 1.0 ; -- needs to be exact for good COMPLEX accuracy
  144.     end if;
  145.     return FLOAT_TYPE ( MATH_LIB.SQRT ( FLOAT ( X ) ) ) ;
  146.   end SQRT ;
  147.  
  148. -- LOG (natural base)
  149. -- Declaration:
  150. --   function LOG (X : FLOAT_TYPE) return FLOAT_TYPE;
  151. -- Definition:
  152. --   LOG(X) ~ ln(X)
  153. -- Usage:
  154. --   Z := LOG(X);   -- natural logarithm
  155. -- Domain:
  156. --   X > 0.0
  157. -- Range:
  158. --   Mathematically unbounded
  159. -- Accuracy:
  160. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  161. --   (b) LOG(1.0) = 0.0
  162. -- Notes:
  163. --   The reachable range of LOG is approximately given by
  164. --   ln(FLOAT_TYPE'SAFE_SMALL) <= LOG(X) <= ln(FLOAT_TYPE'SAFE_LARGE)
  165.  
  166.   function LOG ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  167.   begin
  168.     if X <= 0.0 then
  169.       raise ARGUMENT_ERROR ;
  170.     elsif X = 1.0 then
  171.       return 0.0 ;
  172.     end if ;
  173.     return FLOAT_TYPE ( MATH_LIB.LN ( FLOAT ( X ) ) ) ;
  174.   end LOG ;
  175.  
  176.  
  177. -- LOG (arbitrary base)
  178. -- Declaration:
  179. --   function LOG (X, BASE : FLOAT_TYPE) return FLOAT_TYPE;
  180. -- Definition:
  181. --   LOG(X,BASE) ~ log to base BASE of X
  182. -- Usage:
  183. --   Z := LOG(X, 10.0);   -- base 10 logarithm
  184. --   Z := LOG(X, 2.0);    -- base 2 logarithm
  185. --   Z := LOG(X, BASE);   -- base BASE logarithm
  186. -- Domain:
  187. --   (a) X > 0.0
  188. --   (b) BASE > 0.0
  189. --   (c) BASE /= 1.0
  190. -- Range:
  191. --   Mathematically unbounded
  192. -- Accuracy:
  193. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  194. --   (b) LOG(1.0,BASE) = 0.0
  195. -- Notes:
  196. --   (a) When BASE > 1.0, the reachable range of LOG is approximately given by
  197. --       log to base BASE of FLOAT_TYPE'SAFE_SMALL <= LOG(X,BASE) <=
  198. --       log to base BASE of FLOAT_TYPE'SAFE_LARGE
  199. --   (b) When 0.0 < BASE < 1.0, the reachable range of LOG is approximately given by
  200. --       log to base BASE of FLOAT_TYPE'SAFE_LARGE <= LOG(X,BASE) <=
  201. --       log to base BASE of FLOAT_TYPE'SAFE_SMALL
  202.  
  203.   function LOG ( X , BASE : FLOAT_TYPE ) return FLOAT_TYPE is
  204.   begin
  205.     if X <= 0.0 then
  206.       raise ARGUMENT_ERROR ;
  207.     elsif BASE <= 0.0 or else BASE = 1.0 then
  208.       raise ARGUMENT_ERROR ;
  209.     elsif X = 1.0 then
  210.       return 0.0 ;
  211.     end if ;
  212.     return FLOAT_TYPE ( MATH_LIB.LN ( FLOAT ( X ) )
  213.                       / MATH_LIB.LN ( FLOAT ( BASE ) ) ) ;
  214.   end LOG ;
  215.  
  216.  
  217. -- EXP
  218. -- Declaration:
  219. --   function EXP (X : FLOAT_TYPE) return FLOAT_TYPE;
  220. -- Definition:
  221. --   EXP(X) ~ natural e raised to the X power
  222. -- Usage:
  223. --   Z := EXP(X);   -- e raised to the power X
  224. -- Domain:
  225. --   Mathematically unbounded
  226. -- Range:
  227. --   EXP(X) >= 0.0
  228. -- Accuracy:
  229. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  230. --   (b) EXP(0.0) = 1.0
  231. -- Notes:
  232. --   The usable domain of EXP is approximately given by
  233. --   X <= ln(FLOAT_TYPE'SAFE_LARGE)
  234.  
  235.   function EXP ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  236.     RESULT : FLOAT_TYPE ;
  237.   begin
  238.     if X = 0.0 then
  239.       return 1.0 ;
  240.     elsif X > LOG_LAST then
  241.       raise ARGUMENT_ERROR ;
  242.     end if ;
  243.     RESULT := FLOAT_TYPE ( MATH_LIB.EXP ( FLOAT ( X ) ) ) ;
  244.     if RESULT <= 0.0 then
  245.       return 0.0 ;
  246.     end if ;
  247.     return RESULT ;
  248.   exception
  249.     when others =>
  250.       raise ARGUMENT_ERROR ;
  251.   end EXP ;
  252.  
  253.  
  254.  
  255. -- "**"
  256. -- Declaration:
  257. --   function "**" (X, Y : FLOAT_TYPE) return FLOAT_TYPE;
  258. -- Definition:
  259. --   X ** Y ~ X raised to the power Y
  260. -- Usage:
  261. --   Z := X ** Y;   -- X raised to the power Y
  262. -- Domain:
  263. --   (a) X >= 0.0
  264. --   (b) Y > 0.0 when X = 0.0
  265. -- Range:
  266. --   X ** Y >= 0.0
  267. -- Accuracy:
  268. --   (a) Maximum relative error (when X > 0.0) =
  269. --   (4.0+|Y*ln(X)|/32.0) * FLOAT_TYPE'BASE'EPSILON
  270. --   (b) X ** 0.0 = 1.0 when X > 0.0
  271. --   (c) 0.0 ** Y = 0.0 when Y > 0.0
  272. --   (d) X ** 1.0 = X
  273. --   (e) 1.0 ** Y =1.0
  274. -- Notes:
  275. --   The usable domain of "**", when X > 0.0, is approximately the set of
  276. --   values for X and Y satisfying
  277. --   Y*ln(X) <= ln(FLOAT_TYPE'SAFE_LARGE)
  278. --   This imposes a positive upper bound on Y (as a function of X) when
  279. --   X > 1.0, and a negative lower bound on Y (as a function of X) when
  280. --   0.0 < X < 1.0.
  281.  
  282.   function "**" ( X , Y : FLOAT_TYPE ) return FLOAT_TYPE is
  283.     RESULT : FLOAT_TYPE ;
  284.   begin
  285.     if X = 0.0 and then Y = 0.0 then
  286.       raise ARGUMENT_ERROR ;
  287.     elsif X < 0.0 then
  288.       raise ARGUMENT_ERROR ;
  289.     elsif Y = 0.0 then
  290.       return 1.0 ;
  291.     elsif X = 0.0 then
  292.       return 0.0 ;
  293.     elsif X = 1.0 then
  294.       return 1.0 ;
  295.     elsif Y = 1.0 then
  296.       return X ;
  297.     elsif Y = 2.0 then
  298.       return X * X ;
  299.     end if ;
  300.     RESULT := FLOAT_TYPE ( MATH_LIB.EXP ( FLOAT ( Y ) * MATH_LIB.LN (
  301.         FLOAT ( X ) ) ) );
  302.     if RESULT <= 0.0 then
  303.       return 0.0 ;
  304.     end if ;
  305.     return RESULT ;
  306.   exception
  307.     when others =>
  308.       raise ARGUMENT_ERROR ;
  309.   end "**" ;
  310.  
  311.  
  312. -- SIN (natural cycle)
  313. -- Declaration:
  314. --   function SIN (X : FLOAT_TYPE) return FLOAT_TYPE;
  315. -- Definition:
  316. --   SIN(X) ~ sin(X)
  317. -- Usage:
  318. --   Z := SIN(X);   -- X in radians
  319. -- Domain:
  320. --   Mathematically unbounded
  321. -- Range:
  322. --   |SIN(X)| <= 1.0
  323. -- Accuracy:
  324. --   (a) Maximum relative error = 2.0 * FLOAT_TYPE'BASE'EPSILON
  325. --   when |X| is less than or equal to some documented implementation-dependent
  326. --   threshold, which must not be less than
  327. --     FLOAT_TYPE'MACHINE_RADIX ** FLOAT_TYPE'MACHINE_MANTISSA/2
  328. --   For larger values of |X|, degraded accuracy is allowed. An implementation
  329. --   must document its behavior for large |X|.
  330. --   (b) SIN(0.0) = 0.0
  331.  
  332.   function SIN ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  333.   begin
  334.     if X = 0.0 then
  335.       return 0.0 ;
  336.     elsif abs X < SQUARE_ROOT_EPSILON then
  337.       return X ;
  338.     end if ;
  339.     return FLOAT_TYPE ( MATH_LIB.SIN ( FLOAT ( X ) ) ) ;
  340.   end SIN ;
  341.  
  342. -- SIN (arbitrary cycle)
  343. -- Declaration:
  344. --   function SIN (X, CYCLE : FLOAT_TYPE) return FLOAT_TYPE;
  345. -- Definition:
  346. --   SIN(X,CYCLE) ~ sin(2Pi * X/CYCLE)
  347. -- Usage:
  348. --   Z := SIN(X, 360.0);   -- X in degrees
  349. --   Z := SIN(X, 1.0);     -- X in bams (binary angular measure)
  350. --   Z := SIN(X, CYCLE);   -- X in units such that one complete
  351. --                         -- cycle of rotation corresponds to
  352. --                         -- X = CYCLE
  353. -- Domain:
  354. --   (a) X mathematically unbounded
  355. --   (b) CYCLE > 0.0
  356. -- Range:
  357. --   |SIN(X,CYCLE)| <= 1.0
  358. -- Accuracy:
  359. --   (a) Maximum relative error = 2.0 * FLOAT_TYPE'BASE'EPSILON
  360. --   (b) For integer k, SIN(X,CYCLE)= 0.0 when X=k*CYCLE/2.0
  361. --                                    1.0 when X=(4k+1)*CYCLE/4.0
  362. --                                    -1.0 when X=(4k+3)*CYCLE/4.0
  363.  
  364.   function SIN ( X , CYCLE : FLOAT_TYPE ) return FLOAT_TYPE is
  365.   begin
  366.     if CYCLE <= 0.0 then
  367.       raise ARGUMENT_ERROR ;
  368.     elsif X = 0.0 then
  369.       return 0.0 ;
  370.     elsif X = CYCLE then
  371.       return 0.0 ;
  372.     end if ;
  373.     if abs X > abs CYCLE then
  374.       return FLOAT_TYPE ( MATH_LIB.SIN (
  375.                     FLOAT(EXACT_REMAINDER(X,CYCLE)) * TWO_PI /
  376.                                          FLOAT ( CYCLE ) ) ) ;
  377.     else
  378.       return FLOAT_TYPE ( MATH_LIB.SIN ( FLOAT( X ) * TWO_PI /
  379.                                          FLOAT ( CYCLE ) ) ) ;
  380.     end if ;
  381.   end SIN ;
  382.  
  383.  
  384.  
  385. -- COS (natural cycle)
  386. -- Declaration:
  387. --   function COS (X : FLOAT_TYPE) return FLOAT_TYPE;
  388. -- Definition:
  389. --   COS(X) ~ cos(X)
  390. -- Usage:
  391. --   Z := COS(X);   -- X in radians
  392. -- Domain:
  393. --   Mathematically unbounded
  394. -- Range:
  395. --   |COS(X)| <= 1.0
  396. -- Accuracy:
  397. --   (a) Maximum relative error = 2.0 * FLOAT_TYPE'BASE'EPSILON
  398. --   when |X| is less than or equal to some documented implementation-dependent
  399. --   threshold, which must not be less than
  400. --     FLOAT_TYPE'MACHINE_RADIX ** FLOAT_TYPE'MACHINE_MANTISSA/2
  401. --   For larger values of |X|, degraded accuracy is allowed. An implementation
  402. --   must document its behavior for large |X|.
  403. --   (b) COS(0.0) = 1.0
  404.  
  405.   function COS ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  406.   begin
  407.     if X = 0.0 then
  408.       return 1.0 ;
  409.     elsif abs X < SQUARE_ROOT_EPSILON then
  410.       return 1.0 ;
  411.     end if ;
  412.     return FLOAT_TYPE ( MATH_LIB.COS ( FLOAT( X ) ) ) ;
  413.   end COS ;
  414.  
  415.  
  416.  
  417. -- COS (arbitrary cycle)
  418. -- Declaration:
  419. --   function COS (X, CYCLE : FLOAT_TYPE) return FLOAT_TYPE;
  420. -- Definition:
  421. --   COS(X,CYCLE) ~ cos(2Pi*X/CYCLE)
  422. -- Usage:
  423. --   Z := COS(X, 360.0);   -- X in degrees
  424. --   Z := COS(X, 1.0);     -- X in bams
  425. --   Z := COS(X, CYCLE);   -- X in units such that one complete
  426. --                         -- cycle of rotation corresponds to
  427. --                         -- X = CYCLE
  428. -- Domain:
  429. --   (a) X mathematically unbounded
  430. --   (b) CYCLE > 0.0
  431. -- Range:
  432. --   |COS(X,CYCLE)| <= 1.0
  433. -- Accuracy:
  434. --   (a) Maximum relative error = 2.0 * FLOAT_TYPE'BASE'EPSILON
  435. --   (b) For integer k, COS(X,CYCLE) = 1.0 when X=k*CYCLE
  436. --                                     0.0 when X=(2k+1)*CYCLE/4.0
  437. --                                    -1.0 when X=(2k+1)*CYCLE/2.0
  438.  
  439.   function COS ( X , CYCLE : FLOAT_TYPE ) return FLOAT_TYPE is
  440.   begin
  441.     if CYCLE <= 0.0 then
  442.       raise ARGUMENT_ERROR ;
  443.     elsif X = 0.0 then
  444.       return 1.0 ;
  445.     elsif X = CYCLE then
  446.       return 1.0 ;
  447.     end if ;
  448.     if abs X > abs CYCLE then
  449.       return FLOAT_TYPE ( MATH_LIB.COS (
  450.                     FLOAT(EXACT_REMAINDER(X,CYCLE)) * TWO_PI /
  451.                                          FLOAT ( CYCLE ) ) ) ;
  452.     else
  453.       return FLOAT_TYPE ( MATH_LIB.COS ( FLOAT( X ) * TWO_PI /
  454.                                          FLOAT ( CYCLE ) ) ) ;
  455.     end if;
  456.   end COS ;
  457.  
  458.  
  459.  
  460. -- TAN (natural cycle)
  461. -- Declaration:
  462. --   function TAN (X : FLOAT_TYPE) return FLOAT_TYPE;
  463. -- Definition:
  464. --   TAN(X) ~ tan(X)
  465. -- Usage:
  466. --   Z := TAN(X);   -- X in radians
  467. -- Domain:
  468. --   Mathematically unbounded
  469. -- Range:
  470. --   Mathematically unbounded
  471. -- Accuracy:
  472. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  473. --   when |X| is less than or equal to some documented implementation-dependent
  474. --   threshold, which must not be less than
  475. --     FLOAT_TYPE'MACHINE_RADIX ** FLOAT_TYPE'MACHINE_MANTISSA/2
  476. --   For larger values of |X|, degraded accuracy is allowed. An implementation
  477. --   must document its behavior for large |X|.
  478. --   (b) TAN(0.0) = 0.0
  479.  
  480.   function TAN ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  481.   begin
  482.     if X = 0.0 then
  483.       return 0.0 ;
  484.     elsif abs X < SQUARE_ROOT_EPSILON then
  485.       return X ;
  486.     end if ;
  487.     return SIN ( X ) / COS ( X ) ;
  488.   end TAN ;
  489.  
  490. -- TAN (arbitrary cycle)
  491. -- Declaration:
  492. --   function TAN (X, CYCLE : FLOAT_TYPE) return FLOAT_TYPE;
  493. -- Definition:
  494. --   TAN(X,CYCLE) ~ tan(2Pi*X/CYCLE)
  495. -- Usage:
  496. --   Z := TAN(X, 360.0);   -- X in degrees
  497. --   Z := TAN(X, 1.0);     -- X in bams
  498. --   Z := TAN(X, CYCLE);   -- X in units such that one complete
  499. --                         -- cycle of rotation corresponds to
  500. --                         -- X = CYCLE
  501. -- Domain:
  502. --   (a) X /= (2k+1)*CYCLE/4.0, for integer k
  503. --   (b) CYCLE > 0.0
  504. -- Range:
  505. --   Mathematically unbounded
  506. -- Accuracy:
  507. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  508. --   (b) TAN(X,CYCLE) = 0.0 when X=k*CYCLE/2.0, for integer k
  509.  
  510.   function TAN ( X , CYCLE : FLOAT_TYPE ) return FLOAT_TYPE is
  511.   begin
  512.     if CYCLE <= 0.0 then
  513.       raise ARGUMENT_ERROR ;
  514.     elsif X = 0.0 then
  515.       return 0.0 ;
  516.     end if ;
  517.     return SIN ( X , CYCLE ) / COS ( X , CYCLE ) ;
  518.   end TAN ;
  519.  
  520.  
  521.  
  522. -- COT (natural cycle)
  523. -- Declaration:
  524. --   function COT (X : FLOAT_TYPE) return FLOAT_TYPE;
  525. -- Definition:
  526. --   COT(X) ~ cot(X)
  527. -- Usage:
  528. --   Z := COT(X);   -- X in radians
  529. -- Domain:
  530. --   X /= 0.0
  531. -- Range:
  532. --   Mathematically unbounded
  533. -- Accuracy:
  534. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  535. --   when |X| is less than or equal to some documented implementation-dependent
  536. --   threshold, which must not be less than
  537. --     FLOAT_TYPE'MACHINE_RADIX ** FLOAT_TYPE'MACHINE_MANTISSA/2
  538. --   For larger values of |X|, degraded accuracy is allowed. An implementation
  539. --   must document its behavior for large |X|.
  540.  
  541.   function COT ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  542.   begin
  543.     if X = 0.0 then
  544.       raise ARGUMENT_ERROR ;
  545.     end if ;
  546.     return COS ( X ) / SIN ( X ) ;
  547.   end COT ;
  548.  
  549.  
  550. -- COT (arbitrary cycle)
  551. -- Declaration:
  552. --   function COT (X, CYCLE : FLOAT_TYPE) return FLOAT_TYPE;
  553. -- Definition:
  554. --   COT(X,CYCLE) ~ cot(2Pi*X/CYCLE)
  555. -- Usage:
  556. --   Z := COT(X, 360.0);   -- X in degrees
  557. --   Z := COT(X, 1.0);     -- X in bams
  558. --   Z := COT(X, CYCLE);   -- X in units such that one complete
  559. --                         -- cycle of rotation corresponds to
  560. --                         -- X = CYCLE
  561. -- Domain:
  562. --   (a) X /= k*CYCLE/2.0, for integer k
  563. --   (b) CYCLE > 0.0
  564. -- Range:
  565. --   Mathematically unbounded
  566. -- Accuracy:
  567. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  568. --   (b) COT(X,CYCLE) = 0.0 when X=(2k+1)*CYCLE/4.0, for integer k
  569.  
  570.   function COT ( X , CYCLE : FLOAT_TYPE ) return FLOAT_TYPE is
  571.   begin
  572.     if CYCLE <= 0.0 then
  573.       raise ARGUMENT_ERROR ;
  574.     elsif X = 0.0 then
  575.       raise ARGUMENT_ERROR ;
  576.     end if ;
  577.     return  COS ( X , CYCLE ) / SIN ( X , CYCLE ) ;
  578.   end COT ;
  579.  
  580.  
  581.  
  582. -- ARCSIN (natural cycle)
  583. -- Declaration:
  584. --   function ARCSIN (X : FLOAT_TYPE) return FLOAT_TYPE;
  585. -- Definition:
  586. --   ARCSIN(X) ~ arcsine(X)
  587. -- Usage:
  588. --   Z := ARCSIN(X);   -- Z in radians
  589. -- Domain:
  590. --   |X| <= 1.0
  591. -- Range:
  592. --   |ARCSIN(X)| <= Pi/2
  593. -- Accuracy:
  594. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  595. --   (b) ARCSIN(0.0) = 0.0
  596. --   (c) ARCSIN(1.0) = Pi/2
  597. --   (d) ARCSIN(-1.0) = -Pi/2
  598. -- Notes:
  599. --   - Pi/2 and Pi/2 are not safe numbers of FLOAT_TYPE. Accordingly,
  600. --   an implementation may exceed the range limits, but only slightly;
  601. --   cf.Section 9 for a precise statement of the requirements. Similarly,
  602. --   when accuracy requirement (c) or (d) applies, an implementation may
  603. --   approximate the prescribed result, but only within narrow limits;
  604. --   cf.Section 10 for a precise statement of the requirements.
  605.  
  606.   function ARCSIN ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  607.   begin
  608.     if abs X > 1.0 then
  609.       raise ARGUMENT_ERROR ;
  610.     elsif X = 0.0 then
  611.       return 0.0 ;
  612.     elsif abs X < SQUARE_ROOT_EPSILON then
  613.       return X ;
  614.     elsif X = 1.0 then
  615.       return PI / 2.0 ;
  616.     elsif X = -1.0 then
  617.       return -PI / 2.0 ;
  618.     end if ;
  619.     return ARCTAN ( X / SQRT ( 1.0 - X * X ) ) ;
  620.   end ARCSIN ;
  621.  
  622.  
  623. -- ARCSIN (arbitrary cycle)
  624. -- Declaration:
  625. --   function ARCSIN (X, CYCLE : FLOAT_TYPE) return FLOAT_TYPE;
  626. -- Definition:
  627. --   ARCSIN(X,CYCLE) ~ arcsin(X)*CYCLE/2Pi
  628. -- Usage:
  629. --   Z := ARCSIN(X, 360.0);   -- Z in degrees
  630. --   Z := ARCSIN(X, 1.0);     -- Z in bams
  631. --   Z := ARCSIN(X, CYCLE);   -- Z in units such that one complete
  632. --                            -- cycle of rotation corresponds to
  633. --                            -- Z = CYCLE
  634. -- Domain:
  635. --   (a) |X| <= 1.0
  636. --   (b) CYCLE > 0.0
  637. -- Range:
  638. --   |ARCSIN(X,CYCLE) <= CYCLE/4.0
  639. -- Accuracy:
  640. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  641. --   (b) ARCSIN(0.0,CYCLE) = 0.0
  642. --   (c) ARCSIN(1.0,CYCLE) = CYCLE/4.0
  643. --   (d) ARCSIN(-1.0,CYCLE) = -CYCLE/4.0
  644. -- Notes:
  645. --   - CYCLE/4.0 and CYCLE/4.0
  646. --   might not be safe numbers of FLOAT_TYPE. Accordingly,
  647. --   an implementation may exceed the range limits, but only slightly;
  648. --   cf.Section 9 for a precise statement of the requirements. Similarly,
  649. --   when accuracy requirement (c) or (d) applies, an implementation may
  650. --   approximate the prescribed result, but only within narrow limits;
  651. --   cf.Section 10 for a precise statement of the requirements.
  652.  
  653.   function ARCSIN ( X , CYCLE : FLOAT_TYPE ) return FLOAT_TYPE is
  654.   begin
  655.     if CYCLE <= 0.0 then
  656.       raise ARGUMENT_ERROR ;
  657.     elsif abs X > 1.0 then
  658.       raise ARGUMENT_ERROR ;
  659.     elsif X = 0.0 then
  660.       return 0.0 ;
  661.     elsif X = 1.0 then
  662.       return CYCLE / 4.0 ;
  663.     elsif X = -1.0 then
  664.       return -CYCLE / 4.0 ;
  665.     end if ;
  666.     return ARCTAN ( X / SQRT ( 1.0 - X * X ) , 1.0 , CYCLE ) ;
  667.   end ARCSIN ;
  668.  
  669.  
  670. -- ARCCOS (natural cycle)
  671. -- Declaration:
  672. --   function ARCCOS (X : FLOAT_TYPE) return FLOAT_TYPE;
  673. -- Definition:
  674. --   ARCCOS(X) ~ arccos(X)
  675. -- Usage:
  676. --   Z := ARCCOS(X);   -- Z in radians
  677. -- Domain:
  678. --   |X| <= 1.0
  679. -- Range:
  680. --   0.0 <= ARCCOS(X) <= Pi
  681. -- Accuracy:
  682. --   (a)  Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  683. --   (b) ARCCOS(1.0) = 0.0
  684. --   (c) ARCCOS(0.0) = Pi/2
  685. --   (d) ARCCOS(-1.0) = Pi
  686. -- Notes:
  687. --   Pi/2 and Pi are not safe numbers of FLOAT_TYPE. Accordingly,
  688. --   an implementation may exceed the range limits, but only slightly;
  689. --   cf.Section 9 for a precise statement of the requirements. Similarly,
  690. --   when accuracy requirement (c) or (d) applies, an implementation may
  691. --   approximate the prescribed result, but only within narrow limits;
  692. --   cf.Section 10 for a precise statement of the requirements.
  693.  
  694.   function ARCCOS ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  695.     TEMP : FLOAT_TYPE ;
  696.   begin
  697.     if abs X > 1.0 then
  698.       raise ARGUMENT_ERROR ;
  699.     elsif X = 0.0 then
  700.       return PI / 2.0 ;
  701.     elsif X = 1.0 then
  702.       return 0.0 ;
  703.     elsif X = -1.0 then
  704.       return PI ;
  705.     end if ;
  706.     TEMP := ARCTAN ( SQRT ( 1.0 - X * X ) / X ) ;
  707.     if TEMP < 0.0 then
  708.       TEMP := PI + TEMP ;
  709.     end if ;
  710.     return TEMP ;
  711.   end ARCCOS ;
  712.  
  713.  
  714. -- ARCCOS (arbitrary cycle)
  715. -- Declaration:
  716. --   function ARCCOS (X, CYCLE : FLOAT_TYPE) return FLOAT_TYPE;
  717. -- Definition:
  718. --   ARCCOS(X,CYCLE) ~ arccos(X)*CYCLE/2Pi
  719. -- Usage:
  720. --   Z := ARCCOS(X, 360.0);   -- Z in degrees
  721. --   Z := ARCCOS(X, 1.0);     -- Z in bams
  722. --   Z := ARCCOS(X, CYCLE);   -- Z in units such that one complete
  723. --                            -- cycle of rotation corresponds to
  724. --                            -- Z = CYCLE
  725. -- Domain:
  726. --   (a) |X| <= 1.0
  727. --   (b) CYCLE > 0.0
  728. -- Range:
  729. --   0.0 <= ARCCOS(X,CYCLE) <= CYCLE/2.0
  730. -- Accuracy:
  731. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  732. --   (b) ARCCOS(1.0,CYCLE) = 0.0
  733. --   (c) ARCCOS(0.0,CYCLE) = CYCLE/4.0
  734. --   (d) ARCCOS(-1.0,CYCLE) = CYCLE/2.0
  735. -- Notes:
  736. --   CYCLE/4.0 and CYCLE/2.0
  737. --   might not be safe numbers of FLOAT_TYPE. Accordingly,
  738. --   an implementation may exceed the range limits, but only slightly;
  739. --   cf.Section 9 for a precise statement of the requirements. Similarly,
  740. --   when accuracy requirement (c) or (d) applies, an implementation may
  741. --   approximate the prescribed result, but only within narrow limits;
  742. --   cf.Section 10 for a precise statement of the requirements.
  743.  
  744.   function ARCCOS ( X , CYCLE : FLOAT_TYPE ) return FLOAT_TYPE is
  745.     TEMP : FLOAT_TYPE ;
  746.   begin
  747.   if CYCLE <= 0.0 then
  748.       raise ARGUMENT_ERROR ;
  749.     elsif abs X > 1.0 then
  750.       raise ARGUMENT_ERROR ;
  751.     elsif X = 0.0 then
  752.       return CYCLE / 4.0 ;
  753.     elsif X = 1.0 then
  754.       return 0.0 ;
  755.     elsif X = -1.0 then
  756.       return CYCLE / 2.0 ;
  757.     end if ;
  758.     TEMP := ARCTAN ( SQRT ( 1.0 - X * X ) / X , 1.0 , CYCLE ) ;
  759.     if TEMP < 0.0 then
  760.       TEMP := CYCLE / 2.0 + TEMP ;
  761.     end if ;
  762.     return TEMP ;
  763.   end ARCCOS ;
  764.  
  765.  
  766.  
  767. -- ARCTAN (natural cycle)
  768. -- Declaration:
  769. --   function ARCTAN (Y : FLOAT_TYPE;
  770. --                    X : FLOAT_TYPE := 1.0) return FLOAT_TYPE;
  771. -- Definition:
  772. --   (a) ARCTAN(Y) ~ arctan(Y)
  773. --   (b) ARCTAN(Y,X) ~ arctan(Y/X) when X >= 0.0
  774. --                     arctan(Y/X)+Pi when X < 0.0 and Y >= 0.0
  775. --                     arctan(Y/X)-Pi when X < 0.0 and Y < 0.0
  776. -- Usage:
  777. --   Z := ARCTAN(Y);      -- Z, in radians, is the angle (in the
  778. --                        -- quadrant containing the point (1.0,Y))
  779. --                        -- whose tangent is Y
  780. --   Z := ARCTAN(Y, X);   -- Z, in radians, is the angle (in the
  781. --                        -- quadrant containing the point (X,Y))
  782. --                        -- whose tangent is Y/X
  783. -- Domain:
  784. --   X /= 0.0 when Y = 0.0
  785. -- Range:
  786. --     (a) |ARCTAN(Y)| <= Pi/2
  787. --     (b) 0.0 < ARCTAN(Y,X) <= Pi when Y >= 0.0
  788. --     (c) -Pi <= ARCTAN(Y,X) <= 0.0 when Y < 0.0
  789. -- Accuracy:
  790. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  791. --   (b) ARCTAN(0.0) = 0.0
  792. --   (c) ARCTAN((0.0,X) = 0.0 when X > 0.0
  793. --                        Pi when X < 0.0
  794. --   (d) ARCTAN(Y,0.0) = Pi/2 when Y > 0.0
  795. --                       -Pi/2 when Y < 0.0
  796. -- Notes:
  797. --   -Pi,-Pi/2,Pi/2 and Pi are not safe numbers of FLOAT_TYPE. Accordingly,
  798. --   an implementation may exceed the range limits, but only slightly;
  799. --   cf.Section 9 for a precise statement of the requirements. Similarly,
  800. --   when accuracy requirement (c) or (d) applies, an implementation may
  801. --   approximate the prescribed result, but only within narrow limits;
  802. --   cf.Section 10 for a precise statement of the requirements.
  803.  
  804.  
  805.  
  806.  function ARCTAN ( Y : FLOAT_TYPE ;
  807.                     X : FLOAT_TYPE := 1.0 ) return FLOAT_TYPE is
  808.     T : FLOAT_TYPE ;
  809.   begin
  810.     if X = 0.0 and then Y = 0.0 then
  811.       raise ARGUMENT_ERROR ;
  812.     elsif Y = 0.0 then
  813.       if X > 0.0 then
  814.         return 0.0 ;
  815.       else -- X < 0.0
  816.         return PI ;
  817.       end if;
  818.     elsif X = 0.0 then
  819.       if Y > 0.0 then
  820.         return HALF_PI ;
  821.       else -- Y < 0.0
  822.         return - HALF_PI ;
  823.       end if;
  824.     else
  825.       return LOCAL_ATAN ( Y , X ) ;
  826.     end if ;
  827.   end ARCTAN ;
  828.  
  829.  
  830. -- ARCTAN (arbitrary cycle)
  831. -- Declaration:
  832. --   function ARCTAN (Y     : FLOAT_TYPE;
  833. --                    X     : FLOAT_TYPE := 1.0;
  834. --                    CYCLE : FLOAT_TYPE)        return FLOAT_TYPE;
  835. -- Definition:
  836. --   (a) ARCTAN(Y,CYCLE) ~ arctan(Y)*CYCLE/2Pi
  837. --   (b) ARCTAN(Y,X,CYCLE) ~ arctan(Y/X)*CYCLE/2Pi when X >= 0.0
  838. --                           (arctan(Y/X)+Pi)*CYCLE/2Pi when X < 0.0 and Y >= 0.0
  839. --                           (arctan(Y/X)-Pi)*CYCLE/2Pi when X < 0.0 and Y < 0.0
  840. -- Usage:
  841. --   Z := ARCTAN(Y, CYCLE => 360.0);   -- Z, in degrees, is the
  842. --                                     -- angle (in the quadrant
  843. --                                     -- containing the point
  844. --                                     -- (1.0,Y)) whose tangent is Y
  845. --   Z := ARCTAN(Y, CYCLE => 1.0);     -- Z, in bams, is the
  846. --                                     -- angle (in the quadrant
  847. --                                     -- containing the point
  848. --                                     -- (1.0,Y)) whose tangent is Y
  849. --   Z := ARCTAN(Y, CYCLE => CYCLE);   -- Z, in units such that one
  850. --                                     -- complete cycle of rotation
  851. --                                     -- corresponds to Z = CYCLE,
  852. --                                     -- is the angle (in the
  853. --                                     -- quadrant containing the
  854. --                                     -- point (1.0,Y)) whose
  855. --                                     -- tangent is Y
  856. --   Z := ARCTAN(Y, X, 360.0);         -- Z, in degrees, is the
  857. --                                     -- angle (in the quadrant
  858. --                                     -- containing the point (X,Y))
  859. --                                     -- whose tangent is Y/X
  860. --   Z := ARCTAN(Y, X, 1.0);           -- Z, in bams, is the
  861. --                                     -- angle (in the quadrant
  862. --                                     -- containing the point (X,Y))
  863. --                                     -- whose tangent is Y/X
  864. --   Z := ARCTAN(Y, X, CYCLE);         -- Z, in units such that one
  865. --                                     -- complete cycle of rotation
  866. --                                     -- corresponds to Z = CYCLE,
  867. --                                     -- is the angle (in the
  868. --                                     -- quadrant containing the
  869. --                                     -- point (X,Y)) whose
  870. --                                     -- tangent is Y/X
  871. -- Domain:
  872. --   (a) X /= 0.0 when Y = 0.0
  873. --   (b) CYCLE > 0.0
  874. -- Range:
  875. --   (a) |ARCTAN(Y,CYCLE)| <= CYCLE/4.0
  876. --   (b) 0.0 <= ARCTAN(Y,X,CYCLE) <= CYCLE/2.0 when Y >= 0.0
  877. --   (c) -CYCLE/2.0 <= ARCTAN(Y,X,CYCLE) <= 0.0 when Y < 0.0
  878. -- Accuracy:
  879. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  880. --   (b) ARCTAN(0.0,CYCLE) = 0.0
  881. --   (c) ARCTAN(0.0,X,CYCLE) = 0.0 when X > 0.0
  882. --                             CYCLE/2.0 when X < 0.0
  883. --   (d) ARCTAN(Y,0.0,CYCLE) = CYCLE/4.0 when Y > 0.0
  884. --                             -CYCLE/4.0 when Y < 0.0
  885. -- Notes:
  886. --   -CYCLE/2.0, -CYCLE/4.0, CYCLE/4.0 and CYCLE/2.0
  887. --   might not be safe numbers of FLOAT_TYPE. Accordingly,
  888. --   an implementation may exceed the range limits, but only slightly;
  889. --   cf.Section 9 for a precise statement of the requirements. Similarly,
  890. --   when accuracy requirement (c) or (d) applies, an implementation may
  891. --   approximate the prescribed result, but only within narrow limits;
  892. --   cf.Section 10 for a precise statement of the requirements.
  893.  
  894.   function ARCTAN ( Y : FLOAT_TYPE ;
  895.                     X : FLOAT_TYPE := 1.0 ;
  896.                     CYCLE : FLOAT_TYPE ) return FLOAT_TYPE is
  897.   begin
  898.     if CYCLE <= 0.0 then
  899.       raise ARGUMENT_ERROR ;
  900.     elsif X = 0.0 and then Y = 0.0 then
  901.       raise ARGUMENT_ERROR ;
  902.     elsif Y = 0.0 then
  903.       if X > 0.0 then
  904.         return 0.0 ;
  905.       else -- X < 0.0
  906.         return CYCLE / 2.0 ;
  907.       end if;
  908.     elsif X = 0.0 then
  909.       if Y > 0.0 then
  910.         return CYCLE / 4.0 ;
  911.       else -- Y < 0.0
  912.         return -CYCLE / 4.0 ;
  913.       end if;
  914.     else
  915.       return LOCAL_ATAN ( Y , X ) * CYCLE / TWO_PI ;
  916.     end if ;
  917.   end ARCTAN ;
  918.  
  919.  
  920.  
  921. -- ARCCOT (natural cycle)
  922. -- Declaration:
  923. --   function ARCCOT (X : FLOAT_TYPE;
  924. --                    Y : FLOAT_TYPE := 1.0) return FLOAT_TYPE;
  925. -- Definition:
  926. --   (a) ARCCOT(X) ~ arccot(X)
  927. --   (b) ARCCOT(X,Y) ~ arccot(X/Y) when Y >= 0.0
  928. --                     arccot(X/Y)-Pi when Y < 0.0
  929. -- Usage:
  930. --   Z := ARCCOT(X);      -- Z, in radians, is the angle (in the
  931. --                        -- quadrant containing the point (X,1.0)
  932. --                        -- whose cotangent is X
  933. --   Z := ARCCOT(X, Y);   -- Z, in radians, is the angle (in the
  934. --                        -- quadrant containing the point (X,Y))
  935. --                        -- whose cotangent is X/Y
  936. -- Domain:
  937. --   Y /= 0.0 when X = 0.0
  938. -- Range:
  939. --   (a) 0.0 <= ARCCOT(X) <= Pi
  940. --   (b) 0.0 <= ARCCOT(X,Y) <= Pi when Y >= 0.0
  941. --   (c) -Pi <= ARCCOT(X,Y) <= 0.0 when Y < 0.0
  942. -- Accuracy:
  943. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  944. --   (b) ARCCOT(0.0) = Pi/2
  945. --   (c) ARCCOT(0.0,Y) = Pi/2 when Y > 0.0
  946. --                       -Pi/2 when Y < 0.0
  947. --   (d) ARCCOT(X,0.0) = 0.0 when X > 0.0
  948. --                       Pi when X < 0.0
  949. -- Notes:
  950. --   -Pi,-Pi/2,Pi/2 and Pi are not safe numbers of FLOAT_TYPE. Accordingly,
  951. --   an implementation may exceed the range limits, but only slightly;
  952. --   cf.Section 9 for a precise statement of the requirements. Similarly,
  953. --   when accuracy requirement (b), (c) or (d) applies, an implementation may
  954. --   approximate the prescribed result, but only within narrow limits;
  955. --   cf.Section 10 for a precise statement of the requirements.
  956.  
  957.   function ARCCOT ( X : FLOAT_TYPE ;
  958.                     Y : FLOAT_TYPE := 1.0 ) return FLOAT_TYPE is
  959.   begin
  960.     return ARCTAN ( Y , X ) ;  -- just reverse arguments
  961.   end ARCCOT ;
  962.  
  963.  
  964.  
  965. -- ARCCOT (arbitrary cycle)
  966. -- Declaration:
  967. --   function ARCCOT (X     : FLOAT_TYPE;
  968. --                    Y     : FLOAT_TYPE := 1.0;
  969. --                    CYCLE : FLOAT_TYPE)        return FLOAT_TYPE;
  970. -- Definition:
  971. --   (a) ARCCOT(X,CYCLE) ~ arccot(X)*CYCLE/2Pi
  972. --   (b) ARCCOT(X,Y) ~ arccot(X/Y)*CYCLE/2Pi when Y >= 0.0
  973. --                     (arccot(X/Y)-Pi)*CYCLE/2Pi
  974. -- Usage:
  975. --   Z := ARCCOT(X, CYCLE => 360.0);   -- Z, in degrees, is the
  976. --                                     -- angle (in the quadrant
  977. --                                     -- containing the point
  978. --                                     -- (X,1.0)) whose cotangent
  979. --                                     -- is X
  980. --   Z := ARCCOT(X, CYCLE => 1.0);     -- Z, in bams, is the
  981. --                                     -- angle (in the quadrant
  982. --                                     -- containing the point
  983. --                                     -- (X,1.0)) whose cotangent
  984. --                                     -- is X
  985. --   Z := ARCCOT(X, CYCLE => CYCLE);   -- Z, in units such that one
  986. --                                     -- complete cycle of rotation
  987. --                                     -- corresponds to Z = CYCLE,
  988. --                                     -- is the angle (in the
  989. --                                     -- quadrant containing the
  990. --                                     -- point (X,1.0)) whose
  991. --                                     -- cotangent is X
  992. --   Z := ARCCOT(X, Y, 360.0);         -- Z, in degrees, is the
  993. --                                     -- angle (in the quadrant
  994. --                                     -- containing the point (X,Y))
  995. --                                     -- whose cotangent is X/Y
  996. --   Z := ARCCOT(X, Y, 1.0);           -- Z, in bams, is the
  997. --                                     -- angle (in the quadrant
  998. --                                     -- containing the point (X,Y)
  999. --                                     -- whose cotangent is X/Y
  1000. --   Z := ARCCOT(X, Y, CYCLE);         -- Z, in units such that one
  1001. --                                     -- complete cycle of rotation
  1002. --                                     -- corresponds to Z = CYCLE
  1003. --                                     -- is the angle (in the
  1004. --                                     -- quadrant containing the
  1005. --                                     -- point (X,Y)) whose
  1006. --                                     -- cotangent is X/Y
  1007. -- Domain:
  1008. --   (a) Y /= 0.0 when X = 0.0
  1009. --   (b) CYCLE > 0.0
  1010. -- Range:
  1011. --   (a) 0.0 <= ARCCOT((X,CYCLE) <= CYCLE/2.0
  1012. --   (b) 0.0 <= ARCCOT(X,Y,CYCLE) <= CYCLE/2.0 when Y >= 0.0
  1013. --   (c) -CYCLE/2.0 <= ARCCOT(X,Y,CYCLE) <= 0.0 when Y < 0.0
  1014. -- Accuracy:
  1015. --   (a) Maximum relative error = 4.0 * FLOAT_TYPE'BASE'EPSILON
  1016. --   (b) ARCCOT(0.0,CYCLE) = CYCLE/4.0
  1017. --   (c) ARCCOT(0.0,Y,CYCLE) = CYCLE/4.0 when Y > 0.0
  1018. --                             -CYCLE/4.0 when Y < 0.0
  1019. --   (d) ARCCOT(X,0.0,CYCLE) = 0.0 when X > 0.0
  1020. --                             CYCLE/2.0 when X < 0.0
  1021. -- Notes:
  1022. --   - CYCLE/2.0, - CYCLE/4.0, CYCLE/4.0 and CYCLE/2.0
  1023. --   might not be safe numbers of FLOAT_TYPE. Accordingly,
  1024. --   an implementation may exceed the range limits, but only slightly;
  1025. --   cf.Section 9 for a precise statement of the requirements. Similarly,
  1026. --   when accuracy requirement (c) or (d) applies, an implementation may
  1027. --   approximate the prescribed result, but only within narrow limits;
  1028. --   cf.Section 10 for a precise statement of the requirements.
  1029.  
  1030.   function ARCCOT ( X : FLOAT_TYPE ;
  1031.                     Y : FLOAT_TYPE := 1.0 ;
  1032.                     CYCLE : FLOAT_TYPE ) return FLOAT_TYPE is
  1033.   begin
  1034.     return ARCTAN ( Y , X , CYCLE ) ;  -- just reverse arguments
  1035.   end ARCCOT ;
  1036.  
  1037.  
  1038. -- SINH
  1039. -- Declaration:
  1040. --   function SINH (X : FLOAT_TYPE) return FLOAT_TYPE;
  1041. -- Definition:
  1042. --   SINH(X) ~ hyperbolic sine of X
  1043. -- Usage:
  1044. --   Z := SINH(X);
  1045. -- Domain:
  1046. --   Mathematically unbounded
  1047. -- Range:
  1048. --   Mathematically unbounded
  1049. -- Accuracy:
  1050. --   (a) Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1051. --   (b) SINH(0.0) = 0.0
  1052. -- Notes:
  1053. --   The usable domain of SINH is approximately given by
  1054. --   |X| <= ln(FLOAT_TYPE'SAFE_LARGE)+ln(2.0)
  1055.  
  1056.   function SINH ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  1057.     EXP_X : FLOAT_TYPE ;
  1058.   begin
  1059.     if X = 0.0 then
  1060.       return 0.0 ;
  1061.     elsif abs X < SQUARE_ROOT_EPSILON then
  1062.       return X ;
  1063.     elsif abs X > LOG_LAST + LOG_TWO then
  1064.       raise ARGUMENT_ERROR ;
  1065.     elsif  X > LOG_INVERSE_EPSILON then
  1066.       return EXP ( X - LOG_TWO ) ;
  1067.     elsif X < -LOG_INVERSE_EPSILON then
  1068.       return - EXP ( (-X) - LOG_TWO ) ;
  1069.     end if;
  1070.     EXP_X := EXP ( X ) ;
  1071.     return 0.5 * ( EXP_X - 1.0 / EXP_X ) ;
  1072.   exception
  1073.     when others =>
  1074.       raise ARGUMENT_ERROR ;
  1075.   end SINH ;
  1076.  
  1077.  
  1078. -- COSH
  1079. -- Declaration:
  1080. --   function COSH (X : FLOAT_TYPE) return FLOAT_TYPE;
  1081. -- Definition:
  1082. --   COSH(X) ~ hyperbolic cosine of X
  1083. -- Usage:
  1084. --   Z := COSH(X);
  1085. -- Domain:
  1086. --   Mathematically unbounded
  1087. -- Range:
  1088. --   COSH(X) >= 1.0
  1089. -- Accuracy:
  1090. --   (a) Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1091. --   (b) COSH(0.0) = 1.0
  1092. -- Notes:
  1093. --   The usable domain of COSH is approximately given by
  1094. --   |X| <= ln(FLOAT_TYPE'SAFE_LARGE)+ln(2.0)
  1095.  
  1096.   function COSH ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  1097.     EXP_X : FLOAT_TYPE ;
  1098.   begin
  1099.     if X = 0.0 then
  1100.       return 1.0 ;
  1101.     elsif abs X < SQUARE_ROOT_EPSILON then
  1102.       return 1.0 ;
  1103.     elsif abs X > LOG_LAST + LOG_TWO then
  1104.       raise ARGUMENT_ERROR ;
  1105.     elsif  abs X > LOG_INVERSE_EPSILON then
  1106.       return EXP ( (abs X) - LOG_TWO ) ;
  1107.     end if ;
  1108.     EXP_X := EXP ( X ) ;
  1109.     return 0.5 * ( EXP_X + 1.0 / EXP_X ) ;
  1110.   exception
  1111.     when others =>
  1112.       raise ARGUMENT_ERROR ;
  1113.   end COSH ;
  1114.  
  1115.  
  1116.  
  1117. -- TANH
  1118. -- Declaration:
  1119. --   function TANH (X : FLOAT_TYPE) return FLOAT_TYPE;
  1120. -- Definition:
  1121. --   TANH(X) ~ hyperbolic tangent of X
  1122. -- Usage:
  1123. --   Z := TANH(X);
  1124. -- Domain:
  1125. --   Mathematically unbounded
  1126. -- Range:
  1127. --   |TANH(X)| <= 1.0
  1128. -- Accuracy:
  1129. --   (a) Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1130. --   (b) TANH(0.0) = 0.0
  1131.  
  1132.   function TANH ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  1133.     EXP_2X : FLOAT_TYPE ;
  1134.   begin
  1135.     if X < HALF_LOG_EPSILON then
  1136.       return - 1.0 ;
  1137.     elsif X > - HALF_LOG_EPSILON then
  1138.       return 1.0 ;
  1139.     elsif X = 0.0 then
  1140.       return 0.0 ;
  1141.     elsif abs X < SQUARE_ROOT_EPSILON then
  1142.       return X ;
  1143.     end if ;
  1144.     EXP_2X := EXP ( - 2.0 * X ) ;
  1145.     return ( 1.0 - EXP_2X ) / ( 1.0 + EXP_2X ) ;
  1146.   end TANH ;
  1147.  
  1148.  
  1149.  
  1150. -- COTH
  1151. -- Declaration:
  1152. --   function COTH (X : FLOAT_TYPE) return FLOAT_TYPE;
  1153. -- Definition:
  1154. --   COTH(X) ~ hyperbolic cotangent of X
  1155. -- Usage:
  1156. --   Z := COTH(X);
  1157. -- Domain:
  1158. --   X /= 0.0
  1159. -- Range:
  1160. --   |COTH(X)| >= 1.0
  1161. -- Accuracy:
  1162. --   Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1163.  
  1164.   function COTH ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  1165.     EXP_2X : FLOAT_TYPE ;
  1166.   begin
  1167.     if X < HALF_LOG_EPSILON then
  1168.       return - 1.0 ;
  1169.     elsif X > - HALF_LOG_EPSILON then
  1170.       return 1.0 ;
  1171.     elsif X = 0.0 then
  1172.       raise ARGUMENT_ERROR ;
  1173.     elsif abs X < SQUARE_ROOT_EPSILON then
  1174.       return 1.0 / X ;
  1175.     end if ;
  1176.     EXP_2X := EXP ( - 2.0 * X ) ;
  1177.     return ( 1.0 + EXP_2X ) / ( 1.0 - EXP_2X ) ;
  1178.   end COTH ;
  1179.  
  1180.  
  1181.  
  1182. -- ARCSINH
  1183. -- Declaration:
  1184. --   function ARCSINH (X : FLOAT_TYPE) return FLOAT_TYPE;
  1185. -- Definition:
  1186. --   ARCSINH(X) ~ hyperbolic arcsine of X
  1187. -- Usage:
  1188. --   Z := ARCSINH(X);
  1189. -- Domain:
  1190. --   Mathematically unbounded
  1191. -- Range:
  1192. --   Mathematically unbounded
  1193. -- Accuracy:
  1194. --   (a) Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1195. --   (b) ARCSINH(0.0) = 0.0
  1196. -- Notes:
  1197. --   The reachable range of ARCSINH is approximately given by
  1198. --     |ARCSINH(X)| <= ln(FLOAT_TYPE'SAFE_LARGE)+ln(2.0)
  1199. --   Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1200.  
  1201.   function ARCSINH ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  1202.   begin
  1203.     if abs X < SQUARE_ROOT_EPSILON then
  1204.       return X ;
  1205.     elsif X > 1.0 / SQUARE_ROOT_EPSILON then
  1206.       return LOG ( X ) + LOG_TWO ;
  1207.     elsif X < - 1.0 / SQUARE_ROOT_EPSILON then
  1208.       return - ( LOG ( - X ) + LOG_TWO ) ;
  1209.     elsif X < 0.0 then
  1210.       return -LOG ( abs X + SQRT( X * X + 1.0 )) ;
  1211.     else
  1212.       return LOG ( X + SQRT( X * X + 1.0 )) ;
  1213.     end if ;
  1214.   end ARCSINH ;
  1215.  
  1216.  
  1217. -- ARCCOSH
  1218. -- Declaration:
  1219. --   function ARCCOSH (X : FLOAT_TYPE) return FLOAT_TYPE;
  1220. -- Definition:
  1221. --   ARCCOSH(X) ~ hyperbolic arccosine of X
  1222. -- Usage:
  1223. --   Z := ARCCOSH(X);
  1224. -- Domain:
  1225. --   X >= 1.0
  1226. -- Range:
  1227. --   ARCCOSH(X) >= 0.0
  1228. -- Accuracy:
  1229. --   (a) Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1230. --   (b) ARCCOSH(1.0) = 0.0
  1231. -- Notes:
  1232. --   The upper bound of the reachable range of ARCCOSH is approximately given
  1233. --   by  ARCCOSH(X) <= ln(FLOAT_TYPE'SAFE_LARGE)+ln(2.0)
  1234. --   Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1235.  
  1236.   function ARCCOSH ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  1237.   begin
  1238.   --    return LOG ( X - SQRT( X * X - 1.0 )) ;  double valued,
  1239.   --                                             only positive value returned
  1240.     if X < 1.0 then
  1241.       raise ARGUMENT_ERROR ;
  1242.     elsif X < 1.0 + SQUARE_ROOT_EPSILON then
  1243.       return X - 1.0 ;
  1244.     elsif abs X > 1.0 / SQUARE_ROOT_EPSILON then
  1245.       return LOG ( X ) + LOG_TWO ;
  1246.     else
  1247.       return LOG ( X + SQRT( X * X - 1.0 )) ;
  1248.     end if ;
  1249.   end ARCCOSH ;
  1250.  
  1251.  
  1252.  
  1253. -- ARCTANH
  1254. -- Declaration:
  1255. --   function ARCTANH (X : FLOAT_TYPE) return FLOAT_TYPE;
  1256. -- Definition:
  1257. --   ARCTANH(X) ~ hyperbolic arctangent of X
  1258. -- Usage:
  1259. --   Z := ARCTANH(X);
  1260. -- Domain:
  1261. --   |X| < 1.0
  1262. -- Range:
  1263. --   Mathematically unbounded
  1264. -- Accuracy:
  1265. --   (a) Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1266. --   (b) ARCTANH(0.0) = 0.0
  1267.  
  1268.   function ARCTANH ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  1269.   begin
  1270.     if abs X >= 1.0 then
  1271.       raise ARGUMENT_ERROR ;
  1272.     elsif abs X < EPSILON then
  1273.       return X ;
  1274.     else
  1275.       return 0.5 * LOG (( 1.0 + X ) / ( 1.0 - X )) ;
  1276.     end if ;
  1277.   end ARCTANH ;
  1278.  
  1279.  
  1280. -- ARCCOTH
  1281. -- Declaration:
  1282. --   function ARCCOTH (X : FLOAT_TYPE) return FLOAT_TYPE;
  1283. -- Definition:
  1284. --   ARCCOTH(X) ~ hyperbolic arc cotangent X
  1285. -- Usage:
  1286. --   Z := ARCCOTH(X);
  1287. -- Domain:
  1288. --   |X| > 1.0
  1289. -- Range:
  1290. --   Mathematically unbounded
  1291. -- Accuracy:
  1292. --   Maximum relative error = 8.0 * FLOAT_TYPE'BASE'EPSILON
  1293.  
  1294.   function ARCCOTH ( X : FLOAT_TYPE ) return FLOAT_TYPE is
  1295.   begin
  1296.     if abs X <= 1.0 then
  1297.       raise ARGUMENT_ERROR ;
  1298.     elsif abs X > 1.0 / EPSILON then
  1299.       return 0.0 ;
  1300.     else
  1301.       return 0.5 * LOG (( 1.0 + X ) / ( X - 1.0 )) ;
  1302.     end if ;
  1303.   end ARCCOTH ;
  1304.  
  1305. begin -- pseudo constants computed during elaboration
  1306.   EPSILON := FLOAT_TYPE ( FLOAT_TYPE'MACHINE_RADIX ) ** ( - FLOAT_TYPE'
  1307.     MACHINE_MANTISSA ) ;
  1308.   PREVIOUS := EPSILON ;
  1309.   while EPSILON + 1.0 /= 1.0 loop
  1310.     PREVIOUS := EPSILON ;
  1311.     EPSILON := EPSILON / FLOAT_TYPE ( FLOAT_TYPE'MACHINE_RADIX ) ;
  1312.   end loop ;
  1313.   EPSILON := PREVIOUS ;
  1314.   SQUARE_ROOT_EPSILON := SQRT ( EPSILON ) ;
  1315.   LOG_INVERSE_EPSILON := LOG ( 1.0 / EPSILON ) ;
  1316.   LOG_LAST := LOG ( FLOAT_TYPE'LAST ) ;
  1317.   HALF_LOG_EPSILON := 0.5 * LOG ( EPSILON ) ;
  1318. end GENERIC_ELEMENTARY_FUNCTIONS ;
  1319.