-- compare float and long_float versions COMPLEX_ELEMENTARY_FUNCTIONS -- development test used to develope GENERIC_COMPLEX_ELEMENTARY_FUNCTIONS -- check range and accuracy with respect to signs with long_complex_types; -- for test with long_complex_elementary_functions; -- for test with complex_types; use complex_types; with complex_arrays; use complex_arrays; with complex_elementary_functions; with text_io; use text_io; with complex_arrays_io; with complex_io; procedure test_complex_elementary_functions is package cf renames complex_elementary_functions; package lcf renames long_complex_elementary_functions; subtype long_complex is long_complex_types.complex; package real_io is new float_io(float); use real_io; package cx_io is new complex_io(float, complex); use cx_io; function "-"(a,b:long_complex) return long_complex renames long_complex_types."-"; function modulus(a:long_complex) return long_float renames long_complex_types.modulus; function re(a:long_complex) return long_float renames long_complex_types.re; function im(a:long_complex) return long_float renames long_complex_types.im; function compose_from_cartesian(a,b:long_float) return long_complex renames long_complex_types.compose_from_cartesian; package long_cx_io is new complex_io(long_float, long_complex); use long_cx_io; argument_error : exception renames complex_elementary_functions.argument_error; PI : constant := 3.14159_26535_89793_23846_26433_83279_50288_41971 ; Pi_2 : constant := Pi / 2.0; two_Pi : constant := 2.0 * Pi; eps1 : float := (1.0+float'epsilon); eps2 : long_float := (1.0+long_float'epsilon); K : array(integer(-44)..44) of float; P : COMPLEX_VECTOR ( 1..k'length*k'length); P2 : COMPLEX_VECTOR ( 0..48); ii : integer; complex_zero : complex := (0.0,0.0); complex_one : complex := (1.0,0.0); complex_i : complex := (0.0,1.0); maxerr : float:= 0.0; perr : complex := (0.0,0.0); myval : complex := (0.0,0.0); longt : long_complex := (0.0,0.0); base : complex := (0.0,0.0); long : long_complex := (0.0,0.0); lgen : long_complex := (0.0,0.0); excp : integer := 0; excl : integer := 0; errc : integer := 0; z : complex; z2 : complex; function lengthen(z:complex) return long_complex is begin return compose_from_cartesian(long_float(RE(z)), long_float(IM(z))); end lengthen; function shorten(z:long_complex) return complex is begin return compose_from_cartesian(float(RE(z)), float(IM(z))); end shorten; procedure track(point: complex; gcef_value: complex; longt_value: long_complex; lgen_value: long_complex; print_all: boolean := false) is error : float; errorg : long_float; begin if modulus(gcef_value) /= 0.0 then error := float(modulus (longt_value - lengthen(gcef_value))/ modulus(lengthen(gcef_value))); errorg := modulus(longt_value - lgen_value) / modulus(lgen_value); else error := float(modulus (longt_value - lengthen(gcef_value))); errorg := modulus(longt_value - lgen_value); end if; if error > maxerr then maxerr := error; perr := point; myval := gcef_value; longt := longt_value; end if; if error > 0.1 then errc := errc + 1; if print_all and errc < 25 then put("Track at z= "); put(point); put(" base= "); put(gcef_value); new_line; put(" long= "); put(longt_value); put(", err= "); put(error); new_line; end if; end if; if errorg > 2.0 * long_float'epsilon and errc < 4 then put("Generic /= Long at z= "); put(point); put(", err= "); put(float(errorg)); new_line; errc := errc + 1; end if; end track; procedure print_track is begin put(" exception count "); put(integer'image(excp)); put(" excluded count "); put(integer'image(excl)); put(" error count "); put(integer'image(errc)); new_line; put(" maxerr "); put(maxerr,aft=>3); new_line; put(" z at maxerr"); put(perr); new_line; put(" base "); put(myval); new_line; put(" long "); put(longt); new_line; new_line; maxerr := 0.0; excp := 0; excl := 0; errc := 0; perr := (0.0,0.0); myval := (0.0,0.0); longt := (0.0,0.0); end print_track; begin -- The values below are used positive and negative in all combinations -- real and imaginary parts k(0) := 0.0; k(1) := 0.0000001; k(2) := 0.000001; k(3) := 0.00001; k(4) := 0.001; k(5) := 0.01; k(6) := 0.02; k(7) := 0.06; k(8) := 0.1; k(9) := 0.2; k(10) := 0.25; k(11) := 0.35; k(12) := 0.5; k(13) := 0.7071; k(14) := 0.785; k(15) := 0.786; k(16) := 0.97; k(17) := 0.999; k(18) := 1.0; k(19) := 1.001; k(20) := 1.1; k(21) := 1.01; k(22) := 1.25; k(23) := 1.35; k(24) := 1.41421; k(25) := 1.5; k(26) := 1.54; k(27) := 1.57079; k(28) := 1.63; k(29) := 2.0; k(30) := 2.2; k(31) := 2.4; k(32) := 2.71828; k(33) := 3.0; k(34) := 3.141; k(35) := 3.142; k(36) := 8.0; k(37) := 12.0; k(38) := 16.0; k(39) := 20.0; k(40) := 30.0; k(41) := 64.0; k(42) := 500.0; k(43) := 1000.0; k(44) := 2500.0; for i in 1..k'last loop k(-i) := -k(i); end loop; ii := p'first; for i in k'range loop for j in k'range loop P(ii) := compose_from_cartesian(k(i),k(j)); ii := ii+1; end loop; end loop; p2(0) := (-2.5,-2.5); p2(1) := (-2.0,-2.5); p2(2) := (-1.0,-2.5); p2(3) := (0.0,-2.5); p2(4) := (1.0,-2.5); p2(5) := (2.0,-2.5); p2(6) := (2.5,-2.5); for i in 7..48 loop p2(i) := p2(i mod 7); set_im(p2(i),re(p2(i/7))); end loop; put_line("test complex elementary functions"); put_line("test sqrt"); for i in p'range loop begin z := p(i); base:=cf.sqrt(z); if re(base) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (im(z)<0.0 and im(base)>0.0) or (im(z)>0.0 and im(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long:=lcf.sqrt(lengthen(z)); if re(long) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (im(z)<0.0 and im(long)>0.0) or (im(z)>0.0 and im(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen:=lcf.sqrt(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test log"); for i in p'range loop begin z := p(i); base := cf.log(z); if im(base) < -(Pi*eps1) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif im(base) > Pi*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (im(z)<0.0 and im(base)>0.0) or (im(z)>0.0 and im(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.log(lengthen(z)); if im(long) < -(Pi*eps2) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif im(long) > Pi*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (im(z)<0.0 and im(long)>0.0) or (im(z)>0.0 and im(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.log(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test exp, complex"); for i in p'range loop begin z := p(i); base := cf.exp(z); long := lcf.exp(lengthen(z)); lgen := lcf.exp(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test exp, imaginary"); for i in 1..k'length loop begin z := p(i); base := cf.exp(complex_types.i*re(z)); long := lcf.exp(compose_from_cartesian(0.0,re(lengthen(z)))); lgen := lcf.exp(compose_from_cartesian(0.0,re(lengthen(z)))); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test **, complex**complex, this takes a while"); for i in p'range loop for j in p2'range loop begin z := p(i); z2 := p2(j); base := cf."**"(z,z2); long := lcf."**"(lengthen(z),lengthen(z2)); lgen := lcf."**"(lengthen(z),lengthen(z2)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; end loop; print_track; put_line("test **, complex**real, this takes a while"); for i in p'range loop for j in 0..6 loop begin z := p(i); z2 := p2(j); base := cf."**"(z,re(z2)); long := lcf."**"(lengthen(z),re(lengthen(z2))); lgen := lcf."**"(lengthen(z),re(lengthen(z2))); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; end loop; print_track; put_line("test **, real**complex, this takes a while"); for i in 1..k'length loop for j in p2'range loop begin z := p(i); z2 := p2(j); base := cf."**"(re(z),z2); long := lcf."**"(re(lengthen(z)),lengthen(z2)); lgen := lcf."**"(re(lengthen(z)),lengthen(z2)); track(z,base,long,lgen,true); exception when others => excp := excp + 1; end; end loop; end loop; print_track; put_line("test sin"); for i in p'range loop begin z := p(i); base := cf.sin(z); long := lcf.sin(lengthen(z)); lgen := lcf.sin(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test cos"); for i in p'range loop begin z := p(i); base := cf.cos(z); long := lcf.cos(lengthen(z)); lgen := lcf.cos(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test tan"); for i in p'range loop begin z := p(i); base := cf.tan(z); long := lcf.tan(lengthen(z)); lgen := lcf.tan(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test cot"); for i in p'range loop begin z := p(i); base := cf.cot(z); long := lcf.cot(lengthen(z)); lgen := lcf.cot(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test arcsin"); for i in p'range loop begin z := p(i); base := cf.arcsin(z); if re(base) < -(Pi_2*eps1) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif re(base) > Pi_2*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (im(z)<0.0 and im(base)>0.0) or (im(z)>0.0 and im(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (re(z)<0.0 and re(base)>0.0) or (re(z)>0.0 and re(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.arcsin(lengthen(z)); if re(long) < -(Pi_2*eps2) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif re(long) > Pi_2*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (im(z)<0.0 and im(long)>0.0) or (im(z)>0.0 and im(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (re(z)<0.0 and re(long)>0.0) or (re(z)>0.0 and re(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.arcsin(lengthen(z)); track(z,base,long,lgen,true); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test arccos"); for i in p'range loop begin z := p(i); base := cf.arccos(z); if re(base) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif re(base) > Pi*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (im(z)<0.0 and im(base)<0.0) or (im(z)>0.0 and im(base)>0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.arccos(lengthen(z)); if re(long) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif re(long) > Pi*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (im(z)<0.0 and im(long)<0.0) or (im(z)>0.0 and im(long)>0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.arccos(lengthen(z)); track(z,base,long,lgen,true); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test arctan"); for i in p'range loop begin z := p(i); base := cf.arctan(z); if re(base) < -(Pi_2*eps1) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif re(base) > Pi_2*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.arctan(lengthen(z)); if re(long) < -(Pi_2*eps2) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif re(long) > Pi_2*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.arctan(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test arccot"); for i in p'range loop begin z := p(i); base := cf.arccot(z); if re(base) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif re(base) > Pi*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.arccot(lengthen(z)); if re(long) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif re(long) > Pi*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.arccot(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test sinh"); for i in p'range loop begin z := p(i); base := cf.sinh(z); long := lcf.sinh(lengthen(z)); lgen := lcf.sinh(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test cosh"); for i in p'range loop begin z := p(i); base := cf.cosh(z); long := lcf.cosh(lengthen(z)); lgen := lcf.cosh(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test tanh"); for i in p'range loop begin z := p(i); base := cf.tanh(z); long := lcf.tanh(lengthen(z)); lgen := lcf.tanh(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test coth"); for i in p'range loop begin z := p(i); base := cf.coth(z); long := lcf.coth(lengthen(z)); lgen := lcf.coth(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test arcsinh"); for i in p'range loop begin z := p(i); base := cf.arcsinh(z); if im(base) < -(Pi_2*eps1) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif im(base) > Pi_2*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (im(z)<0.0 and im(base)>0.0) or (im(z)>0.0 and im(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (re(z)<0.0 and re(base)>0.0) or (re(z)>0.0 and re(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.arcsinh(lengthen(z)); if im(long) < -(Pi_2*eps2) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif im(long) > Pi_2*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (im(z)<0.0 and im(long)>0.0) or (im(z)>0.0 and im(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (re(z)<0.0 and re(long)>0.0) or (re(z)>0.0 and re(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.arcsinh(lengthen(z)); track(z,base,long,lgen,true); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test arccosh"); for i in p'range loop begin z := p(i); base := cf.arccosh(z); if im(base) < -(Pi*eps1) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif im(base) > Pi*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif re(base) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (im(z)<0.0 and im(base)>0.0) or (im(z)>0.0 and im(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.arccosh(lengthen(z)); if im(long) < -(Pi*eps2) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif im(long) > Pi*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif re(long) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (im(z)<0.0 and im(long)>0.0) or (im(z)>0.0 and im(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.arccosh(lengthen(z)); track(z,base,long,lgen,true); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test arctanh"); for i in p'range loop begin z := p(i); base := cf.arctanh(z); if im(base) < -(Pi_2*eps1) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif im(base) > Pi_2*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (im(z)<0.0 and im(base)>0.0) or (im(z)>0.0 and im(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (re(z)<0.0 and re(base)>0.0) or (re(z)>0.0 and re(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.arctanh(lengthen(z)); if im(long) < -(Pi_2*eps2) then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif im(long) > Pi_2*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (im(z)<0.0 and im(long)>0.0) or (im(z)>0.0 and im(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (re(z)<0.0 and re(long)>0.0) or (re(z)>0.0 and re(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.arctanh(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("test arccoth"); for i in p'range loop begin z := p(i); base := cf.arccoth(z); if im(base) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif im(base) > Pi*eps1 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; elsif (re(z)<0.0 and re(base)>0.0) or (re(z)>0.0 and re(base)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(base); new_line; end if; long := lcf.arccoth(lengthen(z)); if im(long) < 0.0 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif im(long) > Pi*eps2 then put("Range violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; elsif (re(z)<0.0 and re(long)>0.0) or (re(z)>0.0 and re(long)<0.0) then put("Accuracy violation error at z= "); put(z); new_line; put(" at "); put(long); new_line; end if; lgen := lcf.arccoth(lengthen(z)); track(z,base,long,lgen); exception when others => excp := excp + 1; end; end loop; print_track; put_line("Some operands that were used for testing are as follows:"); for i in 1..48 loop put(p(i)); put(p2(i)); new_line; end loop; new_line; put_line("end test complex elementary functions"); exception when others => put_line("abnormal exception, end test complex elementary functions"); end test_complex_elementary_functions;