intervals 0.3.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. data/VERSION.txt +1 -0
  2. data/ext/crlibm/AUTHORS +2 -0
  3. data/ext/crlibm/COPYING +504 -0
  4. data/ext/crlibm/ChangeLog +80 -0
  5. data/ext/crlibm/INSTALL +182 -0
  6. data/ext/crlibm/Makefile.am +84 -0
  7. data/ext/crlibm/Makefile.in +530 -0
  8. data/ext/crlibm/NEWS +0 -0
  9. data/ext/crlibm/README +31 -0
  10. data/ext/crlibm/TODO +47 -0
  11. data/ext/crlibm/VERSION +1 -0
  12. data/ext/crlibm/aclocal.m4 +989 -0
  13. data/ext/crlibm/atan-itanium.c +846 -0
  14. data/ext/crlibm/atan-pentium.c +261 -0
  15. data/ext/crlibm/atan_accurate.c +244 -0
  16. data/ext/crlibm/atan_accurate.h +191 -0
  17. data/ext/crlibm/atan_fast.c +324 -0
  18. data/ext/crlibm/atan_fast.h +678 -0
  19. data/ext/crlibm/config.guess +1461 -0
  20. data/ext/crlibm/config.sub +1566 -0
  21. data/ext/crlibm/configure +7517 -0
  22. data/ext/crlibm/configure.ac +364 -0
  23. data/ext/crlibm/crlibm.h +125 -0
  24. data/ext/crlibm/crlibm_config.h +149 -0
  25. data/ext/crlibm/crlibm_config.h.in +148 -0
  26. data/ext/crlibm/crlibm_private.c +293 -0
  27. data/ext/crlibm/crlibm_private.h +658 -0
  28. data/ext/crlibm/csh_fast.c +631 -0
  29. data/ext/crlibm/csh_fast.h +771 -0
  30. data/ext/crlibm/double-extended.h +496 -0
  31. data/ext/crlibm/exp-td.c +962 -0
  32. data/ext/crlibm/exp-td.h +685 -0
  33. data/ext/crlibm/exp_accurate.c +197 -0
  34. data/ext/crlibm/exp_accurate.h +85 -0
  35. data/ext/crlibm/gappa/log-de-E0-logir0.gappa +106 -0
  36. data/ext/crlibm/gappa/log-de-E0.gappa +79 -0
  37. data/ext/crlibm/gappa/log-de.gappa +81 -0
  38. data/ext/crlibm/gappa/log-td-E0-logir0.gappa +126 -0
  39. data/ext/crlibm/gappa/log-td-E0.gappa +143 -0
  40. data/ext/crlibm/gappa/log-td-accurate-E0-logir0.gappa +230 -0
  41. data/ext/crlibm/gappa/log-td-accurate-E0.gappa +213 -0
  42. data/ext/crlibm/gappa/log-td-accurate.gappa +217 -0
  43. data/ext/crlibm/gappa/log-td.gappa +156 -0
  44. data/ext/crlibm/gappa/trigoSinCosCase3.gappa +204 -0
  45. data/ext/crlibm/gappa/trigoTanCase2.gappa +73 -0
  46. data/ext/crlibm/install-sh +269 -0
  47. data/ext/crlibm/log-de.c +431 -0
  48. data/ext/crlibm/log-de.h +732 -0
  49. data/ext/crlibm/log-td.c +852 -0
  50. data/ext/crlibm/log-td.h +819 -0
  51. data/ext/crlibm/log10-td.c +906 -0
  52. data/ext/crlibm/log10-td.h +823 -0
  53. data/ext/crlibm/log2-td.c +935 -0
  54. data/ext/crlibm/log2-td.h +821 -0
  55. data/ext/crlibm/maple/atan.mpl +359 -0
  56. data/ext/crlibm/maple/common-procedures.mpl +997 -0
  57. data/ext/crlibm/maple/csh.mpl +446 -0
  58. data/ext/crlibm/maple/double-extended.mpl +151 -0
  59. data/ext/crlibm/maple/exp-td.mpl +195 -0
  60. data/ext/crlibm/maple/log-de.mpl +243 -0
  61. data/ext/crlibm/maple/log-td.mpl +316 -0
  62. data/ext/crlibm/maple/log10-td.mpl +345 -0
  63. data/ext/crlibm/maple/log2-td.mpl +334 -0
  64. data/ext/crlibm/maple/trigo.mpl +728 -0
  65. data/ext/crlibm/maple/triple-double.mpl +58 -0
  66. data/ext/crlibm/missing +198 -0
  67. data/ext/crlibm/mkinstalldirs +40 -0
  68. data/ext/crlibm/rem_pio2_accurate.c +219 -0
  69. data/ext/crlibm/rem_pio2_accurate.h +53 -0
  70. data/ext/crlibm/scs_lib/AUTHORS +3 -0
  71. data/ext/crlibm/scs_lib/COPYING +504 -0
  72. data/ext/crlibm/scs_lib/ChangeLog +16 -0
  73. data/ext/crlibm/scs_lib/INSTALL +215 -0
  74. data/ext/crlibm/scs_lib/Makefile.am +18 -0
  75. data/ext/crlibm/scs_lib/Makefile.in +328 -0
  76. data/ext/crlibm/scs_lib/NEWS +0 -0
  77. data/ext/crlibm/scs_lib/README +9 -0
  78. data/ext/crlibm/scs_lib/TODO +4 -0
  79. data/ext/crlibm/scs_lib/addition_scs.c +623 -0
  80. data/ext/crlibm/scs_lib/config.guess +1461 -0
  81. data/ext/crlibm/scs_lib/config.sub +1566 -0
  82. data/ext/crlibm/scs_lib/configure +6226 -0
  83. data/ext/crlibm/scs_lib/division_scs.c +110 -0
  84. data/ext/crlibm/scs_lib/double2scs.c +174 -0
  85. data/ext/crlibm/scs_lib/install-sh +269 -0
  86. data/ext/crlibm/scs_lib/missing +198 -0
  87. data/ext/crlibm/scs_lib/mkinstalldirs +40 -0
  88. data/ext/crlibm/scs_lib/multiplication_scs.c +456 -0
  89. data/ext/crlibm/scs_lib/poly_fct.c +112 -0
  90. data/ext/crlibm/scs_lib/print_scs.c +73 -0
  91. data/ext/crlibm/scs_lib/rand_scs.c +63 -0
  92. data/ext/crlibm/scs_lib/scs.h +353 -0
  93. data/ext/crlibm/scs_lib/scs2double.c +391 -0
  94. data/ext/crlibm/scs_lib/scs2mpf.c +58 -0
  95. data/ext/crlibm/scs_lib/scs2mpfr.c +61 -0
  96. data/ext/crlibm/scs_lib/scs_private.c +23 -0
  97. data/ext/crlibm/scs_lib/scs_private.h +133 -0
  98. data/ext/crlibm/scs_lib/tests/tbx_timing.h +102 -0
  99. data/ext/crlibm/scs_lib/wrapper_scs.h +486 -0
  100. data/ext/crlibm/scs_lib/zero_scs.c +52 -0
  101. data/ext/crlibm/stamp-h.in +1 -0
  102. data/ext/crlibm/tests/Makefile.am +43 -0
  103. data/ext/crlibm/tests/Makefile.in +396 -0
  104. data/ext/crlibm/tests/blind_test.c +148 -0
  105. data/ext/crlibm/tests/generate_test_vectors.c +258 -0
  106. data/ext/crlibm/tests/soak_test.c +334 -0
  107. data/ext/crlibm/tests/test_common.c +627 -0
  108. data/ext/crlibm/tests/test_common.h +28 -0
  109. data/ext/crlibm/tests/test_perf.c +570 -0
  110. data/ext/crlibm/tests/test_val.c +249 -0
  111. data/ext/crlibm/trigo_accurate.c +500 -0
  112. data/ext/crlibm/trigo_accurate.h +331 -0
  113. data/ext/crlibm/trigo_fast.c +1219 -0
  114. data/ext/crlibm/trigo_fast.h +639 -0
  115. data/ext/crlibm/triple-double.h +878 -0
  116. data/ext/extconf.rb +31 -0
  117. data/ext/fpu.c +107 -0
  118. data/ext/jamis-mod.rb +591 -0
  119. data/lib/fpu.rb +287 -0
  120. data/lib/interval.rb +1170 -0
  121. data/lib/intervals.rb +212 -0
  122. data/lib/struct_float.rb +133 -0
  123. data/test/data_atan.txt +360 -0
  124. data/test/data_cos.txt +346 -0
  125. data/test/data_cosh.txt +3322 -0
  126. data/test/data_exp.txt +3322 -0
  127. data/test/data_log.txt +141 -0
  128. data/test/data_sin.txt +140 -0
  129. data/test/data_sinh.txt +3322 -0
  130. data/test/data_tan.txt +342 -0
  131. metadata +186 -0
