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
data/lib/fpu.rb
ADDED
@@ -0,0 +1,287 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# Definitions for the module FPU.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2006 Stefano Taschini <taschini@ieee.org>.
|
6
|
+
# Licensed under the terms of LGPL: http://www.gnu.org/copyleft/lesser.html
|
7
|
+
|
8
|
+
begin
|
9
|
+
require "fpu_c"
|
10
|
+
rescue LoadError
|
11
|
+
Dir.chdir($LOAD_PATH.
|
12
|
+
map{|p| File.expand_path('../ext', p)}.
|
13
|
+
find(proc {$stderr.puts "Cannot locate fpu.c"; raise}) {|d|
|
14
|
+
File.exist?(File.expand_path('fpu.c',d))
|
15
|
+
}) {
|
16
|
+
begin
|
17
|
+
require "fpu_c"
|
18
|
+
rescue LoadError
|
19
|
+
$stderr.puts "*** I'll try and build fpu_c (it should happen only once)"
|
20
|
+
system("./extconf.rb")
|
21
|
+
system("make")
|
22
|
+
require "fpu_c"
|
23
|
+
$stderr.puts "*** Apparently, I succeeded in building fpu_c"
|
24
|
+
end
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
require "struct_float"
|
29
|
+
|
30
|
+
module FPU
|
31
|
+
|
32
|
+
#
|
33
|
+
# Perform a computation with the FPU rounding downwards.
|
34
|
+
#
|
35
|
+
# Example:
|
36
|
+
# FPU.down{1/5.0} < FPU.up{1/5.0} # => true
|
37
|
+
#
|
38
|
+
def FPU.down
|
39
|
+
saved = roundingDown
|
40
|
+
yield
|
41
|
+
ensure
|
42
|
+
self.rounding = saved
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Perform a computation with the FPU rounding upwards.
|
47
|
+
#
|
48
|
+
# Example:
|
49
|
+
# FPU.down{1/5.0} < FPU.up{1/5.0} # => true
|
50
|
+
#
|
51
|
+
def FPU.up
|
52
|
+
saved = roundingUp
|
53
|
+
yield
|
54
|
+
ensure
|
55
|
+
self.rounding = saved
|
56
|
+
end
|
57
|
+
|
58
|
+
# Raise +x+ to the +n+-th power with correct rounding.
|
59
|
+
def FPU.power(x, n)
|
60
|
+
if Float === x && Integer === n
|
61
|
+
return 1/FPU.power(x,-n) if n < 0
|
62
|
+
l=[];
|
63
|
+
while n > 0
|
64
|
+
n,y=n.divmod(2);
|
65
|
+
l=[y,l]
|
66
|
+
end
|
67
|
+
l.flatten.inject(1){|p,i| if i == 1 then p*p*x; else p*p; end}
|
68
|
+
else
|
69
|
+
x ** n
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# :stopdoc:
|
75
|
+
StandardRounding = rounding # :nodoc:
|
76
|
+
PlusRounding = up { rounding } # :nodoc:
|
77
|
+
MinusRounding = down{ rounding } # :nodoc:
|
78
|
+
|
79
|
+
private_class_method :rounding=, :roundingDown, :roundingUp
|
80
|
+
# :startdoc:
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
require 'test/unit'
|
85
|
+
|
86
|
+
# Tests the FPU rounding modes.
|
87
|
+
class FPU::TestRounding < Test::Unit::TestCase
|
88
|
+
include FPU
|
89
|
+
|
90
|
+
def setup
|
91
|
+
@saved = rounding
|
92
|
+
end
|
93
|
+
|
94
|
+
def teardown
|
95
|
+
self.rounding = @saved
|
96
|
+
end
|
97
|
+
|
98
|
+
# Nearest rounding of 1/3 is downwards.
|
99
|
+
def test_third
|
100
|
+
assert(FPU.down {1/3.0} == 1/3.0, "1/3 to -");
|
101
|
+
assert(FPU.up {1/3.0} != 1/3.0, "1/3 to +");
|
102
|
+
assert(FPU.down {-1/3.0} != -1/3.0, "-1/3 to -");
|
103
|
+
assert(FPU.up {-1/3.0} == -1/3.0, "-1/3 to +");
|
104
|
+
end
|
105
|
+
|
106
|
+
# 1/4 is exact.
|
107
|
+
def test_fourth
|
108
|
+
assert(FPU.down {1/4.0} == 1/4.0, "1/4 to -");
|
109
|
+
assert(FPU.up {1/4.0} == 1/4.0, "1/4 to +");
|
110
|
+
assert(FPU.down {-1/4.0} == -1/4.0, "-1/4 to -");
|
111
|
+
assert(FPU.up {-1/4.0} == -1/4.0, "-1/4 to +");
|
112
|
+
end
|
113
|
+
|
114
|
+
# Nearest rounding of 1/5 is upwards.
|
115
|
+
def test_fifth
|
116
|
+
assert(FPU.down {1/5.0} != 1/5.0, "1/5 to -");
|
117
|
+
assert(FPU.up {1/5.0} == 1/5.0, "1/5 to +");
|
118
|
+
assert(FPU.down {-1/5.0} == -1/5.0, "-1/5 to -");
|
119
|
+
assert(FPU.up {-1/5.0} != -1/5.0, "-1/5 to +");
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_platform
|
123
|
+
modes = case (RUBY_PLATFORM)
|
124
|
+
when /powerpc/ then [0,2,3]
|
125
|
+
when /i[0-9]86/ then [0,0x0800,0x0400]
|
126
|
+
when /sparc/ then [0,0x80000000, 0xC0000000]
|
127
|
+
else flunk("Cannot be sure of the processor flags for platform "+RUBY_PLATFORM)
|
128
|
+
end
|
129
|
+
assert_equal(modes,
|
130
|
+
[rounding, FPU.up { rounding }, FPU.down { rounding }])
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_rounding_consts
|
134
|
+
assert_equal(PlusRounding , FPU.up { FPU.rounding })
|
135
|
+
assert_equal(MinusRounding , FPU.down { FPU.rounding })
|
136
|
+
assert_equal(StandardRounding, rounding)
|
137
|
+
|
138
|
+
tester = proc { |x| assert_equal(x, (self.rounding = x; FPU.rounding))}
|
139
|
+
tester.call(PlusRounding);
|
140
|
+
tester.call(MinusRounding);
|
141
|
+
tester.call(StandardRounding);
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_exception_safety
|
145
|
+
assert_raise(ArgumentError){FPU.up {[2.0, 0/0.0].sort}}
|
146
|
+
assert_equal(StandardRounding, rounding)
|
147
|
+
assert_raise(ArgumentError){FPU.down {[2.0, 0/0.0].sort}}
|
148
|
+
assert_equal(StandardRounding, rounding)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_power
|
152
|
+
x = 1/3.0;
|
153
|
+
# The cube of one third should depend on the rounding mode
|
154
|
+
assert_operator(FPU.down{x*x*x}, :<, FPU.up{x*x*x})
|
155
|
+
# But using the built-in power operator, usually it doesn't
|
156
|
+
# assert_equal(FPU.down{x**3}, FPU.up{x**3})
|
157
|
+
# So we define an integer power methods that does
|
158
|
+
assert_operator(FPU.down{FPU.power(x, 3)}, :<, FPU.up{FPU.power(x, 3)})
|
159
|
+
|
160
|
+
assert_equal(32, FPU.power(2, 5))
|
161
|
+
assert_equal([FPU.down{x*x*x}, FPU.up{x*x*x}],[FPU.down{FPU.power(x, 3)},FPU.up{FPU.power(x, 3)}])
|
162
|
+
assert_equal(1.25 ** 13, FPU.power(1.25, 13))
|
163
|
+
assert_equal((-1.25) ** 17, FPU.power(-1.25, 17))
|
164
|
+
assert_equal((-1.25) ** 18, FPU.power(-1.25, 18))
|
165
|
+
(1..10).each {|i|
|
166
|
+
assert_equal(2.0 ** i, FPU.power(2.0, i))
|
167
|
+
}
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
if !FPU.respond_to?(:exp_up)
|
174
|
+
warn "***\n*** Module fpu is compiled without transcendetal functions\n***"
|
175
|
+
else
|
176
|
+
# Tests the correct-rounding transcendental functions, if they exist.
|
177
|
+
class FPU::TestTranscendental < Test::Unit::TestCase
|
178
|
+
require 'enumerator'
|
179
|
+
|
180
|
+
def locate(name)
|
181
|
+
$LOAD_PATH.
|
182
|
+
map{|p| File.expand_path("../test/#{name}", File.expand_path(p))}.
|
183
|
+
find(proc {raise LoadError, "Cannot locate #{name}"}) {|p|
|
184
|
+
File.exist?(p)
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
@@test_vectors_cache = {}
|
189
|
+
|
190
|
+
def get_vectors (name)
|
191
|
+
@@test_vectors_cache[name] ||= IO.readlines(locate(name)).map{|x|
|
192
|
+
e1,m1,e2,m2 = x.chomp.split(' ').map{|y| y.to_i}
|
193
|
+
[e1,m1,e2,m2,e2,m2 - 1].enum_slice(2).map{|e,m| Math::ldexp(m,e)}}
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_easy
|
197
|
+
a, b, c= [
|
198
|
+
[-1, 1008, 2553927345288884],
|
199
|
+
[1, 1022, 4503168880409012],
|
200
|
+
[1, 1022, 4503168880409011]].map{|x| Struct::Float[*x].to_f}
|
201
|
+
assert_equal(b, FPU.exp_up(a))
|
202
|
+
assert_equal(c, FPU.exp_down(a))
|
203
|
+
|
204
|
+
assert_equal(Infinity, FPU.exp_up(Infinity))
|
205
|
+
assert_equal(Infinity, FPU.exp_down(Infinity))
|
206
|
+
assert_equal(0, FPU.exp_up(-Infinity))
|
207
|
+
assert_equal(0, FPU.exp_down(-Infinity))
|
208
|
+
|
209
|
+
assert_equal(Infinity, FPU.log_up(Infinity))
|
210
|
+
assert_equal(Infinity, FPU.log_down(Infinity))
|
211
|
+
assert_equal(-Infinity, FPU.log_up(0))
|
212
|
+
assert_equal(-Infinity, FPU.log_down(0))
|
213
|
+
|
214
|
+
assert_equal(Math::PI, 2*FPU.atan_down(Infinity))
|
215
|
+
assert_equal(Math::PI+2 ** -51, 2*FPU.atan_up(Infinity))
|
216
|
+
assert_equal(-Math::PI, 2*FPU.atan_up(-Infinity))
|
217
|
+
assert_equal(-Math::PI-2 ** -51, 2*FPU.atan_down(-Infinity))
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_exp
|
221
|
+
get_vectors("data_exp.txt").map{|x,y,z|
|
222
|
+
assert_equal(y, FPU.exp_up(x))
|
223
|
+
assert_equal(z, FPU.exp_down(x))
|
224
|
+
}
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_log
|
228
|
+
get_vectors("data_log.txt").map{|x,y,z|
|
229
|
+
assert_equal(y, FPU.log_up(x))
|
230
|
+
assert_equal(z, FPU.log_down(x))
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_atan
|
235
|
+
get_vectors("data_atan.txt").map{|x,y,z|
|
236
|
+
assert_equal(y, FPU.atan_up(x))
|
237
|
+
assert_equal(z, FPU.atan_down(x))
|
238
|
+
}
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_cos
|
242
|
+
get_vectors("data_cos.txt").map{|x,y,z|
|
243
|
+
assert_equal(y, FPU.cos_up(x))
|
244
|
+
assert_equal(z, FPU.cos_down(x))
|
245
|
+
}
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_sin
|
249
|
+
get_vectors("data_sin.txt").map{|x,y,z|
|
250
|
+
assert_equal(y, FPU.sin_up(x))
|
251
|
+
assert_equal(z, FPU.sin_down(x))
|
252
|
+
}
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_tan
|
256
|
+
get_vectors("data_tan.txt").map{|x,y,z|
|
257
|
+
assert_equal(y, FPU.tan_up(x))
|
258
|
+
assert_equal(z, FPU.tan_down(x))
|
259
|
+
}
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_cosh
|
263
|
+
get_vectors("data_cosh.txt").map{|x,y,z|
|
264
|
+
assert_equal(y, FPU.cosh_up(x))
|
265
|
+
assert_equal(z, FPU.cosh_down(x))
|
266
|
+
}
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_sinh
|
270
|
+
get_vectors("data_sinh.txt").map{|x,y,z|
|
271
|
+
assert_equal(y, FPU.sinh_up(x))
|
272
|
+
assert_equal(z, FPU.sinh_down(x))
|
273
|
+
}
|
274
|
+
end
|
275
|
+
|
276
|
+
# It can happen, depending on the implementation, that Math::sinh is broken
|
277
|
+
def broken_math #:nodoc:
|
278
|
+
x = -8218111829489689 * 2.0 **(-67)
|
279
|
+
y = -8218111833737307 * 2.0 **(-67)
|
280
|
+
assert_equal(y, FPU.sinh_up(x))
|
281
|
+
z = Math::sinh(x);
|
282
|
+
assert(z <= y, [FPU.split(x), FPU.split(z), FPU.split(y)].inspect)
|
283
|
+
end
|
284
|
+
|
285
|
+
end end
|
286
|
+
|
287
|
+
Test::Unit.run = (__FILE__ != $0)
|