rationalize 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,40 @@
1
+ rationalize - Refinement version of mathn
2
+ =========================================
3
+
4
+ This project aims to provide refinement version of mathn.rb.
5
+
6
+ Install
7
+ ========================
8
+
9
+ $ gem install rationalize
10
+
11
+ Documentation
12
+ ========================
13
+
14
+ * [API Reference](http://rubydoc.info/github/shugo/rationalize/frames)
15
+
16
+ License
17
+ ========================
18
+
19
+ (The MIT License)
20
+
21
+ Copyright (c) 2012 Shugo Maeda
22
+
23
+ Permission is hereby granted, free of charge, to any person obtaining
24
+ a copy of this software and associated documentation files (the
25
+ 'Software'), to deal in the Software without restriction, including
26
+ without limitation the rights to use, copy, modify, merge, publish,
27
+ distribute, sublicense, and/or sell copies of the Software, and to
28
+ permit persons to whom the Software is furnished to do so, subject to
29
+ the following conditions:
30
+
31
+ The above copyright notice and this permission notice shall be
32
+ included in all copies or substantial portions of the Software.
33
+
34
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
35
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
37
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
38
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
39
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
40
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,203 @@
1
+ require "cmath"
2
+ require "matrix"
3
+ require "prime"
4
+
5
+ #require "mathn/rational"
6
+ #require "mathn/complex"
7
+
8
+ # +Rationalize+ is a refinement version of mathn.
9
+ #
10
+ # @example
11
+ #
12
+ # p 1 / 3 #=> 0
13
+ # class Foo
14
+ # using Rationalize
15
+ # p 1 / 3 #=> (1/3)
16
+ # end
17
+ # p 1 / 3 #=> 0
18
+ # p Rationalize.sqrt(Rational(9, 4)) #=> (3/2)
19
+ module Rationalize
20
+ include CMath
21
+ extend CMath
22
+
23
+ refine Module do
24
+ def define_alias(mid, original)
25
+ define_method(mid) do |*args, &block|
26
+ send(original, *args, &block)
27
+ end
28
+ end
29
+ end
30
+
31
+ refine Fixnum do
32
+ define_alias :/, :quo
33
+ define_alias :power!, :**
34
+
35
+ def ** (other)
36
+ if self < 0 && other.round != other
37
+ Complex(self, 0.0) ** other
38
+ else
39
+ power!(other)
40
+ end
41
+ end
42
+ end
43
+
44
+ refine Bignum do
45
+ define_alias :/, :quo
46
+ define_alias :power!, :**
47
+
48
+ def ** (other)
49
+ if self < 0 && other.round != other
50
+ Complex(self, 0.0) ** other
51
+ else
52
+ power!(other)
53
+ end
54
+ end
55
+ end
56
+
57
+ refine Rational do
58
+ def ** (other)
59
+ if other.kind_of?(Rational)
60
+ other2 = other
61
+ if self < 0
62
+ return Complex(self, 0.0) ** other
63
+ elsif other == 0
64
+ return Rational(1,1)
65
+ elsif self == 0
66
+ return Rational(0,1)
67
+ elsif self == 1
68
+ return Rational(1,1)
69
+ end
70
+
71
+ npd = numerator.prime_division
72
+ dpd = denominator.prime_division
73
+ if other < 0
74
+ other = -other
75
+ npd, dpd = dpd, npd
76
+ end
77
+
78
+ for elm in npd
79
+ elm[1] = elm[1] * other
80
+ if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
81
+ return Float(self) ** other2
82
+ end
83
+ elm[1] = elm[1].to_i
84
+ end
85
+
86
+ for elm in dpd
87
+ elm[1] = elm[1] * other
88
+ if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
89
+ return Float(self) ** other2
90
+ end
91
+ elm[1] = elm[1].to_i
92
+ end
93
+
94
+ num = Integer.from_prime_division(npd)
95
+ den = Integer.from_prime_division(dpd)
96
+
97
+ Rational(num,den)
98
+
99
+ elsif other.kind_of?(Integer)
100
+ if other > 0
101
+ num = numerator ** other
102
+ den = denominator ** other
103
+ elsif other < 0
104
+ num = denominator ** -other
105
+ den = numerator ** -other
106
+ elsif other == 0
107
+ num = 1
108
+ den = 1
109
+ end
110
+ Rational(num, den)
111
+ elsif other.kind_of?(Float)
112
+ Float(self) ** other
113
+ else
114
+ x , y = other.coerce(self)
115
+ x ** y
116
+ end
117
+ end
118
+ end
119
+
120
+ refine Float do
121
+ define_alias :power!, :**
122
+
123
+ def ** (other)
124
+ if self < 0 && other.round != other
125
+ Complex(self, 0.0) ** other
126
+ else
127
+ power!(other)
128
+ end
129
+ end
130
+ end
131
+
132
+ def sqrt(a)
133
+ if a.kind_of?(Complex)
134
+ abs = sqrt(a.real*a.real + a.imag*a.imag)
135
+ # if not abs.kind_of?(Rational)
136
+ # return a**Rational(1,2)
137
+ # end
138
+ x = sqrt((a.real + abs)/Rational(2))
139
+ y = sqrt((-a.real + abs)/Rational(2))
140
+ # if !(x.kind_of?(Rational) and y.kind_of?(Rational))
141
+ # return a**Rational(1,2)
142
+ # end
143
+ if a.imag >= 0
144
+ Complex(x, y)
145
+ else
146
+ Complex(x, -y)
147
+ end
148
+ elsif a.respond_to?(:nan?) and a.nan?
149
+ a
150
+ elsif a >= 0
151
+ rsqrt(a)
152
+ else
153
+ Complex(0,rsqrt(-a))
154
+ end
155
+ end
156
+
157
+ def rsqrt(a)
158
+ if a.kind_of?(Float)
159
+ sqrt!(a)
160
+ elsif a.kind_of?(Rational)
161
+ rsqrt(a.numerator)/rsqrt(a.denominator)
162
+ else
163
+ src = a
164
+ max = 2 ** 32
165
+ byte_a = [src & 0xffffffff]
166
+ # ruby's bug
167
+ while (src >= max) and (src >>= 32)
168
+ byte_a.unshift src & 0xffffffff
169
+ end
170
+
171
+ answer = 0
172
+ main = 0
173
+ side = 0
174
+ for elm in byte_a
175
+ main = (main << 32) + elm
176
+ side <<= 16
177
+ if answer != 0
178
+ if main * 4 < side * side
179
+ applo = main.div(side)
180
+ else
181
+ applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
182
+ end
183
+ else
184
+ applo = sqrt!(main).to_i + 1
185
+ end
186
+
187
+ while (x = (side + applo) * applo) > main
188
+ applo -= 1
189
+ end
190
+ main -= x
191
+ answer = (answer << 16) + applo
192
+ side += applo * 2
193
+ end
194
+ if main == 0
195
+ answer
196
+ else
197
+ sqrt!(a)
198
+ end
199
+ end
200
+ end
201
+
202
+ module_function :sqrt, :rsqrt
203
+ end
@@ -0,0 +1,3 @@
1
+ $VERBOSE = true
2
+
3
+ require "test/unit"
@@ -0,0 +1,21 @@
1
+ require_relative "test_helper"
2
+
3
+ require_relative "../lib/rationalize"
4
+
5
+ class TestRationalize < Test::Unit::TestCase
6
+ def test_fixnum_slash
7
+ assert_equal(0, 0 / 3)
8
+ assert_equal(0, 1 / 3)
9
+ assert_equal(1, 3 / 3)
10
+
11
+ using Rationalize
12
+
13
+ assert_equal(Rational(0, 3), 0 / 3)
14
+ assert_equal(Rational(1, 3), 1 / 3)
15
+ assert_equal(Rational(3, 3), 3 / 3)
16
+ end
17
+
18
+ def test_sqrt
19
+ assert_equal(Rational(2, 3), Rationalize.sqrt(Rational(4, 9)))
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rationalize
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Shugo Maeda
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-10-01 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description:
17
+ email: shugo@ruby-lang.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/rationalize.rb
26
+ - test/test_helper.rb
27
+ - test/test_rationalize.rb
28
+ - README.md
29
+ homepage: http://github.com/shugo/rationalize
30
+ licenses: []
31
+
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ requirements: []
50
+
51
+ rubyforge_project:
52
+ rubygems_version: 1.8.15
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: Refinement version of mathn
56
+ test_files: []
57
+