@@ -0,0 +1,446 @@
1
+ restart:
2
+ Digits := 150;
3
+ with (numapprox):with(orthopoly):
4
+ interface(quiet=true);
5
+ read "common-procedures.mpl";
6
+ mkdir("TEMPCSH");
7
+
8
+
9
+ #######################################################################
10
+ # Some values to go to the .testdata
11
+ # What is the first value that rounds to nearest to +inf ?
12
+ ieeehexa(arcsinh(hexa2ieee(["7fefffff","ffffffff"])));
13
+
14
+ # What is the first value that rounds to +inf to +inf ?
15
+
16
+
17
+ ######################################################################
18
+ #First, some constants variables (used in the polynomial evaluations)
19
+ n_double_ch := 11: # max degree for cosh's polynomial evaluation
20
+ n_double_sh := 8: # max degree for sinh's polynomial evaluation
21
+ b_max := 2**(-9.): # max absolute input for polynomial evaluation
22
+
23
+ ######################################################################
24
+ #some constants ...
25
+ inv_ln_2 := 1/ln(2.):
26
+ ln2_hi := hexa2ieee(["3FE62E42", "FEFA3800"]):
27
+ ln2_lo := nearest(ln(2.)-ln2_hi):
28
+ two_43_44 := 2^43 + 2^44:
29
+ bias := convert(op(2,ieeehexa(ln(2.)/2.+two_43_44)),'decimal','hex'): #to get maximum index for the second range reduction ...
30
+
31
+
32
+ ######################################################################
33
+ #Bounds of our evaluation
34
+ max_input_ch := arccosh(hexa2ieee(["7FEFFFFF","FFFFFFFF"])):
35
+ k_max_ch := ceil(max_input_ch / ln(2)):
36
+ max_input_sh := arcsinh(hexa2ieee(["7FEFFFFF","FFFFFFFF"])):
37
+ k_max_sh := ceil(max_input_sh / ln(2)):
38
+ #towards +inf, we have cosh(x) = sinh(x) since exp(-x) is too small
39
+ #so, we are sure of k_max_sh == k_max_ch
40
+ k_max := k_max_ch;
41
+
42
+ ######################################################################
43
+ # When can we ignore exp(-x) in front of exp(x) in the first step ?
44
+ # We want the same error as in the general case
45
+ k_max_csh_approx_exp := 35:
46
+ tempxmax:=(k_max_csh_approx_exp-1)*log(2):
47
+ eps_csh_approx_exp := exp(-tempxmax)/exp(tempxmax):
48
+ log2(%); #
49
+
50
+ # When can we ignore exp(-x) in front of exp(x) in the second step ?
51
+ # The worst case for exp for large arguments requires 115 bits
52
+ k_max_csh_approx_exp_2 := 65:
53
+ tempxmax:=(k_max_csh_approx_exp_2-1)*log(2):
54
+ eps_csh_approx_exp_2 := exp(-tempxmax)/exp(tempxmax):
55
+ log2(%); # 118
56
+
57
+
58
+ ######################################################################
59
+ #The Taylor polynoms
60
+ poly_ch :=series(cosh(x),x,n_double_ch):
61
+ poly_ch := convert(poly_ch,polynom)-1;
62
+ poly_sh :=series(sinh(x),x,n_double_sh):
63
+ poly_sh := (convert(poly_sh,polynom))/x-1;
64
+
65
+
66
+
67
+
68
+
69
+
70
+ ####################################################################
71
+ # secondary functions
72
+
73
+ size_of_table := convert(op(2,ieeehexa(two_43_44+ln(2.)/2.)),decimal,hex);
74
+ #returns the float which follow immediately the input
75
+ next_float := proc(value)
76
+ local hex1,hex2,hexcat,result;
77
+ hex1:= op(1, value):
78
+ hex2:= op(2, value):
79
+ hexcat:= cat(hex1, hex2);
80
+ result := convert(convert(convert(hexcat,decimal,hex)+1+2**64,hex),string);
81
+ result := [substring(result,2..9), substring(result,10..18)];
82
+ end:
83
+ #compute the errors done in tabulated values for cosh
84
+ delta_table_cosh_func := proc()
85
+ local result, i, value, temp, tmp, maxi;
86
+ value := ieeehexa(two_43_44-ln(2.)/2.);
87
+ result := 0;
88
+ maxi := 0;
89
+ for i from -size_of_table to size_of_table do
90
+ tmp := cosh(hexa2ieee(value)-two_43_44):
91
+ temp := nearest(tmp):
92
+ result := max(result, abs(tmp - temp - nearest(tmp-temp)));
93
+ maxi := max(maxi, abs(temp + nearest(tmp-temp)));
94
+ value:=next_float(value):
95
+ od:
96
+ result,maxi;
97
+ end:
98
+ #compute the error done in tabulated values for sinh
99
+ delta_table_sinh_func := proc()
100
+ local result, i, value, temp, tmp, maxi;
101
+ value := ieeehexa(two_43_44-ln(2.)/2.);
102
+ result := 0;
103
+ maxi := 0;
104
+ for i from -size_of_table to size_of_table do
105
+ tmp := sinh(hexa2ieee(value)-two_43_44):
106
+ temp := nearest(tmp):
107
+ result := max(result, abs(tmp - temp - nearest(tmp-temp)));
108
+ maxi := max(maxi, abs(temp + nearest(tmp-temp)));
109
+ value:=next_float(value):
110
+ od:
111
+ result,maxi;
112
+ end:
113
+
114
+
115
+ #return the error on x_hi * y_lo
116
+ Mul11_Error := proc(x,err_x, y, err_y)
117
+ (2^(-53) * y + err_y) * (err_x + 1/2*ulp(x)) + x * err_y;
118
+ end:
119
+
120
+
121
+ #return the error on (x_hi * y_hi)_lo + x_lo * y_hi + x_hi * y_lo
122
+ Mul43_Error := proc(x,err_x, y, err_y)
123
+ 1/2*ulp(3*2^(-53)* x * y) + 1/2*ulp(2*2^(-53) * x * y) + Mul11_Error(x, err_x, y, err_y) + Mul11_Error(y, err_y, x, err_x);
124
+ end:
125
+
126
+
127
+
128
+ cosh_0_35 := proc()
129
+ local k, delta, maxi,epsilon, mini,cosh_0_35_max, delta_cosh_0_35:
130
+ epsilon := 0; delta := 0:
131
+ for k from -35 to -1 do
132
+ delta_cosh_0_35 := 1/2*2^(-53)*ulp(1/(2^k)*(cosh_max + sinh_max)) + 1/(2^k)*(delta_sinh + delta_cosh):
133
+ cosh_0_35_max := 1/(2^k)*(cosh_max + sinh_max):
134
+ delta_cosh_0_35 := 1/2*2^(-53)*ulp(cosh_0_35_max + 2^k * sinh_max) + delta_cosh_0_35 + 2^k * delta_sinh:
135
+ cosh_0_35_max := cosh_0_35_max + 2^k * sinh_max:
136
+ delta_cosh_0_35 := 1/2*2^(-53)*ulp(cosh_0_35_max + 2^k * cosh_max) + delta_cosh_0_35 + 2^k * delta_cosh:
137
+ cosh_0_35_max := cosh_0_35_max + 2^k * cosh_max:
138
+ maxi := max(evalf(cosh((k-1/2)*ln(2))),evalf(cosh((k+1/2)*ln(2)))):
139
+ mini := min(evalf(cosh((k-1/2)*ln(2))),evalf(cosh((k+1/2)*ln(2)))):
140
+
141
+ epsilon := max(epsilon, delta_cosh_0_35/mini):
142
+ delta := max(delta, delta_cosh_0_35):
143
+ od;
144
+ for k from 1 to 35 do
145
+ delta_cosh_0_35 := 1/2*2^(-53)*ulp(1/(2^k)*(cosh_max + sinh_max)) + 1/(2^k)*(delta_sinh + delta_cosh):
146
+ cosh_0_35_max := 1/(2^k)*(cosh_max + sinh_max):
147
+ delta_cosh_0_35 := 1/2*2^(-53)*ulp(cosh_0_35_max + 2^k * sinh_max) + delta_cosh_0_35 + 2^k * delta_sinh:
148
+ cosh_0_35_max := cosh_0_35_max + 2^k * sinh_max:
149
+ delta_cosh_0_35 := 1/2*2^(-53)*ulp(cosh_0_35_max + 2^k * cosh_max) + delta_cosh_0_35 + 2^k * delta_cosh:
150
+ cosh_0_35_max := cosh_0_35_max + 2^k * cosh_max:
151
+
152
+ maxi := max(evalf(cosh((k-1/2)*ln(2))),evalf(cosh((k+1/2)*ln(2)))):
153
+ mini := min(evalf(cosh((k-1/2)*ln(2))),evalf(cosh((k+1/2)*ln(2)))):
154
+ epsilon := max(epsilon, delta_cosh_0_35/mini):
155
+ delta := max(delta, delta_cosh_0_35):
156
+ od;
157
+ delta, epsilon;
158
+ end:
159
+
160
+
161
+ cosh_35_inf := proc()
162
+ local k, delta, maxi,epsilon, mini,cosh_0_35_max, delta_cosh_0_35:
163
+ epsilon := 0; delta := 0:
164
+ for k from 35 to 1025 do
165
+ delta_cosh_0_35 := 1/2*2^(-53)*ulp(2^k*(cosh_max + sinh_max)) + 2^k*(delta_sinh + delta_cosh) + 1/(2^k)*(cosh_max + sinh_max + delta_sinh + delta_cosh):
166
+ cosh_0_35_max := 2^k*(cosh_max + sinh_max):
167
+
168
+ maxi := max(evalf(cosh((k-1/2)*ln(2))),evalf(cosh((k+1/2)*ln(2)))):
169
+ mini := min(evalf(cosh((k-1/2)*ln(2))),evalf(cosh((k+1/2)*ln(2)))):
170
+ epsilon := max(epsilon, delta_cosh_0_35/mini):
171
+ delta := max(delta, delta_cosh_0_35):
172
+ od;
173
+ delta, epsilon;
174
+ end:
175
+ #############################################################
176
+
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+ ######################################################################
185
+ #now we can begin the proof
186
+
187
+ ######################################################################
188
+ #first, we must compute the error created by the first range reduction
189
+ # CODY and WAITE Argument reduction
190
+
191
+ ln2 := ln(2.);
192
+ invln2:= nearest(1/ln2);
193
+ reminvln2 := evalf(1/ln2 - invln2);
194
+ expln2:=ieeedouble(ln2)[2]: #get the exponent of ln2 in its IEEE representation
195
+
196
+ bits_ln2_hi_0 := ceil(log2(k_max));
197
+ # 1/2 <= ln2/2^(expln2 + 1) < 1
198
+ ln2_hi := round(evalf(ln2 * 2^(52 - bits_ln2_hi_0 - expln2)))/2^(52 - bits_ln2_hi_0 - expln2);#this trick is used to get a truncated mantissa for ln2_hi
199
+ #ln2_hi is a now exactly representable in the IEEE format and bits_ln2_hi_0 last bits of its mantissa are set to 0
200
+ #and bits_ln2_hi_0 is exactly the max number of bits to represent k
201
+ #so the k * ln2_hi-product is exact :)
202
+ ln2_lo:=nearest(ln2 - ln2_hi):
203
+
204
+ # The error in this case (we need absolute error)
205
+ delta_repr_ln2 := abs(ln2 - ln2_hi - ln2_lo);
206
+ delta_round := evalf(1/2 * ulp(ln2_lo));
207
+ delta_cody_waite := k_max * (delta_repr_ln2 + delta_round);
208
+
209
+ delta_b := delta_repr_ln2 + delta_round + delta_cody_waite;
210
+
211
+ #we have 2 cases:
212
+ # * k != 0 and we have an inexact range reduction
213
+ # * k == 0 and we have no range reduction and then delta_range_reduc = 0
214
+
215
+ #the second range reduction is exact, so it doesn't introduce new error
216
+ #after this second range reduction, we have a argument <= 2^(-9)
217
+ #'mathematical' reductions:
218
+ # x = k * ln(2) + y
219
+ # y = a + b
220
+ #'true' reductions:
221
+ # x = k * (ln2_hi + ln2_lo) + (b_hi + b_lo) + table_index_float
222
+ # with table_index_float = table_index * 2^(-8)
223
+
224
+ #we'll use the following mathematical formulaes :
225
+ #cosh(a + b) = cosh(a) * cosh(b) + sinh(a) * sinh(b)
226
+ #sinh(a + b) = sinh(a) * cosh(b) + sinh(b) * cosh(a)
227
+ #sinh(a) and cosh(a) are tabulated as double double
228
+ # and we use Taylor series to compute approximations of the sums
229
+
230
+ #computation of the absolute error in the tabulated values :
231
+ delta_ca := delta_table_cosh_func()[1];
232
+ delta_sa := delta_table_sinh_func()[1];
233
+ ca_max := delta_table_cosh_func()[2];
234
+ sa_max := delta_table_sinh_func()[2];
235
+
236
+
237
+ #now we must compute the error done in polynomial evaluation
238
+ #we use cosh(b) = 1 + sum(b^(2*k)/(2*k!), k > 0)
239
+ # sinh(b) = b * (1 + sum(b^(2*k)/(2*k+1!), k > 0))
240
+
241
+ #both used polynoms are even (x�, x^4, x^6, ...) and we can use this fact
242
+ y_max := b_max ^ 2;
243
+ delta_y := 1/2*ulp(y_max) + delta_b^2;
244
+ # remove the first x and compute the polynomial of y = x�
245
+ poly_ch2 := subs(x=sqrt(y), expand(poly_ch));
246
+ poly_sh2 := subs(x=sqrt(y), expand(poly_sh));
247
+ errlist_cosh := errlist_quickphase_horner(degree(poly_ch2), 0, 0, 2^(-53), 2^(-70)):
248
+ errlist_sinh := errlist_quickphase_horner(degree(poly_sh2), 0, 0, 2^(-53), 2^(-70)):
249
+
250
+ #error between effective result and theorical polynomial result
251
+ rounding_error_tcb := compute_horner_rounding_error(poly_ch2, y, y_max, errlist_cosh, true);
252
+ rounding_error_tsb := compute_horner_rounding_error(poly_sh2, y, y_max, errlist_sinh, true);
253
+
254
+ #error between therical polynomial result and cosh value
255
+ approx_error_tcb := infnorm((cosh(x)-1-poly_ch)/(cosh(x)-1),x= -b_max..b_max);
256
+ approx_error_tsb := infnorm((sinh(x)/x-1-poly_sh)/(sinh(x)/x-1),x= -b_max..b_max);
257
+
258
+ delta_tcb := rounding_error_tcb[2] + approx_error_tcb;
259
+ delta_tsb := rounding_error_tsb[2] + approx_error_tsb;
260
+ tsb_max := rounding_error_tsb[4];
261
+ tcb_max := rounding_error_tcb[4];
262
+
263
+ #now we must do the first reconstruction, which correspond to cosh(a + b) = cosh(a) * cosh(b) + sinh(a) * sinh(b)
264
+ #first case : sinh(a) = 0 = sa (= sa_hi + sa_lo in the C code)
265
+ # cosh(a) = 1 = ca (= ca_hi + ca_lo in the C code)
266
+ #there is no error on sa and caj
267
+ delta_cosh0 := delta_tcb;
268
+ cosh0_max := 1+tcb_max;
269
+ delta_sinh0 := delta_b:
270
+ sinh0_max := b_max:
271
+ delta_sinh0 := delta_sinh0 + (tsb_max + delta_tsb)*(b_max + delta_b + 1/2*ulp(b_max)) - b_max * tsb_max + 1/2*ulp(sinh0_max + tsb_max*b_max):
272
+ sinh0_max := sinh0_max + tsb_max*b_max:
273
+ delta_sinh0 := delta_sinh0 + 2^(-53)*1/2*ulp(sinh0_max + tsb_max*b_max);
274
+ sinh0_max := sinh0_max + tsb_max*b_max;
275
+
276
+ #second case : sinh(a) <> 0
277
+ #there is a delta_table_cosh and delta_table_sinh absolute error on ca and sa.
278
+
279
+ delta_cosh1 := delta_ca:
280
+ cosh1_max := 2^(-53)*ca_max:
281
+ delta_cosh1 := 1/2*ulp(cosh1_max + 3*2^(-53)*b_max * sa_max) + delta_cosh1 + Mul43_Error(b_max, delta_b, sa_max, delta_sa):
282
+ cosh1_max := cosh1_max + 3 * 2^(-53) * b_max * sa_max:
283
+ delta_cosh1 := 1/2*ulp(cosh1_max + b_max * sa_max * tsb_max) + delta_cosh1 + ((sa_max+1/2*ulp(sa_max)+delta_sa)*(b_max+ulp(b_max)+delta_b)*(tsb_max+delta_tsb)-tsb_max*sa_max*b_max):
284
+ cosh1_max := cosh1_max + b_max * sa_max * tsb_max:
285
+ delta_cosh1 := 1/2*ulp(cosh1_max + tcb_max*ca_max) + delta_cosh1 + ((ca_max + 1/2*ulp(ca_max) + delta_ca)*(tcb_max-delta_tcb)-ca_max*tcb_max):
286
+ cosh11_max := cosh1_max + tcb_max*ca_max:
287
+ delta_cosh1 := 1/2*ulp(cosh1_max + b_max * sa_max) + delta_cosh1:
288
+ cosh11_max := cosh1_max + b_max * sa_max:
289
+ delta_cosh1 := 1/2*2^(-53)*ulp(cosh1_max + ca_max) + delta_cosh1;
290
+ cosh11_max := cosh1_max + ca_max;
291
+
292
+ cosh_max := max(cosh0_max, cosh1_max);
293
+ delta_cosh := max(delta_cosh0, delta_cosh1);
294
+
295
+ delta_sinh1 := delta_sa:
296
+ sinh1_max := 2^(-53)*sa_max:
297
+ delta_sinh1 := 1/2*ulp(sinh1_max + 3*2^(-53)*ca_max * b_max) + delta_sinh1 + Mul43_Error(ca_max, delta_ca, b_max, delta_b):
298
+ sinh1_max := sinh1_max + 3*2^(-53)*ca_max * b_max:
299
+ delta_sinh1 := delta_sinh1 + 1/2*ulp(sinh1_max + sa_max * tcb_max):
300
+ sinh1_max := sinh1_max + sa_max * tcb_max:
301
+ delta_sinh1 := 1/2*ulp(sinh1_max + b_max * ca_max * tsb_max) + delta_sinh1 + ((ca_max+1/2*ulp(ca_max)+delta_ca)*(b_max+ulp(b_max)+delta_b)*(tsb_max+delta_tsb)-tsb_max*ca_max*b_max):
302
+ sinh1_max := sinh1_max + b_max * sa_max * tsb_max:
303
+ delta_sinh1 := delta_sinh1 + 1/2*2^(-53)*ulp(sinh1_max + b_max * ca_max):
304
+ sinh1_max := sinh1_max + b_max * ca_max:
305
+ delta_sinh1 := delta_sinh1 + 2^(-53)*1/2*ulp(sinh1_max + sa_max);
306
+ sinh1_max := sinh1_max + sa_max;
307
+
308
+ sinh_max := max(sinh1_max, sinh0_max);
309
+ delta_sinh := max(delta_sinh0, delta_sinh1);
310
+ #so we have the error done on cosh(y) and sinh(y)
311
+ #now we must compute the error done on the last reconstruction
312
+ #there are many cases
313
+ #we begin by 0 < |k| < 35
314
+ epsilon_cosh_0_35 := cosh_0_35()[2];
315
+ #|k| > 35
316
+ epsilon_cosh_35_inf := cosh_35_inf()[2];
317
+
318
+ #rounding constant
319
+ maxepsilon_csh := max(epsilon_cosh_35_inf, epsilon_cosh_0_35, delta_cosh):
320
+ round_cst_csh := evalf(compute_rn_constant(maxepsilon_csh));;
321
+
322
+
323
+
324
+ #################################################################################################"
325
+ #now some functions used to build the .h header file.
326
+ #################################################################################################"
327
+ IEEE2db_number_BE := proc(ieee_number)
328
+ local hex1, hex2, hexcat;
329
+ hexcat=ieeehexa(ieee_number);
330
+ hex1:= op(1, ieeehexa(ieee_number)):
331
+ hex2:= op(2, ieeehexa(ieee_number)):
332
+ cat(cat("{{0x"||hex1||",0x"||hex2||"}}; /*",sprintf("%.10e",ieee_number)),"*/ \n");
333
+ end:
334
+ IEEE2db_number_LE := proc(ieee_number)
335
+ local hex1, hex2, hexcat;
336
+ hexcat=ieeehexa(ieee_number);
337
+ hex1:= op(2, ieeehexa(ieee_number)):
338
+ hex2:= op(1, ieeehexa(ieee_number)):
339
+ cat(cat("{{0x"||hex1||",0x"||hex2||"}}; /*",sprintf("%.10e",ieee_number)),"*/ \n");
340
+ end:
341
+ IEEE2db_number := proc(ieee_number, big_little)
342
+ if (big_little = 1) then
343
+ IEEE2db_number_BE(ieee_number):
344
+ else
345
+ IEEE2db_number_LE(ieee_number):
346
+ fi;
347
+ end:
348
+ lo_part := proc(ieee_number)
349
+ if (ieee_number <> 0) then
350
+ ieee_number - nearest(ieee_number);
351
+ else
352
+ 0;
353
+ end if;
354
+ end:
355
+ IEEE2db_db_number_sinh := proc(number,big_little)
356
+ local hexstring1,hexstring2, hex1,hex2,hex3,hex4;
357
+ hexstring1 := ieeehexa(number);
358
+ hexstring2 := ieeehexa(lo_part(number));
359
+ if (big_little = 1) then
360
+ hex1:= op(1, hexstring1):
361
+ hex2:= op(2, hexstring1):
362
+ hex3:= op(1, hexstring2):
363
+ hex4:= op(2, hexstring2):
364
+ else
365
+ hex1:= op(2, hexstring1):
366
+ hex2:= op(1, hexstring1):
367
+ hex3:= op(2, hexstring2):
368
+ hex4:= op(1, hexstring2):
369
+ fi;
370
+ " {{0x"||hex1||", 0x"||hex2||"}}, {{0x"||hex3||", 0x"||hex4||"}}},\n";
371
+ end:
372
+
373
+ IEEE2db_db_number_cosh := proc(number,big_little)
374
+ local hexstring1,hexstring2, hex1,hex2,hex3,hex4;
375
+ hexstring1 := ieeehexa(number);
376
+ hexstring2 := ieeehexa(lo_part(number));
377
+ if (big_little = 1) then
378
+ hex1:= op(1, hexstring1):
379
+ hex2:= op(2, hexstring1):
380
+ hex3:= op(1, hexstring2):
381
+ hex4:= op(2, hexstring2):
382
+ else
383
+ hex1:= op(2, hexstring1):
384
+ hex2:= op(1, hexstring1):
385
+ hex3:= op(2, hexstring2):
386
+ hex4:= op(1, hexstring2):
387
+ fi;
388
+ " {{{0x"||hex1||", 0x"||hex2||"}}, {{0x"||hex3||", 0x"||hex4||"}},\n";
389
+ end:
390
+
391
+ #####################################################################################
392
+
393
+
394
+
395
+ #now, we can produce the header file !
396
+ round_cst_cosh := 1.0020:
397
+ round_cst_sinh := round_cst_cosh:
398
+ filename := "TEMPCSH/csh_fast.h":
399
+ fd := fopen(filename, WRITE, TEXT):
400
+ fprintf(fd, "\n /* File generated by maple/csh.mpl */ \n"):
401
+ fprintf(fd, "\n"):
402
+ fprintf(fd, " static double maxepsilon_csh = %1.30e ;\n", maxepsilon_csh):
403
+ fprintf(fd, " static double round_cst_csh = %1.30e ;\n", round_cst_csh):
404
+ fprintf(fd, "\n"):
405
+
406
+
407
+ fprintf(fd, "#ifdef WORDS_BIGENDIAN \n"):
408
+
409
+ for big_little from 1 to 2 do
410
+ if (big_little = 2) then
411
+ fprintf(fd, "#else \n"):
412
+ fi:
413
+ fprintf(fd, cat( " static db_number const inv_ln_2 = ",IEEE2db_number(inv_ln_2,big_little))):
414
+ fprintf(fd, cat( " static db_number const ln2_hi = ",IEEE2db_number(ln2_hi,big_little))):
415
+ fprintf(fd, cat( " static db_number const ln2_lo = ",IEEE2db_number(ln2_lo,big_little))):
416
+ fprintf(fd, cat( " static db_number const two_43_44 = ", IEEE2db_number(two_43_44,big_little))):
417
+ fprintf(fd, cat( " static db_number const two_minus_30 = ", IEEE2db_number(2**(-40),big_little))):
418
+ fprintf(fd, " static int const bias = %d ;\n", bias):
419
+ fprintf(fd, "\n");
420
+
421
+ fprintf(fd,"/* some bounds */ \n"):
422
+ fprintf(fd, cat( " static db_number const max_input_csh = ",IEEE2db_number(max_input_ch,big_little))):
423
+
424
+ fprintf(fd, "\n"):
425
+ fprintf(fd, cat(cat(" static const db_number cosh_sinh_table[",convert(2*size_of_table+1,string)),"][4] = { \n"));
426
+ vvalue := ieeehexa(two_43_44-ln(2.)/2.);
427
+ for i from -size_of_table to size_of_table do
428
+ fprintf(fd, IEEE2db_db_number_cosh(cosh(hexa2ieee(vvalue)-two_43_44),big_little));
429
+ fprintf(fd, IEEE2db_db_number_sinh(sinh(hexa2ieee(vvalue)-two_43_44),big_little));
430
+ vvalue:=next_float(vvalue):
431
+ od:
432
+ fprintf(fd,"}; \n");
433
+
434
+ fprintf(fd,"/* the coefficients for the cosh-approximations */ \n"):
435
+ for i from 1 to (n_double_ch/2) do
436
+ fprintf(fd, cat(cat(cat( " static const db_number c",convert(2*(i-1),string))," = "),IEEE2db_number(coeff(poly_ch+1,x,2*(i-1)),big_little))):
437
+ od:
438
+
439
+ fprintf(fd,"/* the coefficients for the sinh-approximations */\n"):
440
+ for i from 1 to (n_double_sh/2) do
441
+ fprintf(fd, cat(cat(cat( " static const db_number s",convert(2*i-1,string))," = "),IEEE2db_number(coeff(poly_sh+1,x,2*(i-1)),big_little))):
442
+ od:
443
+ od:
444
+ fprintf(fd, "#endif \n"):
445
+
446
+ fclose(fd):
@@ -0,0 +1,151 @@
1
+
2
+ #---------------------------------------------------------------------
3
+ # ieeedouble converts a number to IEEE double extended format.
4
+ # returns sign (-1 or 1), exponent between -16383 and 16383, mantissa as a fraction between 0.5 and 1.
5
+
6
+ # TODO : use JMM procedure; check subnormals etc
7
+ ieeedoubleExt:=proc(xx)
8
+ local x, sign, logabsx, exponent, mantissa, infmantissa;
9
+ x:=evalf(xx):
10
+ if (x=0) then
11
+ sign,exponent,mantissa := 0,0,0;
12
+ else
13
+ if (x<0) then sign:=-1:
14
+ else sign:=1:
15
+ fi:
16
+ exponent := floor(log2(sign*x));
17
+ if (exponent>16383) then mantissa:=infinity: exponent:=16383:
18
+ elif (exponent< -16382) then
19
+ # denorm
20
+ exponent := -16383
21
+ fi:
22
+ infmantissa := sign*x*2^(63-exponent);
23
+ if frac(infmantissa) <> 0.5 then mantissa := round(infmantissa)
24
+ else
25
+ mantissa := floor(infmantissa);
26
+ if type(mantissa,odd) then mantissa := mantissa+1 fi;
27
+ fi;
28
+ mantissa := mantissa*2^(-63);
29
+ fi;
30
+ sign,exponent,mantissa;
31
+ end:
32
+
33
+ nearestExt := proc(x)
34
+ local sign, exponent, mantissa;
35
+
36
+ sign, exponent, mantissa := ieeedoubleExt(x);
37
+ sign*mantissa*2^(exponent);
38
+ end:
39
+
40
+
41
+
42
+ ieeehexaExt:= proc(x)
43
+ local resultat, sign, exponent, mantissa, t;
44
+
45
+ if(x=0) then resultat:=["0000","0000","0000","0000","0000"];
46
+ elif(x=-0) then resultat:=["8000","0000","0000","0000","0000"];
47
+ else
48
+ sign,exponent,mantissa := ieeedoubleExt(x);
49
+ t := 2**80 + (exponent+16383)*2^64 + mantissa*2^63;
50
+ if (sign=-1) then
51
+ t := t + 2**79;
52
+ fi:
53
+ t := convert(t, hex);
54
+ t:=convert(t, string):
55
+
56
+ resultat:=[substring(t, 2..5),
57
+ substring(t, 6..9 ), substring(t, 10..13 ),
58
+ substring(t, 14..17 ), substring(t, 18..21 )];
59
+
60
+ end if:
61
+ resultat;
62
+ end proc:
63
+
64
+
65
+
66
+ printDoubleAsShort:=proc(x)
67
+ local ss;
68
+ ss:=ieeehexa(x);
69
+ cat( "DOUBLE_HEX(",
70
+ substring(ss[1], 1..4), ", " ,
71
+ substring(ss[1], 5..8), ", " ,
72
+ substring(ss[2], 1..4), ", " ,
73
+ substring(ss[2], 5..8)) ;
74
+ end proc:
75
+
76
+ printDoubleExtAsShort:=proc(x)
77
+ local ss;
78
+ ss:=ieeehexaExt(x);
79
+ cat( "LDOUBLE_HEX(", ss[1], ", ", ss[2], ", ",ss[3], ", ", ss[4], ", ", ss[5], ")");
80
+ end proc:
81
+
82
+ printDoubleAsULL:=proc(x)
83
+ local ss;
84
+ ss:=ieeehexa(x);
85
+ cat( "ULL(", ss[1], ss[2], ")");
86
+ end proc:
87
+
88
+ printDoubleAsHexInt:=proc(x)
89
+ local ss;
90
+ ss:=ieeehexa(x);
91
+ cat(ss[1], ss[2]);
92
+ end proc:
93
+
94
+
95
+
96
+
97
+ #---------------------------------------------------------------------
98
+ # hi_lo takes an arbitrary precision number x and returns two doubles such that:
99
+ # x ~ x_hi + x_lo
100
+ hiloExt:= proc(x)
101
+ local x_hi, x_lo, res:
102
+ x_hi:= nearestExt(evalf(x)):
103
+ res:=x-x_hi:
104
+ if (res = 0) then
105
+ x_lo:=0:
106
+ else
107
+ x_lo:=nearestExt(evalf(res)):
108
+ end if;
109
+ x_hi,x_lo;
110
+ end:
111
+
112
+
113
+ #---------------------------------------------------------------------
114
+ # Like poly_exact, but the n first coefficients are exactly representable as the sum of two doubles.
115
+ # (to actually get the two doubles, use procedure hi_lo)
116
+
117
+ polyExact2Ext:=proc(P,n)
118
+ local deg,i, coef, coef_hi, coef_lo, Q:
119
+ Q:= 0:
120
+ convert(Q, polynom):
121
+ deg:=degree(P,x):
122
+ for i from 0 to deg do
123
+ coef :=coeff(P,x,i):
124
+ coef_hi, coef_lo:=hiloExt(coef):
125
+ Q:= Q + coef_hi*x^i:
126
+ if(i<n) then
127
+ Q := Q + coef_lo*x^i:
128
+ fi:
129
+ od:
130
+ return(Q);
131
+ end:
132
+
133
+ printPolyExt := proc(fd,P,n, name_of_poly)
134
+ local deg,i, coef, coef_hi, coef_lo;
135
+ convert(Q, polynom):
136
+ deg:=degree(P,x):
137
+ fprintf(fd, " static const long double %s[%d][2] = {\n", name_of_poly, deg+1);
138
+ for i from 0 to deg do
139
+ coef :=coeff(P,x,i):
140
+ coef_hi, coef_lo:=hiloExt(coef):
141
+
142
+ fprintf(fd,"{ %1.50eL, ",coef_hi);
143
+
144
+ if(i<n) then
145
+ fprintf(fd," %1.50eL},\n",coef_lo);
146
+ else
147
+ fprintf(fd,"0},\n");
148
+ fi:
149
+ od:
150
+ fprintf(fd,"}; \n");
151
+ end: