flt 1.2.1 → 1.3.0
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/History.txt +10 -0
- data/Manifest.txt +5 -0
- data/README.txt +16 -10
- data/lib/flt/bin_num.rb +4 -0
- data/lib/flt/complex.rb +312 -0
- data/lib/flt/dec_num.rb +0 -21
- data/lib/flt/math.rb +47 -567
- data/lib/flt/num.rb +249 -20
- data/lib/flt/trigonometry.rb +746 -0
- data/lib/flt/version.rb +2 -2
- data/test/generate_trig_data.rb +169 -0
- data/test/test_basic.rb +5 -0
- metadata +11 -4
data/lib/flt/version.rb
CHANGED
@@ -0,0 +1,169 @@
|
|
1
|
+
# Generate test data for trigonometry tests (test_trig.rbG)
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'helper.rb'))
|
4
|
+
require File.dirname(__FILE__) + '/../lib/flt/math'
|
5
|
+
include Flt
|
6
|
+
|
7
|
+
def around(x)
|
8
|
+
[x,x.next_plus,x.next_minus,x.next_plus.next_plus,x.next_minus.next_minus]
|
9
|
+
end
|
10
|
+
|
11
|
+
def near(x)
|
12
|
+
ulp = x.ulp
|
13
|
+
prec = x.num_class.context.precision
|
14
|
+
xs = around(x)
|
15
|
+
[2,3,4].each do |k|
|
16
|
+
d = (prec/k)*ulp
|
17
|
+
xs += around(x-d)
|
18
|
+
xs += around(x+d)
|
19
|
+
end
|
20
|
+
xs.uniq
|
21
|
+
end
|
22
|
+
|
23
|
+
# random angles in radians for sin,cos,tan
|
24
|
+
def angle_data(num_class)
|
25
|
+
xs = []
|
26
|
+
pi = num_class::Math.send(:half_cycle)
|
27
|
+
(-8..8).each do |k|
|
28
|
+
x = k*pi/4
|
29
|
+
xs += near(x)
|
30
|
+
end
|
31
|
+
pi2 = num_class::Math.send(:quarter_cycle)
|
32
|
+
50.times{ xs << random_num_one(num_class)*pi2}
|
33
|
+
base = xs.dup
|
34
|
+
(2...10).each do |k|
|
35
|
+
xs += base.map{|x| x+num_class.int_radix_power(k)}
|
36
|
+
end
|
37
|
+
xs.uniq
|
38
|
+
end
|
39
|
+
|
40
|
+
# random data in [-1,-1] for asin, acos
|
41
|
+
def one_data(num_class)
|
42
|
+
half = num_class.Num(1)/2
|
43
|
+
zero = num_class.Num(0)
|
44
|
+
one = num_class.Num(1)
|
45
|
+
xs = [-one, -half, zero, half, one].map{|x| near(x)}.flatten
|
46
|
+
50.times{ xs << random_num_one(num_class)}
|
47
|
+
xs.uniq.reject{|x| x<-1 || x>1}
|
48
|
+
end
|
49
|
+
|
50
|
+
def random_num_one(num_class=DecNum)
|
51
|
+
context = num_class.context
|
52
|
+
if false # rand(20)==0
|
53
|
+
# generate 5% of subnormals
|
54
|
+
f = rand(context.radix**(context.precision-1))
|
55
|
+
e = context.etiny
|
56
|
+
elsif rand(20)==0
|
57
|
+
# and some singular values too
|
58
|
+
if rand(1) == 0
|
59
|
+
f = context.radix**context.precision - 1
|
60
|
+
f -= rand(3)
|
61
|
+
else
|
62
|
+
f = context.radix**(context.precision - 1)
|
63
|
+
f += rand(3)
|
64
|
+
end
|
65
|
+
# e = random_integer(context.etiny, context.etop)
|
66
|
+
if rand(1)==0
|
67
|
+
e = random_integer(-context.precision-1,-context.precision)
|
68
|
+
else
|
69
|
+
e = random_integer(-context.precision-10,-context.precision)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
f = rand(context.radix**context.precision)
|
73
|
+
# e = random_integer(context.etiny, context.etop)
|
74
|
+
if rand(1)==0
|
75
|
+
e = random_integer(-context.precision-1,-context.precision)
|
76
|
+
else
|
77
|
+
e = random_integer(-context.precision-10,-context.precision)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
# f = -f if rand(1)==0
|
81
|
+
context.Num(f, e)
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def gen_test_data(num_class, prec, angle_units=:rad)
|
86
|
+
dir = File.dirname(__FILE__)+'/trigtest'
|
87
|
+
num_class.context(:precision=>prec) do
|
88
|
+
num_class.context.angle = angle_units
|
89
|
+
DecNum.context.traps[DecNum::DivisionByZero] = false
|
90
|
+
radix = "#{num_class.context.radix}_"
|
91
|
+
units = "_#{num_class.context.angle}"
|
92
|
+
angles = angle_data(num_class)
|
93
|
+
extra_prec = prec + 100
|
94
|
+
extra_elimit = [10000, num_class.context.emax.abs, num_class.context.emin.abs].max
|
95
|
+
File.open("#{dir}/sin#{radix}#{prec}#{units}.txt","w") do |out|
|
96
|
+
angles.each do |angle|
|
97
|
+
result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
|
98
|
+
num_class::Math.sin(angle)
|
99
|
+
}
|
100
|
+
out.puts "#{angle.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
File.open("#{dir}/cos#{radix}#{prec}#{units}.txt","w") do |out|
|
104
|
+
angles.each do |angle|
|
105
|
+
result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
|
106
|
+
num_class::Math.cos(angle)
|
107
|
+
}
|
108
|
+
out.puts "#{angle.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
File.open("#{dir}/tan#{radix}#{prec}#{units}.txt","w") do |out|
|
112
|
+
angles.each do |angle|
|
113
|
+
result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
|
114
|
+
num_class::Math.tan(angle)
|
115
|
+
}
|
116
|
+
out.puts "#{angle.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
xs = one_data(num_class)
|
120
|
+
File.open("#{dir}/asin#{radix}#{prec}#{units}.txt","w") do |out|
|
121
|
+
xs.each do |x|
|
122
|
+
result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
|
123
|
+
num_class::Math.asin(x)
|
124
|
+
}
|
125
|
+
out.puts "#{x.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
File.open("#{dir}/acos#{radix}#{prec}#{units}.txt","w") do |out|
|
129
|
+
xs.each do |x|
|
130
|
+
result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
|
131
|
+
num_class::Math.acos(x)
|
132
|
+
}
|
133
|
+
out.puts "#{x.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
xs += Array.new(100){random_num(num_class)}
|
137
|
+
File.open("#{dir}/atan#{radix}#{prec}#{units}.txt","w") do |out|
|
138
|
+
xs.each do |x|
|
139
|
+
result = +num_class.context(:precision=>extra_prec, :elimit=>extra_elimit) {
|
140
|
+
num_class::Math.atan(x)
|
141
|
+
}
|
142
|
+
out.puts "#{x.to_s(:base=>num_class.radix)}\t#{result.to_s(:base=>num_class.radix)}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
srand 12322
|
149
|
+
gen_test_data DecNum, 12, :rad
|
150
|
+
|
151
|
+
srand 12322
|
152
|
+
gen_test_data DecNum, 12, :deg
|
153
|
+
|
154
|
+
srand 12322
|
155
|
+
BinNum.context = BinNum::IEEEDoubleContext
|
156
|
+
gen_test_data BinNum, 53, :rad
|
157
|
+
|
158
|
+
|
159
|
+
# TODO:
|
160
|
+
# 1. prepare test data for 12, 15, 25, 50 digits with gen_test_data
|
161
|
+
# 2. check with RPL, Mathematica:
|
162
|
+
# programs that process test data and prepare RPL/Mathematica programs that yield results
|
163
|
+
# then check results
|
164
|
+
# RPL: (to be executed in emulator for speed/ease of I/O)
|
165
|
+
# \<< [angle1, angle2, angle3, ...] N \-> D N \<< 1 N FOR I D I GET SIN NEXT N \->LIST \>> |>>
|
166
|
+
# Mathematica:
|
167
|
+
# F[x_]:=N[Sin[x],prec]
|
168
|
+
# Map[F, {angle1.to_r.to_s, angle2.to_r.to_s, ...}]
|
169
|
+
# 3. add special number tests (nans, infinities)
|
data/test/test_basic.rb
CHANGED
@@ -101,6 +101,11 @@ class TestBasic < Test::Unit::TestCase
|
|
101
101
|
}
|
102
102
|
assert_equal 10, DecNum.context.precision
|
103
103
|
|
104
|
+
DecNum.context(:extra_precision=>4) {
|
105
|
+
assert_equal 14, DecNum.context.precision
|
106
|
+
}
|
107
|
+
assert_equal 10, DecNum.context.precision
|
108
|
+
|
104
109
|
DecNum.local_context(DecNum::BasicContext) {
|
105
110
|
assert_equal :half_up, DecNum.context.rounding
|
106
111
|
assert_equal 9, DecNum.context.precision
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 1
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 1.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 1.3.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Javier Goizueta
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-06-
|
18
|
+
date: 2010-06-22 00:00:00 +02:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
@@ -25,6 +26,7 @@ dependencies:
|
|
25
26
|
requirements:
|
26
27
|
- - ">="
|
27
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 9
|
28
30
|
segments:
|
29
31
|
- 2
|
30
32
|
- 1
|
@@ -52,6 +54,7 @@ files:
|
|
52
54
|
- lib/flt/b.rb
|
53
55
|
- lib/flt/bigdecimal.rb
|
54
56
|
- lib/flt/bin_num.rb
|
57
|
+
- lib/flt/complex.rb
|
55
58
|
- lib/flt/d.rb
|
56
59
|
- lib/flt/dec_num.rb
|
57
60
|
- lib/flt/float.rb
|
@@ -61,6 +64,7 @@ files:
|
|
61
64
|
- lib/flt/support.rb
|
62
65
|
- lib/flt/tolerance.rb
|
63
66
|
- lib/flt/tolerance/sugar.rb
|
67
|
+
- lib/flt/trigonometry.rb
|
64
68
|
- lib/flt/version.rb
|
65
69
|
- setup.rb
|
66
70
|
- tasks/ann.rake
|
@@ -77,6 +81,7 @@ files:
|
|
77
81
|
- tasks/svn.rake
|
78
82
|
- tasks/test.rake
|
79
83
|
- test/all_tests.rb
|
84
|
+
- test/generate_trig_data.rb
|
80
85
|
- test/helper.rb
|
81
86
|
- test/reader.rb
|
82
87
|
- test/test_basic.rb
|
@@ -123,6 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
128
|
requirements:
|
124
129
|
- - ">="
|
125
130
|
- !ruby/object:Gem::Version
|
131
|
+
hash: 3
|
126
132
|
segments:
|
127
133
|
- 0
|
128
134
|
version: "0"
|
@@ -131,6 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
137
|
requirements:
|
132
138
|
- - ">="
|
133
139
|
- !ruby/object:Gem::Version
|
140
|
+
hash: 3
|
134
141
|
segments:
|
135
142
|
- 0
|
136
143
|
version: "0"
|