intervals 0.3.56
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.txt +1 -0
- data/ext/crlibm/AUTHORS +2 -0
- data/ext/crlibm/COPYING +504 -0
- data/ext/crlibm/ChangeLog +80 -0
- data/ext/crlibm/INSTALL +182 -0
- data/ext/crlibm/Makefile.am +84 -0
- data/ext/crlibm/Makefile.in +530 -0
- data/ext/crlibm/NEWS +0 -0
- data/ext/crlibm/README +31 -0
- data/ext/crlibm/TODO +47 -0
- data/ext/crlibm/VERSION +1 -0
- data/ext/crlibm/aclocal.m4 +989 -0
- data/ext/crlibm/atan-itanium.c +846 -0
- data/ext/crlibm/atan-pentium.c +261 -0
- data/ext/crlibm/atan_accurate.c +244 -0
- data/ext/crlibm/atan_accurate.h +191 -0
- data/ext/crlibm/atan_fast.c +324 -0
- data/ext/crlibm/atan_fast.h +678 -0
- data/ext/crlibm/config.guess +1461 -0
- data/ext/crlibm/config.sub +1566 -0
- data/ext/crlibm/configure +7517 -0
- data/ext/crlibm/configure.ac +364 -0
- data/ext/crlibm/crlibm.h +125 -0
- data/ext/crlibm/crlibm_config.h +149 -0
- data/ext/crlibm/crlibm_config.h.in +148 -0
- data/ext/crlibm/crlibm_private.c +293 -0
- data/ext/crlibm/crlibm_private.h +658 -0
- data/ext/crlibm/csh_fast.c +631 -0
- data/ext/crlibm/csh_fast.h +771 -0
- data/ext/crlibm/double-extended.h +496 -0
- data/ext/crlibm/exp-td.c +962 -0
- data/ext/crlibm/exp-td.h +685 -0
- data/ext/crlibm/exp_accurate.c +197 -0
- data/ext/crlibm/exp_accurate.h +85 -0
- data/ext/crlibm/gappa/log-de-E0-logir0.gappa +106 -0
- data/ext/crlibm/gappa/log-de-E0.gappa +79 -0
- data/ext/crlibm/gappa/log-de.gappa +81 -0
- data/ext/crlibm/gappa/log-td-E0-logir0.gappa +126 -0
- data/ext/crlibm/gappa/log-td-E0.gappa +143 -0
- data/ext/crlibm/gappa/log-td-accurate-E0-logir0.gappa +230 -0
- data/ext/crlibm/gappa/log-td-accurate-E0.gappa +213 -0
- data/ext/crlibm/gappa/log-td-accurate.gappa +217 -0
- data/ext/crlibm/gappa/log-td.gappa +156 -0
- data/ext/crlibm/gappa/trigoSinCosCase3.gappa +204 -0
- data/ext/crlibm/gappa/trigoTanCase2.gappa +73 -0
- data/ext/crlibm/install-sh +269 -0
- data/ext/crlibm/log-de.c +431 -0
- data/ext/crlibm/log-de.h +732 -0
- data/ext/crlibm/log-td.c +852 -0
- data/ext/crlibm/log-td.h +819 -0
- data/ext/crlibm/log10-td.c +906 -0
- data/ext/crlibm/log10-td.h +823 -0
- data/ext/crlibm/log2-td.c +935 -0
- data/ext/crlibm/log2-td.h +821 -0
- data/ext/crlibm/maple/atan.mpl +359 -0
- data/ext/crlibm/maple/common-procedures.mpl +997 -0
- data/ext/crlibm/maple/csh.mpl +446 -0
- data/ext/crlibm/maple/double-extended.mpl +151 -0
- data/ext/crlibm/maple/exp-td.mpl +195 -0
- data/ext/crlibm/maple/log-de.mpl +243 -0
- data/ext/crlibm/maple/log-td.mpl +316 -0
- data/ext/crlibm/maple/log10-td.mpl +345 -0
- data/ext/crlibm/maple/log2-td.mpl +334 -0
- data/ext/crlibm/maple/trigo.mpl +728 -0
- data/ext/crlibm/maple/triple-double.mpl +58 -0
- data/ext/crlibm/missing +198 -0
- data/ext/crlibm/mkinstalldirs +40 -0
- data/ext/crlibm/rem_pio2_accurate.c +219 -0
- data/ext/crlibm/rem_pio2_accurate.h +53 -0
- data/ext/crlibm/scs_lib/AUTHORS +3 -0
- data/ext/crlibm/scs_lib/COPYING +504 -0
- data/ext/crlibm/scs_lib/ChangeLog +16 -0
- data/ext/crlibm/scs_lib/INSTALL +215 -0
- data/ext/crlibm/scs_lib/Makefile.am +18 -0
- data/ext/crlibm/scs_lib/Makefile.in +328 -0
- data/ext/crlibm/scs_lib/NEWS +0 -0
- data/ext/crlibm/scs_lib/README +9 -0
- data/ext/crlibm/scs_lib/TODO +4 -0
- data/ext/crlibm/scs_lib/addition_scs.c +623 -0
- data/ext/crlibm/scs_lib/config.guess +1461 -0
- data/ext/crlibm/scs_lib/config.sub +1566 -0
- data/ext/crlibm/scs_lib/configure +6226 -0
- data/ext/crlibm/scs_lib/division_scs.c +110 -0
- data/ext/crlibm/scs_lib/double2scs.c +174 -0
- data/ext/crlibm/scs_lib/install-sh +269 -0
- data/ext/crlibm/scs_lib/missing +198 -0
- data/ext/crlibm/scs_lib/mkinstalldirs +40 -0
- data/ext/crlibm/scs_lib/multiplication_scs.c +456 -0
- data/ext/crlibm/scs_lib/poly_fct.c +112 -0
- data/ext/crlibm/scs_lib/print_scs.c +73 -0
- data/ext/crlibm/scs_lib/rand_scs.c +63 -0
- data/ext/crlibm/scs_lib/scs.h +353 -0
- data/ext/crlibm/scs_lib/scs2double.c +391 -0
- data/ext/crlibm/scs_lib/scs2mpf.c +58 -0
- data/ext/crlibm/scs_lib/scs2mpfr.c +61 -0
- data/ext/crlibm/scs_lib/scs_private.c +23 -0
- data/ext/crlibm/scs_lib/scs_private.h +133 -0
- data/ext/crlibm/scs_lib/tests/tbx_timing.h +102 -0
- data/ext/crlibm/scs_lib/wrapper_scs.h +486 -0
- data/ext/crlibm/scs_lib/zero_scs.c +52 -0
- data/ext/crlibm/stamp-h.in +1 -0
- data/ext/crlibm/tests/Makefile.am +43 -0
- data/ext/crlibm/tests/Makefile.in +396 -0
- data/ext/crlibm/tests/blind_test.c +148 -0
- data/ext/crlibm/tests/generate_test_vectors.c +258 -0
- data/ext/crlibm/tests/soak_test.c +334 -0
- data/ext/crlibm/tests/test_common.c +627 -0
- data/ext/crlibm/tests/test_common.h +28 -0
- data/ext/crlibm/tests/test_perf.c +570 -0
- data/ext/crlibm/tests/test_val.c +249 -0
- data/ext/crlibm/trigo_accurate.c +500 -0
- data/ext/crlibm/trigo_accurate.h +331 -0
- data/ext/crlibm/trigo_fast.c +1219 -0
- data/ext/crlibm/trigo_fast.h +639 -0
- data/ext/crlibm/triple-double.h +878 -0
- data/ext/extconf.rb +31 -0
- data/ext/fpu.c +107 -0
- data/ext/jamis-mod.rb +591 -0
- data/lib/fpu.rb +287 -0
- data/lib/interval.rb +1170 -0
- data/lib/intervals.rb +212 -0
- data/lib/struct_float.rb +133 -0
- data/test/data_atan.txt +360 -0
- data/test/data_cos.txt +346 -0
- data/test/data_cosh.txt +3322 -0
- data/test/data_exp.txt +3322 -0
- data/test/data_log.txt +141 -0
- data/test/data_sin.txt +140 -0
- data/test/data_sinh.txt +3322 -0
- data/test/data_tan.txt +342 -0
- 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:
|