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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 467e937606c8e419d779633cb724dd5327bfeeff
4
- data.tar.gz: 1bcc431f67bb1a5581d5574aa816a7a58eea7971
3
+ metadata.gz: 2c8f404bbf236fce57e1e6de091af800546663ff
4
+ data.tar.gz: dd52a75c76ebd8bbc4f8bfbcf23a6cff75b5fbc6
5
5
  SHA512:
6
- metadata.gz: d3d2f5ab89cab030c46699a7500a816980b5742b6148bb50c63c74cd4cf9bff608e4f520dcd416dd0a1f285251325ece2b646e81675d34447099b29e41ff2d22
7
- data.tar.gz: 7f4f2d6254a66cdb96c398e8800f11d7da0440680ce5dce5591874cf27d9edef8be03a73182696e0464c9082cb9a3575298b4d62dc86189ecab6715146391f9f
6
+ metadata.gz: de4d0b8516c0e11d67c45b04c654b10b68768807993354eeef2fb47a32f26608d18a93ebee4516cd50f80611f6cdb8d55a40c7088c854f71aa05dd52ee40b8d3
7
+ data.tar.gz: f62b3e29787871eb7b598fea8603a408e5e04b4a8bc4ec1ca67143ecb3974a32c383a2f83aa39b7e656443aee8a9107a766b7fb5038caf3c9e275a15bb118afd
@@ -1,8 +1,7 @@
1
1
  language: ruby
2
- before_install:
3
- - gem update --system
4
- - gem --version
5
- - gem install rubysl-bundler
6
- script: bundle exec mspec spec
2
+ env:
3
+ - RUBYLIB=lib
4
+ script: bundle exec mspec
7
5
  rvm:
8
- - rbx-nightly-18mode
6
+ - 1.9.3
7
+ - rbx-nightly-19mode
@@ -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
- # mathn.rb -
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
- require "complex.rb"
14
- require "rational.rb"
15
- require "matrix.rb"
41
+ class Numeric; end
16
42
 
17
- class Integer
43
+ require "cmath.rb"
44
+ require "matrix.rb"
45
+ require "prime.rb"
18
46
 
19
- def gcd2(int)
20
- a = self.abs
21
- b = int.abs
22
- a, b = b, a if a < b
47
+ unless defined?(Math.exp!)
48
+ Object.instance_eval{remove_const :Math}
49
+ Math = CMath # :nodoc:
50
+ end
23
51
 
24
- pd_a = a.prime_division
25
- pd_b = b.prime_division
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
- gcd = 1
28
- for pair in pd_a
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
- def Integer.from_prime_division(pd)
38
- value = 1
39
- for prime, index in pd
40
- value *= prime**index
41
- end
42
- value
43
- end
63
+ ##
64
+ # +/+ defines the Rational division for Fixnum.
65
+ #
66
+ # 1/3 # => (1/3)
44
67
 
45
- def prime_division
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
- class Prime
75
- include Enumerable
70
+ alias power! ** unless method_defined? :power!
76
71
 
77
- def initialize
78
- @seed = 1
79
- @primes = []
80
- @counts = []
81
- end
72
+ ##
73
+ # Exponentiate by +other+
82
74
 
83
- def succ
84
- i = -1
85
- size = @primes.size
86
- while i < size
87
- if i == -1
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
- class Fixnum
115
- alias / quo
116
- end
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
- alias / quo
120
- end
90
+ remove_method :/
121
91
 
122
- class Rational
123
- Unify = true
92
+ ##
93
+ # +/+ defines the Rational division for Bignum.
94
+ #
95
+ # (2**72) / ((2**70) * 3) # => 4/3
124
96
 
125
- def inspect
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
- def ** (other)
132
- if other.kind_of?(Rational)
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
- npd = numerator.prime_division
145
- dpd = denominator.prime_division
146
- if other < 0
147
- other = -other
148
- npd, dpd = dpd, npd
149
- end
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
- for elm in npd
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
- for elm in dpd
160
- elm[1] = elm[1] * other
161
- if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
162
- return Float(self) ** other2
163
- end
164
- elm[1] = elm[1].to_i
165
- end
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
- num = Integer.from_prime_division(npd)
168
- den = Integer.from_prime_division(dpd)
169
-
170
- Rational(num,den)
171
-
172
- elsif other.kind_of?(Integer)
173
- if other > 0
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 power2(other)
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
- dem = nil
205
- x = self.denominator.to_f.to_i
206
- neard = self.denominator.to_f ** (1.0/other.denominator.to_f)
207
- loop do
208
- if (neard**other.denominator == self.denominator)
209
- dem = neaed
210
- break
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
- nearn = self.numerator.to_f ** (1.0/other.denominator.to_f)
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.new!(num, den)
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.image*a.image)
241
- # if not abs.kind_of?(Rational)
242
- # return a**Rational(1,2)
243
- # end
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
- # if !(x.kind_of?(Rational) and y.kind_of?(Rational))
247
- # return a**Rational(1,2)
248
- # end
249
- if a.image >= 0
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
- class Complex
311
- Unify = true
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
@@ -1,5 +1,5 @@
1
1
  module RubySL
2
2
  module Mathn
3
- VERSION = "1.0.0"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
@@ -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
- spec.add_development_dependency "rubysl-prettyprint", "~> 1.0"
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: 1.0.0
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-16 00:00:00.000000000 Z
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.3
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: