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.
- 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:
|