2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / testsuite / ada / acats / tests / cxg / cxg2002.a
blob6a1f322e8bf3c3b8905f4b3d40d8f1d2abfefda8
1 -- CXG2002.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.
16 -- DISCLAIMER
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 --*
26 -- OBJECTIVE:
27 -- Check that the complex "abs" or modulus function returns
28 -- results that are within the error bound allowed.
30 -- TEST DESCRIPTION:
31 -- This test uses a generic package to compute and check the
32 -- values of the modulus function. In addition, a non-generic
33 -- copy of this package is used to check the non-generic package
34 -- Ada.Numerics.Complex_Types.
35 -- Of special interest is the case where either the real or
36 -- the imaginary part of the argument is very large while the
37 -- other part is very small or 0.
38 -- We want to check that the value is computed such that
39 -- an overflow does not occur. If computed directly from the
40 -- definition
41 -- abs (x+yi) = sqrt(x**2 + y**2)
42 -- then overflow or underflow is much more likely than if the
43 -- argument is normalized first.
45 -- SPECIAL REQUIREMENTS
46 -- The Strict Mode for the numerical accuracy must be
47 -- selected. The method by which this mode is selected
48 -- is implementation dependent.
50 -- APPLICABILITY CRITERIA:
51 -- This test applies only to implementations supporting the
52 -- Numerics Annex.
53 -- This test only applies to the Strict Mode for numerical
54 -- accuracy.
57 -- CHANGE HISTORY:
58 -- 31 JAN 96 SAIC Initial release for 2.1
59 -- 02 JUN 98 EDS Add parens to intermediate calculations.
60 --!
63 -- Reference:
64 -- Problems and Methodologies in Mathematical Software Production;
65 -- editors: P. C. Messina and A Murli;
66 -- Lecture Notes in Computer Science
67 -- Volume 142
68 -- Springer Verlag 1982
71 with System;
72 with Report;
73 with Ada.Numerics.Generic_Complex_Types;
74 with Ada.Numerics.Complex_Types;
75 procedure CXG2002 is
76 Verbose : constant Boolean := False;
77 Maximum_Relative_Error : constant := 3.0;
79 generic
80 type Real is digits <>;
81 package Generic_Check is
82 procedure Do_Test;
83 end Generic_Check;
85 package body Generic_Check is
86 package Complex_Types is new
87 Ada.Numerics.Generic_Complex_Types (Real);
88 use Complex_Types;
90 procedure Check (Actual, Expected : Real;
91 Test_Name : String;
92 MRE : Real := Maximum_Relative_Error) is
93 Rel_Error,
94 Abs_Error,
95 Max_Error : Real;
96 begin
97 -- In the case where the expected result is very small or 0
98 -- we compute the maximum error as a multiple of Model_Epsilon instead
99 -- of Model_Epsilon and Expected.
100 Rel_Error := MRE * (abs Expected * Real'Model_Epsilon);
101 Abs_Error := MRE * Real'Model_Epsilon;
102 if Rel_Error > Abs_Error then
103 Max_Error := Rel_Error;
104 else
105 Max_Error := Abs_Error;
106 end if;
108 if abs (Actual - Expected) > Max_Error then
109 Report.Failed (Test_Name &
110 " actual: " & Real'Image (Actual) &
111 " expected: " & Real'Image (Expected) &
112 " difference: " &
113 Real'Image (Expected - Actual) &
114 " max_err:" & Real'Image (Max_Error) );
115 elsif Verbose then
116 if Actual = Expected then
117 Report.Comment (Test_Name & " exact result");
118 else
119 Report.Comment (Test_Name & " passed");
120 end if;
121 end if;
122 end Check;
125 procedure Do_Test is
126 Z : Complex;
127 X : Real;
128 T : Real;
129 begin
131 --- test 1 ---
132 begin
133 T := Real'Safe_Last;
134 Z := T + 0.0*i;
135 X := abs Z;
136 Check (X, T, "test 1 -- abs(bigreal + 0i)");
137 exception
138 when Constraint_Error =>
139 Report.Failed ("Constraint_Error raised in test 1");
140 when others =>
141 Report.Failed ("exception in test 1");
142 end;
144 --- test 2 ---
145 begin
146 T := Real'Safe_Last;
147 Z := 0.0 + T*i;
148 X := Modulus (Z);
149 Check (X, T, "test 2 -- abs(0 + bigreal*i)");
150 exception
151 when Constraint_Error =>
152 Report.Failed ("Constraint_Error raised in test 2");
153 when others =>
154 Report.Failed ("exception in test 2");
155 end;
157 --- test 3 ---
158 begin
159 Z := 3.0 + 4.0*i;
160 X := abs Z;
161 Check (X, 5.0 , "test 3 -- abs(3 + 4*i)");
162 exception
163 when Constraint_Error =>
164 Report.Failed ("Constraint_Error raised in test 3");
165 when others =>
166 Report.Failed ("exception in test 3");
167 end;
169 --- test 4 ---
170 declare
171 S : Real;
172 begin
173 S := Real(Real'Machine_Radix) ** (Real'Machine_EMax - 3);
174 Z := 3.0 * S + 4.0*S*i;
175 X := abs Z;
176 Check (X, 5.0*S, "test 4 -- abs(3S + 4S*i) for large S",
177 5.0*Real'Model_Epsilon);
178 exception
179 when Constraint_Error =>
180 Report.Failed ("Constraint_Error raised in test 4");
181 when others =>
182 Report.Failed ("exception in test 4");
183 end;
185 --- test 5 ---
186 begin
187 T := Real'Model_Small;
188 Z := T + 0.0*i;
189 X := abs Z;
190 Check (X, T , "test 5 -- abs(small + 0*i)");
191 exception
192 when Constraint_Error =>
193 Report.Failed ("Constraint_Error raised in test 5");
194 when others =>
195 Report.Failed ("exception in test 5");
196 end;
198 --- test 6 ---
199 begin
200 T := Real'Model_Small;
201 Z := 0.0 + T*i;
202 X := abs Z;
203 Check (X, T , "test 6 -- abs(0 + small*i)");
204 exception
205 when Constraint_Error =>
206 Report.Failed ("Constraint_Error raised in test 6");
207 when others =>
208 Report.Failed ("exception in test 6");
209 end;
211 --- test 7 ---
212 declare
213 S : Real;
214 begin
215 S := Real(Real'Machine_Radix) ** (Real'Model_EMin + 3);
216 Z := 3.0 * S + 4.0*S*i;
217 X := abs Z;
218 Check (X, 5.0*S, "test 7 -- abs(3S + 4S*i) for small S",
219 5.0*Real'Model_Epsilon);
220 exception
221 when Constraint_Error =>
222 Report.Failed ("Constraint_Error raised in test 7");
223 when others =>
224 Report.Failed ("exception in test 7");
225 end;
227 --- test 8 ---
228 declare
229 -- CRC Standard Mathematical Tables; 23rd Edition; pg 738
230 Sqrt2 : constant :=
231 1.41421_35623_73095_04880_16887_24209_69807_85696_71875_37695;
232 begin
233 Z := 1.0 + 1.0*i;
234 X := abs Z;
235 Check (X, Sqrt2 , "test 8 -- abs(1 + 1*i)");
236 exception
237 when Constraint_Error =>
238 Report.Failed ("Constraint_Error raised in test 8");
239 when others =>
240 Report.Failed ("exception in test 8");
241 end;
243 --- test 9 ---
244 begin
245 T := 0.0;
246 Z := T + 0.0*i;
247 X := abs Z;
248 Check (X, T , "test 5 -- abs(0 + 0*i)");
249 exception
250 when Constraint_Error =>
251 Report.Failed ("Constraint_Error raised in test 9");
252 when others =>
253 Report.Failed ("exception in test 9");
254 end;
255 end Do_Test;
256 end Generic_Check;
258 -----------------------------------------------------------------------
259 --- non generic copy of the above generic package
260 -----------------------------------------------------------------------
262 package Non_Generic_Check is
263 subtype Real is Float;
264 procedure Do_Test;
265 end Non_Generic_Check;
267 package body Non_Generic_Check is
268 use Ada.Numerics.Complex_Types;
270 procedure Check (Actual, Expected : Real;
271 Test_Name : String;
272 MRE : Real := Maximum_Relative_Error) is
273 Rel_Error,
274 Abs_Error,
275 Max_Error : Real;
276 begin
277 -- In the case where the expected result is very small or 0
278 -- we compute the maximum error as a multiple of Model_Epsilon instead
279 -- of Model_Epsilon and Expected.
280 Rel_Error := MRE * (abs Expected * Real'Model_Epsilon);
281 Abs_Error := MRE * Real'Model_Epsilon;
282 if Rel_Error > Abs_Error then
283 Max_Error := Rel_Error;
284 else
285 Max_Error := Abs_Error;
286 end if;
288 if abs (Actual - Expected) > Max_Error then
289 Report.Failed (Test_Name &
290 " actual: " & Real'Image (Actual) &
291 " expected: " & Real'Image (Expected) &
292 " difference: " &
293 Real'Image (Expected - Actual) &
294 " max_err:" & Real'Image (Max_Error) );
295 elsif Verbose then
296 if Actual = Expected then
297 Report.Comment (Test_Name & " exact result");
298 else
299 Report.Comment (Test_Name & " passed");
300 end if;
301 end if;
302 end Check;
305 procedure Do_Test is
306 Z : Complex;
307 X : Real;
308 T : Real;
309 begin
311 --- test 1 ---
312 begin
313 T := Real'Safe_Last;
314 Z := T + 0.0*i;
315 X := abs Z;
316 Check (X, T, "test 1 -- abs(bigreal + 0i)");
317 exception
318 when Constraint_Error =>
319 Report.Failed ("Constraint_Error raised in test 1");
320 when others =>
321 Report.Failed ("exception in test 1");
322 end;
324 --- test 2 ---
325 begin
326 T := Real'Safe_Last;
327 Z := 0.0 + T*i;
328 X := Modulus (Z);
329 Check (X, T, "test 2 -- abs(0 + bigreal*i)");
330 exception
331 when Constraint_Error =>
332 Report.Failed ("Constraint_Error raised in test 2");
333 when others =>
334 Report.Failed ("exception in test 2");
335 end;
337 --- test 3 ---
338 begin
339 Z := 3.0 + 4.0*i;
340 X := abs Z;
341 Check (X, 5.0 , "test 3 -- abs(3 + 4*i)");
342 exception
343 when Constraint_Error =>
344 Report.Failed ("Constraint_Error raised in test 3");
345 when others =>
346 Report.Failed ("exception in test 3");
347 end;
349 --- test 4 ---
350 declare
351 S : Real;
352 begin
353 S := Real(Real'Machine_Radix) ** (Real'Machine_EMax - 3);
354 Z := 3.0 * S + 4.0*S*i;
355 X := abs Z;
356 Check (X, 5.0*S, "test 4 -- abs(3S + 4S*i) for large S",
357 5.0*Real'Model_Epsilon);
358 exception
359 when Constraint_Error =>
360 Report.Failed ("Constraint_Error raised in test 4");
361 when others =>
362 Report.Failed ("exception in test 4");
363 end;
365 --- test 5 ---
366 begin
367 T := Real'Model_Small;
368 Z := T + 0.0*i;
369 X := abs Z;
370 Check (X, T , "test 5 -- abs(small + 0*i)");
371 exception
372 when Constraint_Error =>
373 Report.Failed ("Constraint_Error raised in test 5");
374 when others =>
375 Report.Failed ("exception in test 5");
376 end;
378 --- test 6 ---
379 begin
380 T := Real'Model_Small;
381 Z := 0.0 + T*i;
382 X := abs Z;
383 Check (X, T , "test 6 -- abs(0 + small*i)");
384 exception
385 when Constraint_Error =>
386 Report.Failed ("Constraint_Error raised in test 6");
387 when others =>
388 Report.Failed ("exception in test 6");
389 end;
391 --- test 7 ---
392 declare
393 S : Real;
394 begin
395 S := Real(Real'Machine_Radix) ** (Real'Model_EMin + 3);
396 Z := 3.0 * S + 4.0*S*i;
397 X := abs Z;
398 Check (X, 5.0*S, "test 7 -- abs(3S + 4S*i) for small S",
399 5.0*Real'Model_Epsilon);
400 exception
401 when Constraint_Error =>
402 Report.Failed ("Constraint_Error raised in test 7");
403 when others =>
404 Report.Failed ("exception in test 7");
405 end;
407 --- test 8 ---
408 declare
409 -- CRC Standard Mathematical Tables; 23rd Edition; pg 738
410 Sqrt2 : constant :=
411 1.41421_35623_73095_04880_16887_24209_69807_85696_71875_37695;
412 begin
413 Z := 1.0 + 1.0*i;
414 X := abs Z;
415 Check (X, Sqrt2 , "test 8 -- abs(1 + 1*i)");
416 exception
417 when Constraint_Error =>
418 Report.Failed ("Constraint_Error raised in test 8");
419 when others =>
420 Report.Failed ("exception in test 8");
421 end;
423 --- test 9 ---
424 begin
425 T := 0.0;
426 Z := T + 0.0*i;
427 X := abs Z;
428 Check (X, T , "test 5 -- abs(0 + 0*i)");
429 exception
430 when Constraint_Error =>
431 Report.Failed ("Constraint_Error raised in test 9");
432 when others =>
433 Report.Failed ("exception in test 9");
434 end;
435 end Do_Test;
436 end Non_Generic_Check;
438 -----------------------------------------------------------------------
439 --- end of "manual instantiation"
440 -----------------------------------------------------------------------
441 package Chk_Float is new Generic_Check (Float);
443 -- check the floating point type with the most digits
444 type A_Long_Float is digits System.Max_Digits;
445 package Chk_A_Long_Float is new Generic_Check (A_Long_Float);
446 begin
447 Report.Test ("CXG2002",
448 "Check the accuracy of the complex modulus" &
449 " function");
451 if Verbose then
452 Report.Comment ("checking Standard.Float");
453 end if;
454 Chk_Float.Do_Test;
456 if Verbose then
457 Report.Comment ("checking a digits" &
458 Integer'Image (System.Max_Digits) &
459 " floating point type");
460 end if;
461 Chk_A_Long_Float.Do_Test;
463 if Verbose then
464 Report.Comment ("checking non-generic package");
465 end if;
466 Non_Generic_Check.Do_Test;
467 Report.Result;
468 end CXG2002;