rubysl-mathn 1.0.0 → 2.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -6
- data/lib/rubysl/mathn/mathn.rb +195 -181
- data/lib/rubysl/mathn/version.rb +1 -1
- data/rubysl-mathn.gemspec +1 -2
- metadata +3 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c8f404bbf236fce57e1e6de091af800546663ff
|
4
|
+
data.tar.gz: dd52a75c76ebd8bbc4f8bfbcf23a6cff75b5fbc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de4d0b8516c0e11d67c45b04c654b10b68768807993354eeef2fb47a32f26608d18a93ebee4516cd50f80611f6cdb8d55a40c7088c854f71aa05dd52ee40b8d3
|
7
|
+
data.tar.gz: f62b3e29787871eb7b598fea8603a408e5e04b4a8bc4ec1ca67143ecb3974a32c383a2f83aa39b7e656443aee8a9107a766b7fb5038caf3c9e275a15bb118afd
|
data/.travis.yml
CHANGED
data/lib/rubysl/mathn/mathn.rb
CHANGED
@@ -1,198 +1,142 @@
|
|
1
|
+
#--
|
2
|
+
# $Release Version: 0.5 $
|
3
|
+
# $Revision: 1.1.1.1.4.1 $
|
4
|
+
|
5
|
+
##
|
6
|
+
# = mathn
|
7
|
+
#
|
8
|
+
# mathn is a library for changing the way Ruby does math. If you need
|
9
|
+
# more precise rounding with multiple division or exponentiation
|
10
|
+
# operations, then mathn is the right tool.
|
11
|
+
#
|
12
|
+
# Without mathn:
|
13
|
+
#
|
14
|
+
# 3 / 2 => 1 # Integer
|
15
|
+
#
|
16
|
+
# With mathn:
|
17
|
+
#
|
18
|
+
# 3 / 2 => 3/2 # Rational
|
1
19
|
#
|
2
|
-
#
|
3
|
-
# $Release Version: 0.5 $
|
4
|
-
# $Revision: 1.1.1.1.4.1 $
|
5
|
-
# $Date: 1998/01/16 12:36:05 $
|
6
|
-
# by Keiju ISHITSUKA(SHL Japan Inc.)
|
20
|
+
# mathn features late rounding and lacks truncation of intermediate results:
|
7
21
|
#
|
8
|
-
#
|
22
|
+
# Without mathn:
|
9
23
|
#
|
24
|
+
# 20 / 9 * 3 * 14 / 7 * 3 / 2 # => 18
|
10
25
|
#
|
26
|
+
# With mathn:
|
11
27
|
#
|
28
|
+
# 20 / 9 * 3 * 14 / 7 * 3 / 2 # => 20
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# When you require 'mathn', the libraries for Prime, CMath, Matrix and Vector
|
32
|
+
# are also loaded.
|
33
|
+
#
|
34
|
+
# == Copyright
|
35
|
+
#
|
36
|
+
# Author: Keiju ISHITSUKA (SHL Japan Inc.)
|
37
|
+
#--
|
38
|
+
# class Numeric follows to make this documentation findable in a reasonable
|
39
|
+
# location
|
12
40
|
|
13
|
-
|
14
|
-
require "rational.rb"
|
15
|
-
require "matrix.rb"
|
41
|
+
class Numeric; end
|
16
42
|
|
17
|
-
|
43
|
+
require "cmath.rb"
|
44
|
+
require "matrix.rb"
|
45
|
+
require "prime.rb"
|
18
46
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
47
|
+
unless defined?(Math.exp!)
|
48
|
+
Object.instance_eval{remove_const :Math}
|
49
|
+
Math = CMath # :nodoc:
|
50
|
+
end
|
23
51
|
|
24
|
-
|
25
|
-
|
52
|
+
##
|
53
|
+
# When mathn is required, Fixnum's division and exponentiation are enhanced to
|
54
|
+
# return more precise values from mathematical expressions.
|
55
|
+
#
|
56
|
+
# 2/3*3 # => 0
|
57
|
+
# require 'mathn'
|
58
|
+
# 2/3*3 # => 2
|
26
59
|
|
27
|
-
|
28
|
-
|
29
|
-
as = pd_b.assoc(pair[0])
|
30
|
-
if as
|
31
|
-
gcd *= as[0] ** [as[1], pair[1]].min
|
32
|
-
end
|
33
|
-
end
|
34
|
-
return gcd
|
35
|
-
end
|
60
|
+
class Fixnum
|
61
|
+
remove_method :/
|
36
62
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
value
|
43
|
-
end
|
63
|
+
##
|
64
|
+
# +/+ defines the Rational division for Fixnum.
|
65
|
+
#
|
66
|
+
# 1/3 # => (1/3)
|
44
67
|
|
45
|
-
|
46
|
-
raise ZeroDivisionError if self == 0
|
47
|
-
ps = Prime.new
|
48
|
-
value = self
|
49
|
-
if value < 0
|
50
|
-
value = -value
|
51
|
-
pv = [[-1, 1]]
|
52
|
-
else
|
53
|
-
pv = []
|
54
|
-
end
|
55
|
-
for prime in ps
|
56
|
-
count = 0
|
57
|
-
while (value1, mod = value.divmod(prime)
|
58
|
-
mod) == 0
|
59
|
-
value = value1
|
60
|
-
count += 1
|
61
|
-
end
|
62
|
-
if count != 0
|
63
|
-
pv.push [prime, count]
|
64
|
-
end
|
65
|
-
break if prime * prime >= value
|
66
|
-
end
|
67
|
-
if value > 1
|
68
|
-
pv.push [value, 1]
|
69
|
-
end
|
70
|
-
return pv
|
71
|
-
end
|
72
|
-
end
|
68
|
+
alias / quo
|
73
69
|
|
74
|
-
|
75
|
-
include Enumerable
|
70
|
+
alias power! ** unless method_defined? :power!
|
76
71
|
|
77
|
-
|
78
|
-
|
79
|
-
@primes = []
|
80
|
-
@counts = []
|
81
|
-
end
|
72
|
+
##
|
73
|
+
# Exponentiate by +other+
|
82
74
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
@seed += 1
|
89
|
-
i += 1
|
90
|
-
else
|
91
|
-
while @seed > @counts[i]
|
92
|
-
@counts[i] += @primes[i]
|
93
|
-
end
|
94
|
-
if @seed != @counts[i]
|
95
|
-
i += 1
|
96
|
-
else
|
97
|
-
i = -1
|
98
|
-
end
|
99
|
-
end
|
75
|
+
def ** (other)
|
76
|
+
if self < 0 && other.round != other
|
77
|
+
Complex(self, 0.0) ** other
|
78
|
+
else
|
79
|
+
power!(other)
|
100
80
|
end
|
101
|
-
@primes.push @seed
|
102
|
-
@counts.push @seed + @seed
|
103
|
-
return @seed
|
104
81
|
end
|
105
|
-
alias next succ
|
106
82
|
|
107
|
-
def each
|
108
|
-
loop do
|
109
|
-
yield succ
|
110
|
-
end
|
111
|
-
end
|
112
83
|
end
|
113
84
|
|
114
|
-
|
115
|
-
|
116
|
-
|
85
|
+
##
|
86
|
+
# When mathn is required Bignum's division and exponentiation are enhanced to
|
87
|
+
# return more precise values from mathematical expressions.
|
117
88
|
|
118
89
|
class Bignum
|
119
|
-
|
120
|
-
end
|
90
|
+
remove_method :/
|
121
91
|
|
122
|
-
|
123
|
-
|
92
|
+
##
|
93
|
+
# +/+ defines the Rational division for Bignum.
|
94
|
+
#
|
95
|
+
# (2**72) / ((2**70) * 3) # => 4/3
|
124
96
|
|
125
|
-
|
126
|
-
format "%s/%s", numerator.inspect, denominator.inspect
|
127
|
-
end
|
97
|
+
alias / quo
|
128
98
|
|
129
|
-
alias power! **
|
99
|
+
alias power! ** unless method_defined? :power!
|
130
100
|
|
131
|
-
|
132
|
-
|
133
|
-
other2 = other
|
134
|
-
if self < 0
|
135
|
-
return Complex.new!(self, 0) ** other
|
136
|
-
elsif other == 0
|
137
|
-
return Rational(1,1)
|
138
|
-
elsif self == 0
|
139
|
-
return Rational(0,1)
|
140
|
-
elsif self == 1
|
141
|
-
return Rational(1,1)
|
142
|
-
end
|
101
|
+
##
|
102
|
+
# Exponentiate by +other+
|
143
103
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
104
|
+
def ** (other)
|
105
|
+
if self < 0 && other.round != other
|
106
|
+
Complex(self, 0.0) ** other
|
107
|
+
else
|
108
|
+
power!(other)
|
109
|
+
end
|
110
|
+
end
|
150
111
|
|
151
|
-
|
152
|
-
elm[1] = elm[1] * other
|
153
|
-
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
|
154
|
-
return Float(self) ** other2
|
155
|
-
end
|
156
|
-
elm[1] = elm[1].to_i
|
157
|
-
end
|
112
|
+
end
|
158
113
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
114
|
+
##
|
115
|
+
# When mathn is required Rational is changed to simplify the use of Rational
|
116
|
+
# operations.
|
117
|
+
#
|
118
|
+
# Normal behaviour:
|
119
|
+
#
|
120
|
+
# Rational.new!(1,3) ** 2 # => Rational(1, 9)
|
121
|
+
# (1 / 3) ** 2 # => 0
|
122
|
+
#
|
123
|
+
# require 'mathn' behaviour:
|
124
|
+
#
|
125
|
+
# (1 / 3) ** 2 # => 1/9
|
166
126
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
num = numerator ** other
|
175
|
-
den = denominator ** other
|
176
|
-
elsif other < 0
|
177
|
-
num = denominator ** -other
|
178
|
-
den = numerator ** -other
|
179
|
-
elsif other == 0
|
180
|
-
num = 1
|
181
|
-
den = 1
|
182
|
-
end
|
183
|
-
Rational.new!(num, den)
|
184
|
-
elsif other.kind_of?(Float)
|
185
|
-
Float(self) ** other
|
186
|
-
else
|
187
|
-
x , y = other.coerce(self)
|
188
|
-
x ** y
|
189
|
-
end
|
190
|
-
end
|
127
|
+
class Rational
|
128
|
+
remove_method :**
|
129
|
+
|
130
|
+
##
|
131
|
+
# Exponentiate by +other+
|
132
|
+
#
|
133
|
+
# (1/3) ** 2 # => 1/9
|
191
134
|
|
192
|
-
def
|
135
|
+
def ** (other)
|
193
136
|
if other.kind_of?(Rational)
|
137
|
+
other2 = other
|
194
138
|
if self < 0
|
195
|
-
return Complex(self, 0) ** other
|
139
|
+
return Complex(self, 0.0) ** other
|
196
140
|
elsif other == 0
|
197
141
|
return Rational(1,1)
|
198
142
|
elsif self == 0
|
@@ -201,16 +145,32 @@ class Rational
|
|
201
145
|
return Rational(1,1)
|
202
146
|
end
|
203
147
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
148
|
+
npd = numerator.prime_division
|
149
|
+
dpd = denominator.prime_division
|
150
|
+
if other < 0
|
151
|
+
other = -other
|
152
|
+
npd, dpd = dpd, npd
|
153
|
+
end
|
154
|
+
|
155
|
+
for elm in npd
|
156
|
+
elm[1] = elm[1] * other
|
157
|
+
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
|
158
|
+
return Float(self) ** other2
|
211
159
|
end
|
160
|
+
elm[1] = elm[1].to_i
|
212
161
|
end
|
213
|
-
|
162
|
+
|
163
|
+
for elm in dpd
|
164
|
+
elm[1] = elm[1] * other
|
165
|
+
if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
|
166
|
+
return Float(self) ** other2
|
167
|
+
end
|
168
|
+
elm[1] = elm[1].to_i
|
169
|
+
end
|
170
|
+
|
171
|
+
num = Integer.from_prime_division(npd)
|
172
|
+
den = Integer.from_prime_division(dpd)
|
173
|
+
|
214
174
|
Rational(num,den)
|
215
175
|
|
216
176
|
elsif other.kind_of?(Integer)
|
@@ -224,7 +184,7 @@ class Rational
|
|
224
184
|
num = 1
|
225
185
|
den = 1
|
226
186
|
end
|
227
|
-
Rational
|
187
|
+
Rational(num, den)
|
228
188
|
elsif other.kind_of?(Float)
|
229
189
|
Float(self) ** other
|
230
190
|
else
|
@@ -234,23 +194,50 @@ class Rational
|
|
234
194
|
end
|
235
195
|
end
|
236
196
|
|
197
|
+
##
|
198
|
+
# When mathn is required, the Math module changes as follows:
|
199
|
+
#
|
200
|
+
# Standard Math module behaviour:
|
201
|
+
# Math.sqrt(4/9) # => 0.0
|
202
|
+
# Math.sqrt(4.0/9.0) # => 0.666666666666667
|
203
|
+
# Math.sqrt(- 4/9) # => Errno::EDOM: Numerical argument out of domain - sqrt
|
204
|
+
#
|
205
|
+
# After require 'mathn', this is changed to:
|
206
|
+
#
|
207
|
+
# require 'mathn'
|
208
|
+
# Math.sqrt(4/9) # => 2/3
|
209
|
+
# Math.sqrt(4.0/9.0) # => 0.666666666666667
|
210
|
+
# Math.sqrt(- 4/9) # => Complex(0, 2/3)
|
211
|
+
|
237
212
|
module Math
|
213
|
+
remove_method(:sqrt)
|
214
|
+
|
215
|
+
##
|
216
|
+
# Computes the square root of +a+. It makes use of Complex and
|
217
|
+
# Rational to have no rounding errors if possible.
|
218
|
+
#
|
219
|
+
# Math.sqrt(4/9) # => 2/3
|
220
|
+
# Math.sqrt(- 4/9) # => Complex(0, 2/3)
|
221
|
+
# Math.sqrt(4.0/9.0) # => 0.666666666666667
|
222
|
+
|
238
223
|
def sqrt(a)
|
239
224
|
if a.kind_of?(Complex)
|
240
|
-
abs = sqrt(a.real*a.real + a.
|
241
|
-
|
242
|
-
|
243
|
-
|
225
|
+
abs = sqrt(a.real*a.real + a.imag*a.imag)
|
226
|
+
# if not abs.kind_of?(Rational)
|
227
|
+
# return a**Rational(1,2)
|
228
|
+
# end
|
244
229
|
x = sqrt((a.real + abs)/Rational(2))
|
245
230
|
y = sqrt((-a.real + abs)/Rational(2))
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
if a.
|
231
|
+
# if !(x.kind_of?(Rational) and y.kind_of?(Rational))
|
232
|
+
# return a**Rational(1,2)
|
233
|
+
# end
|
234
|
+
if a.imag >= 0
|
250
235
|
Complex(x, y)
|
251
236
|
else
|
252
237
|
Complex(x, -y)
|
253
238
|
end
|
239
|
+
elsif a.respond_to?(:nan?) and a.nan?
|
240
|
+
a
|
254
241
|
elsif a >= 0
|
255
242
|
rsqrt(a)
|
256
243
|
else
|
@@ -258,6 +245,10 @@ module Math
|
|
258
245
|
end
|
259
246
|
end
|
260
247
|
|
248
|
+
##
|
249
|
+
# Compute square root of a non negative number. This method is
|
250
|
+
# internally used by +Math.sqrt+.
|
251
|
+
|
261
252
|
def rsqrt(a)
|
262
253
|
if a.kind_of?(Float)
|
263
254
|
sqrt!(a)
|
@@ -303,11 +294,34 @@ module Math
|
|
303
294
|
end
|
304
295
|
end
|
305
296
|
|
297
|
+
class << self
|
298
|
+
remove_method(:sqrt)
|
299
|
+
end
|
306
300
|
module_function :sqrt
|
307
301
|
module_function :rsqrt
|
308
302
|
end
|
309
303
|
|
310
|
-
|
311
|
-
|
304
|
+
##
|
305
|
+
# When mathn is required, Float is changed to handle Complex numbers.
|
306
|
+
|
307
|
+
class Float
|
308
|
+
alias power! **
|
309
|
+
|
310
|
+
##
|
311
|
+
# Exponentiate by +other+
|
312
|
+
|
313
|
+
def ** (other)
|
314
|
+
if self < 0 && other.round != other
|
315
|
+
Complex(self, 0.0) ** other
|
316
|
+
else
|
317
|
+
power!(other)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
312
321
|
end
|
313
322
|
|
323
|
+
module Rubinius
|
324
|
+
def self.mathn_loaded?
|
325
|
+
true
|
326
|
+
end
|
327
|
+
end
|
data/lib/rubysl/mathn/version.rb
CHANGED
data/rubysl-mathn.gemspec
CHANGED
@@ -19,5 +19,4 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.add_development_dependency "bundler", "~> 1.3"
|
20
20
|
spec.add_development_dependency "rake", "~> 10.0"
|
21
21
|
spec.add_development_dependency "mspec", "~> 1.5"
|
22
|
-
|
23
|
-
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubysl-mathn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Shirai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.5'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rubysl-prettyprint
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ~>
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.0'
|
69
55
|
description: Ruby standard library mathn.
|
70
56
|
email:
|
71
57
|
- brixen@gmail.com
|
@@ -122,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
108
|
version: '0'
|
123
109
|
requirements: []
|
124
110
|
rubyforge_project:
|
125
|
-
rubygems_version: 2.0.
|
111
|
+
rubygems_version: 2.0.7
|
126
112
|
signing_key:
|
127
113
|
specification_version: 4
|
128
114
|
summary: Ruby standard library mathn.
|
@@ -145,4 +131,3 @@ test_files:
|
|
145
131
|
- spec/rational/Rational_spec.rb
|
146
132
|
- spec/rational/exponent_spec.rb
|
147
133
|
- spec/rational/inspect_spec.rb
|
148
|
-
has_rdoc:
|