1-- CXA5A04.A
2--
3--                             Grant of Unlimited Rights
4--
5--     Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
6--     F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
7--     unlimited rights in the software and documentation contained herein.
8--     Unlimited rights are defined in DFAR 252.227-7013(a)(19).  By making
9--     this public release, the Government intends to confer upon all
10--     recipients unlimited rights  equal to those held by the Government.
11--     These rights include rights to use, duplicate, release or disclose the
12--     released technical data and computer software in whole or in part, in
13--     any manner and for any purpose whatsoever, and to have or permit others
14--     to do so.
15--
16--                                    DISCLAIMER
17--
18--     ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
19--     DISCLOSED ARE AS IS.  THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
20--     WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
21--     SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
22--     OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
23--     PARTICULAR PURPOSE OF SAID MATERIAL.
24--*
25--
26-- OBJECTIVE:
27--      Check that the functions Cot, Coth, and Arccoth provide correct
28--      results.
29--
30-- TEST DESCRIPTION:
31--      This test examines both the version of Cot, Coth, and Arccoth
32--      the instantiation of the Ada.Numerics.Generic_Elementary_Functions
33--      with a type derived from type Float, as well as the preinstantiated
34--      version of this package for type Float.
35--      Prescribed results, including instances prescribed to raise
36--      exceptions, are examined in the test cases.  In addition,
37--      certain evaluations are performed where the actual function result
38--      is compared with the expected result (within an epsilon range of
39--      accuracy).
40--
41-- TEST FILES:
42--      The following files comprise this test:
43--
44--         FXA5A00.A   (foundation code)
45--         CXA5A04.A
46--
47--
48-- CHANGE HISTORY:
49--      15 Mar 95   SAIC    Initial prerelease version.
50--      07 Apr 95   SAIC    Corrected errors in context clause reference,
51--                          added trigonometric relationship checks.
52--      13 Jun 95   SAIC    Incorporated use of Dont_Optimize procedure, and
53--                          use of Result_Within_Range function overloaded for
54--                          FXA5A00.New_Float_Type.
55--      18 Apr 96   SAIC    Incorporated reviewer comments for ACVC 2.1.
56--      28 Feb 97   PWB.CTA Removed checks with explicit Cycle => 2.0*Pi
57--      29 Jun 98   EDS     Protected exception tests by first testing
58--                          for 'Machine_Overflows
59--
60-- CHANGE NOTE:
61--      According to Ken Dritz, author of the Numerics Annex of the RM,
62--      one should never specify the cycle 2.0*Pi for the trigonometric
63--      functions.  In particular, if the machine number for the first
64--      argument is not an exact multiple of the machine number for the
65--      explicit cycle, then the specified exact results cannot be
66--      reasonably expected.  The affected checks in this test have been
67--      marked as comments, with the additional notation "pwb-math".
68--      Phil Brashear
69--!
70
71with Ada.Exceptions;
72with Ada.Numerics.Elementary_Functions;
73with Ada.Numerics.Generic_Elementary_Functions;
74with FXA5A00;
75with Report;
76
77procedure CXA5A04 is
78begin
79
80   Report.Test ("CXA5A04", "Check that the functions Cot, Coth, and " &
81                           "Arccoth provide correct results");
82
83   Test_Block:
84   declare
85
86      use Ada.Exceptions;
87      use Ada.Numerics;
88      use FXA5A00;
89
90      package GEF is new Ada.Numerics.Generic_Elementary_Functions(New_Float);
91      package  EF renames Ada.Numerics.Elementary_Functions;
92
93      The_Result       : Float;
94      New_Float_Result : New_Float;
95
96      procedure Dont_Optimize_Float     is new Dont_Optimize(Float);
97      procedure Dont_Optimize_New_Float is new Dont_Optimize(New_Float);
98
99   begin
100
101      -- Testing of Cot Function, both instantiated and pre-instantiated
102      -- version.
103
104      -- Check that Constraint_Error is raised with the Cot function is
105      -- given a parameter input value of 0.0.
106
107      if New_Float'Machine_Overflows = True then
108         begin
109            New_Float_Result := GEF.Cot (0.0);
110            Report.Failed("Constraint_Error not raised by Function Cot " &
111                          "when provided a zero input parameter value");
112            Dont_Optimize_New_Float(New_Float_Result, 1);
113         exception
114            when Constraint_Error => null;  -- OK, expected exception.
115            when others           =>
116            Report.Failed("Unexpected exception raised by Function Cot " &
117                          "when provided a zero input parameter value");
118         end;
119      end if;
120
121      -- Check that no exception occurs on computing the Cot with very
122      -- large (positive and negative) input values.
123
124      begin
125         New_Float_Result := GEF.Cot (New_Float(FXA5A00.Large));
126         Dont_Optimize_New_Float(New_Float_Result, 2);
127      exception
128         when others =>
129           Report.Failed("Unexpected exception on GEF.Cot with large " &
130                         "positive value");
131      end;
132
133      begin
134         The_Result := EF.Cot (FXA5A00.Minus_Large);
135         Dont_Optimize_Float(The_Result, 3);
136      exception
137         when others =>
138           Report.Failed("Unexpected exception on EF.Cot with large " &
139                         "negative value");
140      end;
141
142
143      -- Check the results of the Cot function with various input parameters.
144
145      if not (FXA5A00.Result_Within_Range(GEF.Cot(Pi/4.0),     1.0, 0.001) and
146              FXA5A00.Result_Within_Range( EF.Cot(Pi/2.0),     0.0, 0.001) and
147              FXA5A00.Result_Within_Range(GEF.Cot(3.0*Pi/4.0),-1.0, 0.001) and
148              FXA5A00.Result_Within_Range( EF.Cot(3.0*Pi/2.0), 0.0, 0.001))
149      then
150         Report.Failed("Incorrect result from Cot function with various " &
151                       "input parameters");
152      end if;
153
154
155      -- Check the results of the Cot function against the results of
156      -- various trigonometric relationships.
157
158      if not FXA5A00.Result_Within_Range(GEF.Cot(New_Float(Pi/4.0)),
159                                         1.0/EF.Tan(Pi/4.0),
160                                         0.001)           or
161         not FXA5A00.Result_Within_Range(EF.Cot(Pi/4.0),
162                                         EF.Cos(Pi/4.0)/EF.Sin(Pi/4.0),
163                                         0.001) or
164         not FXA5A00.Result_Within_Range(EF.Cot(EF.Arccot(Pi/4.0)),
165                                         Pi/4.0,
166                                         0.001)
167      then
168         Report.Failed("Incorrect result from Cot function with respect " &
169                       "to various trigonometric relationship expected "  &
170                       "results");
171      end if;
172
173
174      -- Testing of Cot with Cycle parameter.
175
176      -- Check that Argument_Error is raised by the Cot function when the
177      -- value of the Cycle parameter is zero or negative.
178
179      begin
180         New_Float_Result := GEF.Cot (1.0, Cycle => 0.0);
181         Report.Failed("Argument_Error not raised by the Cot Function " &
182                       "with a specified cycle value of 0.0");
183         Dont_Optimize_New_Float(New_Float_Result, 4);
184      exception
185         when Argument_Error => null;  -- OK, expected exception.
186         when others         =>
187            Report.Failed
188              ("Unexpected exception raised by the Cot Function with " &
189               "a specified cycle value of 0.0");
190      end;
191
192      begin
193         The_Result := EF.Cot (X => 1.0, Cycle => -360.0);
194         Report.Failed("Argument_Error not raised by the Cot Function " &
195                       "with a specified cycle value of -360.0");
196         Dont_Optimize_Float(The_Result, 5);
197      exception
198         when Argument_Error => null;  -- OK, expected exception.
199         when others         =>
200            Report.Failed
201              ("Unexpected exception raised by the Cot Function with " &
202               "a specified cycle value of -360.0");
203      end;
204
205
206      -- Check that Constraint_Error is raised by the Cot Function with
207      -- specified cycle, when the value of the parameter X is 0.0.
208
209      if New_Float'Machine_Overflows = True then
210         begin
211            New_Float_Result := GEF.Cot (0.0, 360.0);
212            Report.Failed("Constraint_Error not raised by Function Cot "   &
213                          "with specified cycle, when value of parameter " &
214                          "X is 0.0");
215            Dont_Optimize_New_Float(New_Float_Result, 6);
216         exception
217            when Constraint_Error => null;  -- OK, expected exception.
218            when others           =>
219               Report.Failed("Unexpected exception raised by Function Cot "   &
220                             "with specified cycle, when value of parameter " &
221                             "X is 0.0");
222         end;
223      end if;
224
225      -- Check that Constraint_Error is raised by the Cot Function with
226      -- specified cycle, when the value of the parameter X is a multiple
227      -- of the half cycle.
228
229      if New_Float'Machine_Overflows = True then
230         begin
231            New_Float_Result := GEF.Cot (180.0, 360.0);
232            Report.Failed("Constraint_Error not raised by Function Cot "   &
233                          "with specified cycle, when value of parameter " &
234                          "X is a multiple of the half cycle (180.0, 360.0)");
235            Dont_Optimize_New_Float(New_Float_Result, 7);
236         exception
237            when Constraint_Error => null;  -- OK, expected exception.
238            when others           =>
239               Report.Failed("Unexpected exception raised by Function Cot "   &
240                             "with specified cycle, when value of parameter " &
241                             "X is a multiple of the half cycle" &
242                             " (180.0, 360.0)");
243         end;
244      end if;
245
246      if Float'Machine_Overflows = True then
247         begin
248            The_Result := EF.Cot (540.0, 360.0);
249            Report.Failed("Constraint_Error not raised by Function Cot "   &
250                          "with specified cycle, when value of parameter " &
251                          "X is a multiple of the half cycle (540.0, 360.0)");
252            Dont_Optimize_Float(The_Result, 8);
253         exception
254            when Constraint_Error => null;  -- OK, expected exception.
255            when others           =>
256               Report.Failed("Unexpected exception raised by Function Cot "   &
257                             "with specified cycle, when value of parameter " &
258                             "X is a multiple of the half cycle (540.0, 360.0)");
259         end;
260      end if;
261
262--pwb-math      -- Check that no exception occurs on computing the Cot with very
263--pwb-math      -- large (positive and negative) input values.
264--pwb-math
265--pwb-math      begin
266--pwb-math         New_Float_Result := GEF.Cot (New_Float(FXA5A00.Large), 2.0*Pi);
267--pwb-math         Dont_Optimize_New_Float(New_Float_Result, 9);
268--pwb-math      exception
269--pwb-math         when others =>
270--pwb-math           Report.Failed("Unexpected exception on GEF.Cot with large " &
271--pwb-math                         "positive value");
272--pwb-math      end;
273--pwb-math
274--pwb-math      begin
275--pwb-math         The_Result := EF.Cot (FXA5A00.Minus_Large, Cycle => 2.0*Pi);
276--pwb-math         Dont_Optimize_Float(The_Result, 10);
277--pwb-math      exception
278--pwb-math         when others =>
279--pwb-math           Report.Failed("Unexpected exception on EF.Cot with large " &
280--pwb-math                         "negative value");
281--pwb-math      end;
282--pwb-math
283--pwb-math
284--pwb-math      -- Check prescribed result from Cot function with Cycle parameter.
285--pwb-math
286--pwb-math      if not FXA5A00.Result_Within_Range
287--pwb-math               (GEF.Cot(New_Float(FXA5A00.Half_Pi), 2.0*Pi), 0.0, 0.001) or
288--pwb-math         not FXA5A00.Result_Within_Range
289--pwb-math               (EF.Cot(3.0*Pi/2.0, Cycle => 2.0*Pi), 0.0, 0.001)
290--pwb-math      then
291--pwb-math         Report.Failed("Incorrect result from Cot function with cycle " &
292--pwb-math                       "parameter, using a multiple of Pi/2 as the "    &
293--pwb-math                       "input parameter");
294--pwb-math      end if;
295
296
297      -- Testing of Coth Function, both instantiated and pre-instantiated
298      -- version.
299
300      -- Check that no exception occurs on computing the Coth with very
301      -- large (positive and negative) input values.
302
303      begin
304         The_Result := EF.Coth (FXA5A00.Large);
305         if The_Result > 1.0 then
306            Report.Failed("Result of Coth function with large positive " &
307                          "value greater than 1.0");
308         end if;
309      exception
310         when others =>
311           Report.Failed("Unexpected exception on EF.Coth with large " &
312                         "positive value");
313      end;
314
315      begin
316         The_Result := EF.Coth (FXA5A00.Minus_Large);
317         if The_Result < -1.0 then
318            Report.Failed("Result of Coth function with large negative " &
319                          "value less than -1.0");
320         end if;
321      exception
322         when others =>
323           Report.Failed("Unexpected exception on EF.Coth with large " &
324                         "negative value");
325      end;
326
327
328      -- Check that Constraint_Error is raised by the Coth function, when
329      -- the value of the parameter X is 0.0.
330
331      if New_Float'Machine_Overflows = True then
332         begin
333            New_Float_Result := GEF.Coth (X => 0.0);
334            Report.Failed("Constraint_Error not raised by the Coth function " &
335                          "when the value of parameter X is 0.0");
336            Dont_Optimize_New_Float(New_Float_Result, 11);
337         exception
338            when Constraint_Error => null;  -- OK, expected exception.
339            when others           =>
340               Report.Failed("Unexpected exception raised by the Coth " &
341                             "function when the value of parameter X is 0.0");
342         end;
343      end if;
344
345
346      -- Testing of Arccoth Function, both instantiated and pre-instantiated
347      -- version.
348
349      -- Check that Constraint_Error is raised by the Arccoth function
350      -- when the absolute value of the parameter X is 1.0.
351
352      if New_Float'Machine_Overflows = True then
353         begin
354            New_Float_Result := GEF.Arccoth (X => 1.0);
355            Report.Failed("Constraint_Error not raised by the Arccoth " &
356                          "function when the value of parameter X is 1.0");
357            Dont_Optimize_New_Float(New_Float_Result, 12);
358         exception
359            when Constraint_Error => null;  -- OK, expected exception.
360            when others           =>
361               Report.Failed("Unexpected exception raised by the Arccoth " &
362                             "function when the value of parameter X is 1.0");
363         end;
364      end if;
365
366      if Float'Machine_Overflows = True then
367         begin
368            The_Result := EF.Arccoth (-1.0);
369            Report.Failed("Constraint_Error not raised by the Arccoth " &
370                          "function when the value of parameter X is -1.0");
371            Dont_Optimize_Float(The_Result, 13);
372         exception
373            when Constraint_Error => null;  -- OK, expected exception.
374            when others           =>
375               Report.Failed("Unexpected exception raised by the Arccoth " &
376                             "function when the value of parameter X is -1.0");
377         end;
378      end if;
379
380      -- Check that Argument_Error is raised by the Arccoth function when
381      -- the absolute value of the parameter X is less than 1.0.
382
383      begin
384         New_Float_Result := GEF.Arccoth (X => New_Float(One_Minus_Delta));
385         Report.Failed("Argument_Error not raised by the Arccoth " &
386                       "function with parameter value less than 1.0");
387         Dont_Optimize_New_Float(New_Float_Result, 14);
388      exception
389         when Argument_Error => null;  -- OK, expected exception.
390         when others         =>
391            Report.Failed("Unexpected exception raised by the Arccoth " &
392                          "function with parameter value less than 1.0");
393      end;
394
395      begin
396         The_Result := EF.Arccoth (X => FXA5A00.Minus_One_Plus_Delta);
397         Report.Failed("Argument_Error not raised by the Arccoth function " &
398                       "with parameter value between 0.0 and -1.0");
399         Dont_Optimize_Float(The_Result, 15);
400      exception
401         when Argument_Error => null;  -- OK, expected exception.
402         when others         =>
403            Report.Failed("Unexpected exception raised by the Arccoth " &
404                          "function with parameter value between 0.0 "  &
405                          "and -1.0");
406      end;
407
408
409      -- Check the results of the Arccoth function with various input
410      -- parameters.
411
412      if not (Result_Within_Range(GEF.Arccoth(1.01), 2.652, 0.01)  and
413              Result_Within_Range( EF.Arccoth(1.25), 1.099, 0.01)  and
414              Result_Within_Range(GEF.Arccoth(1.56), 0.760, 0.001) and
415              Result_Within_Range( EF.Arccoth(1.97), 0.560, 0.001) and
416              Result_Within_Range(GEF.Arccoth(2.40), 0.444, 0.001) and
417              Result_Within_Range( EF.Arccoth(4.30), 0.237, 0.001) and
418              Result_Within_Range(GEF.Arccoth(5.80), 0.174, 0.001) and
419              Result_Within_Range( EF.Arccoth(7.00), 0.144, 0.001))
420      then
421         Report.Failed("Incorrect result from Arccoth function with various " &
422                       "input parameters");
423      end if;
424
425
426   exception
427      when The_Error : others =>
428         Report.Failed ("The following exception was raised in the " &
429                        "Test_Block: " & Exception_Name(The_Error));
430   end Test_Block;
431
432   Report.Result;
433
434end CXA5A04;
435