quadratic_number 0.0.1 → 0.0.2

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: 705d8a42df709867ad6b91d3640cef83984ef48b
4
- data.tar.gz: 34a4ac05039bdbbc0a79b8b5d3b3f3e9a22a9fd0
3
+ metadata.gz: 592839e562c20b3ad315b30b1d4b6806b87610fd
4
+ data.tar.gz: 7f5bc9f6afdd48da7aa698be16a1f9914ad8ce72
5
5
  SHA512:
6
- metadata.gz: a324310465b08035e341a90d58fe1eefcfa89fce53c2e16384794090a7a1cc8c78f6d628dcaeede2e39d9d0c7b63f545443618c31b597596075344e361de9165
7
- data.tar.gz: 29bd1b248cffc3b4fb7678ae609186323fd30851bac9fec0414e116981b40cd7f408f0d26fb9b93216cb66acceaac76fe732f76d952266ada9cbde0f64b5e408
6
+ metadata.gz: b3a2450f1d646157ea8fb744f9d6327967bbba6c949f7d75d4c0a53cd20d54d49f5d613df04feb590aa4842ccf8ca3fffe34a4bf87acea2d81d82b18fab5354c
7
+ data.tar.gz: 4daf1c009dd3c709aee9cb14a76f783f3f46778e55f9a28f4d20c75c6195bdba129299ad1a6b1f2338a5cb7b680d42bb8b8d84f7ca8d440b660093563654eb8b
@@ -1,11 +1,20 @@
1
1
  require_relative '../quadratic_number'
2
2
 
3
- class Quadratic::Imag # < Quadratic < Numeric
3
+ ##
4
+ # Abstract class for <tt>Quadratic[d]</tt> (d < 0).
5
+ #
6
+ # Instances behave like those of <tt>Complex</tt>.
7
+ # See <tt>#to_c</tt> for details of the complex expression.
8
+ #
9
+ class Quadratic::Imag
4
10
  ### Classification ###
5
11
 
6
12
  # defined by Numeric:
7
13
  # * integer? #=> false
8
14
 
15
+ ##
16
+ # Returns false.
17
+ #
9
18
  def real?
10
19
  false
11
20
  end
@@ -19,6 +28,11 @@ class Quadratic::Imag # < Quadratic < Numeric
19
28
 
20
29
  undef <=>
21
30
  undef_method(*Comparable.public_instance_methods(false))
31
+
32
+ ##
33
+ # @param [Object] other
34
+ # @return [Boolean]
35
+ #
22
36
  def ==(other)
23
37
  if other.kind_of?(Numeric)
24
38
  self.to_c - other == 0
@@ -35,6 +49,18 @@ class Quadratic::Imag # < Quadratic < Numeric
35
49
 
36
50
  ### Type conversions ###
37
51
 
52
+ ##
53
+ # Returns an equivalent complex.
54
+ # Its imaginary part is usually a <tt>Quadratic::Real</tt>.
55
+ #
56
+ # @return [Complex]
57
+ #
58
+ # @example
59
+ # Quadratic[-3].new(1, 2) #=> (1+2√-3)
60
+ # Quadratic[-3].new(1, 2).to_c #=> (1+(0+2√3)*i)
61
+ # Quadratic[-1].new(3, 4) #=> (3+4√-1)
62
+ # Quadratic[-1].new(3, 4).to_c #=> (3+4i)
63
+ #
38
64
  def to_c
39
65
  d = self.class::D
40
66
  if d == -1
@@ -45,6 +71,31 @@ class Quadratic::Imag # < Quadratic < Numeric
45
71
  end
46
72
  end
47
73
 
74
+ ##
75
+ # @!method to_f
76
+ # @return [Float]
77
+ # @raise [RangeError] if its imaginary part is not zero.
78
+ #
79
+
80
+ ##
81
+ # @!method to_r
82
+ # @return [Rational]
83
+ # @raise [RangeError] if its imaginary part is not zero.
84
+ #
85
+
86
+ ##
87
+ # @!method rationalize(eps)
88
+ # @param [Numeric] eps
89
+ # @return [Rational]
90
+ # @raise [RangeError] if its imaginary part is not zero.
91
+ #
92
+
93
+ ##
94
+ # @!method to_i
95
+ # @return [Integer]
96
+ # @raise [RangeError] if its imaginary part is not zero.
97
+ #
98
+
48
99
  {
49
100
  :to_f => Float,
50
101
  :to_r => Rational,
@@ -66,6 +117,36 @@ class Quadratic::Imag # < Quadratic < Numeric
66
117
  alias conjugate conj
67
118
  alias abs2 norm
68
119
 
120
+ ##
121
+ # @!method rect
122
+ # @return [[Integer/Rational, Quadratic[-d]]]
123
+ #
124
+
125
+ ##
126
+ # @!method real
127
+ # @return [Integer/Rational]
128
+ #
129
+
130
+ ##
131
+ # @!method imag
132
+ # @return [Quadratic[-d]]
133
+ #
134
+
135
+ ##
136
+ # @!method abs
137
+ # @return [Real]
138
+ #
139
+
140
+ ##
141
+ # @!method arg
142
+ # @return [Real]
143
+ #
144
+
145
+ ##
146
+ # @!method polar
147
+ # @return [[Real, Real]]
148
+ #
149
+
69
150
  [:rect, :real, :imag, :abs, :arg, :polar].each do |sym|
70
151
  define_method(sym) do
71
152
  to_c.send(sym)
@@ -1,6 +1,9 @@
1
1
  require_relative '../quadratic_number'
2
2
 
3
- class Quadratic::Real # < Quadratic < Numeric
3
+ ##
4
+ # Abstract class for <tt>Quadratic[d]</tt> (d > 0).
5
+ #
6
+ class Quadratic::Real
4
7
  ### Classification ###
5
8
 
6
9
  # defined by Numeric:
@@ -21,6 +24,10 @@ class Quadratic::Real # < Quadratic < Numeric
21
24
 
22
25
  ### Comparisons ###
23
26
 
27
+ ##
28
+ # @param [Object] other
29
+ # @return [+1/0/-1/nil]
30
+ #
24
31
  def <=>(other)
25
32
  if other.kind_of?(Numeric)
26
33
  if other.real?
@@ -34,6 +41,10 @@ class Quadratic::Real # < Quadratic < Numeric
34
41
  end
35
42
  end
36
43
 
44
+ ##
45
+ # @param [Object] other
46
+ # @return [Boolean]
47
+ #
37
48
  def ==(other)
38
49
  if other.kind_of?(Numeric) && other.real?
39
50
  (self - other).to_f == 0
@@ -47,6 +58,16 @@ class Quadratic::Real # < Quadratic < Numeric
47
58
  # defined by Numeric:
48
59
  # * to_c #=> Complex.rect(self, 0)
49
60
 
61
+ ##
62
+ # Returns a float.
63
+ # Prevents cancellations of significant digits.
64
+ #
65
+ # @return [Float]
66
+ #
67
+ # @example
68
+ # -665857 + 470832 * Math.sqrt(2) #=> -7.508788257837296e-07
69
+ # Quadratic[2].new(-665857, 470832).to_f #=> -7.509119826032946e-07
70
+ #
50
71
  def to_f
51
72
  d = self.class::D
52
73
  if @a * @b < 0
@@ -58,6 +79,22 @@ class Quadratic::Real # < Quadratic < Numeric
58
79
  end
59
80
  end
60
81
 
82
+ ##
83
+ # @!method to_r
84
+ # @return [Rational]
85
+ #
86
+
87
+ ##
88
+ # @!method rationalize(eps)
89
+ # @param [Numeric] eps
90
+ # @return [Rational]
91
+ #
92
+
93
+ ##
94
+ # @!method to_i
95
+ # @return [Integer]
96
+ #
97
+
61
98
  [:to_r, :rationalize, :to_i].each do |sym|
62
99
  define_method(sym) do |*args|
63
100
  (@b == 0 ? @a : to_f).send(sym, *args)
@@ -1,8 +1,31 @@
1
1
  require 'prime' # Prime.prime_division
2
2
 
3
+ ##
4
+ # Base class.
5
+ #
6
+ # Users must specify a square-free integer to get a concrete class (see class method +.[]+).
7
+ #
3
8
  class Quadratic < Numeric
4
9
  @@classes = {}
5
10
 
11
+ # @!parse class Real < self; end
12
+
13
+ # @!parse class Imag < self; end
14
+
15
+ ##
16
+ # Provides a concrete class.
17
+ #
18
+ # @param [Integer] d
19
+ # @return [Class]
20
+ # @raise [TypeError] if +d+ is not an integer.
21
+ # @raise [RangeError] if +d+ is not square-free.
22
+ #
23
+ # @example
24
+ # Quadratic[2].ancestors.take(4)
25
+ # #=> [Quadratic[2], Quadratic::Real, Quadratic, Numeric]
26
+ # Quadratic[-1].ancestors.take(4)
27
+ # #=> [Quadratic[-1], Quadratic::Imag, Quadratic, Numeric]
28
+ #
6
29
  def self.[](d)
7
30
  # return a memoized subclass if exists
8
31
  return @@classes[d] if @@classes[d]
@@ -40,6 +63,13 @@ class Quadratic < Numeric
40
63
  attr_reader :a, :b
41
64
  protected :a, :b
42
65
 
66
+ ##
67
+ # Returns <tt>(a+b√d)</tt>.
68
+ #
69
+ # @example
70
+ # phi = Quadratic[5].new(1, 1) / 2 #=> ((1/2)+(1/2)*√5)
71
+ # omega = Quadratic[-3].new(-1, 1) / 2 #=> ((-1/2)+(1/2)*√-3)
72
+ #
43
73
  def initialize(a, b = 0)
44
74
  unless [a, b].all? { |x| __rational__(x) }
45
75
  raise TypeError, "not a rational"
@@ -51,6 +81,13 @@ class Quadratic < Numeric
51
81
 
52
82
  ### Basic arithmetic operations ###
53
83
 
84
+ ##
85
+ # Performs type conversion.
86
+ #
87
+ # @param [Numeric] other
88
+ # @return [[Numeric, Numeric]] +other+ and +self+
89
+ # @raise [TypeError]
90
+ #
54
91
  def coerce(other)
55
92
  my_class = self.class
56
93
  if other.kind_of?(my_class)
@@ -79,6 +116,12 @@ class Quadratic < Numeric
79
116
  end
80
117
  end
81
118
 
119
+ ##
120
+ # Performs addition.
121
+ #
122
+ # @param [Numeric] other
123
+ # @return [Quadratic[d]]
124
+ #
82
125
  def +(other)
83
126
  my_class = self.class
84
127
  if other.kind_of?(my_class)
@@ -90,6 +133,12 @@ class Quadratic < Numeric
90
133
  end
91
134
  end
92
135
 
136
+ ##
137
+ # Performs subtraction.
138
+ #
139
+ # @param [Numeric] other
140
+ # @return [Quadratic[d]]
141
+ #
93
142
  def -(other)
94
143
  my_class = self.class
95
144
  if other.kind_of?(my_class)
@@ -101,6 +150,12 @@ class Quadratic < Numeric
101
150
  end
102
151
  end
103
152
 
153
+ ##
154
+ # Performs multiplication.
155
+ #
156
+ # @param [Numeric] other
157
+ # @return [Quadratic[d]]
158
+ #
104
159
  def *(other)
105
160
  my_class = self.class
106
161
  if other.kind_of?(my_class)
@@ -114,6 +169,12 @@ class Quadratic < Numeric
114
169
  end
115
170
  end
116
171
 
172
+ ##
173
+ # Performs division.
174
+ #
175
+ # @param [Numeric] other
176
+ # @return [Quadratic[d]]
177
+ #
117
178
  def quo(other)
118
179
  my_class = self.class
119
180
  if other.kind_of?(my_class)
@@ -129,6 +190,12 @@ class Quadratic < Numeric
129
190
  end
130
191
  alias / quo
131
192
 
193
+ ##
194
+ # Performs division.
195
+ #
196
+ # @param [Numeric] other
197
+ # @return [Float/Complex]
198
+ #
132
199
  def fdiv(other)
133
200
  if other.kind_of?(Quadratic)
134
201
  self.to_builtin.fdiv(other.to_builtin)
@@ -140,9 +207,15 @@ class Quadratic < Numeric
140
207
  end
141
208
  end
142
209
 
210
+ ##
211
+ # Performs exponentiation.
212
+ #
213
+ # @param [Numeric] index
214
+ # @return [Quadratic[d]/Float/Complex]
215
+ #
143
216
  def **(index)
144
217
  unless index.kind_of?(Numeric)
145
- num1, num2 = other.coerce(self)
218
+ num1, num2 = index.coerce(self)
146
219
  return num1 ** num2
147
220
  end
148
221
 
@@ -162,7 +235,7 @@ class Quadratic < Numeric
162
235
  end
163
236
 
164
237
  # quadratic -> rational or integer / float or complex
165
- if index.kind_of?(Quadratic) && index.b == 0
238
+ if index.kind_of?(Quadratic)
166
239
  if index.b == 0
167
240
  index = index.a
168
241
  else
@@ -194,6 +267,12 @@ class Quadratic < Numeric
194
267
 
195
268
  ### Comparisons ###
196
269
 
270
+ ##
271
+ # Returns true if the two numbers are equal including their types.
272
+ #
273
+ # @param [Object] other
274
+ # @return [Boolean]
275
+ #
197
276
  def eql?(other)
198
277
  if other.kind_of?(self.class)
199
278
  @a.eql?(other.a) && @b.eql?(other.b)
@@ -202,6 +281,11 @@ class Quadratic < Numeric
202
281
  end
203
282
  end
204
283
 
284
+ ##
285
+ # Returns a hash value.
286
+ #
287
+ # @return [Integer]
288
+ #
205
289
  def hash
206
290
  [@a, @b, self.class::D].hash
207
291
  end
@@ -216,11 +300,21 @@ class Quadratic < Numeric
216
300
 
217
301
  ### Type conversions ###
218
302
 
303
+ ##
304
+ # Convert to a bilt-in class' object.
305
+ #
306
+ # @return [Float/Complex]
307
+ #
219
308
  def to_builtin
220
309
  real? ? to_f : to_c
221
310
  end
222
311
  protected :to_builtin
223
312
 
313
+ ##
314
+ # Returns a string.
315
+ #
316
+ # @return [String]
317
+ #
224
318
  def inspect
225
319
  '(' << __format__(:inspect) << ')'
226
320
  end
@@ -228,12 +322,22 @@ class Quadratic < Numeric
228
322
 
229
323
  ### Utilities ###
230
324
 
325
+ ##
326
+ # Returns its denominator.
327
+ #
328
+ # @return [Integer]
329
+ #
231
330
  def denominator
232
331
  ad = @a.denominator
233
332
  bd = @b.denominator
234
333
  ad.lcm(bd)
235
334
  end
236
335
 
336
+ ##
337
+ # Returns its numerator.
338
+ #
339
+ # @return [Quadratic[d]]
340
+ #
237
341
  def numerator
238
342
  an = @a.numerator
239
343
  ad = @a.denominator
@@ -245,16 +349,31 @@ class Quadratic < Numeric
245
349
 
246
350
  ### Extensions for Quadratic ###
247
351
 
352
+ ##
353
+ # Returns its quadratic conjugate.
354
+ #
355
+ # @return [Quadratic[d]]
356
+ #
248
357
  def qconj
249
358
  self.class.new(@a, -@b)
250
359
  end
251
360
  alias quadratic_conjugate qconj
252
361
 
362
+ ##
363
+ # Returns its trace.
364
+ #
365
+ # @return [Integer/Rational]
366
+ #
253
367
  def trace
254
368
  # self + self.qconj
255
369
  @a * 2
256
370
  end
257
371
 
372
+ ##
373
+ # Returns its norm.
374
+ #
375
+ # @return [Integer/Rational]
376
+ #
258
377
  def norm
259
378
  # self * self.qconj
260
379
  @a * @a - @b * @b * self.class::D
@@ -262,6 +381,11 @@ class Quadratic < Numeric
262
381
  alias qabs2 norm
263
382
  alias quadratic_abs2 qabs2
264
383
 
384
+ ##
385
+ # Returns its discriminant.
386
+ #
387
+ # @return [Integer/Rational]
388
+ #
265
389
  def discriminant
266
390
  # trace ** 2 - 4 * norm
267
391
  @b * @b * (self.class::D * 4)
@@ -3,12 +3,12 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = "quadratic_number"
6
- spec.version = "0.0.1"
6
+ spec.version = "0.0.2"
7
7
  spec.authors = ["Masahiro Nomoto"]
8
8
  spec.email = ["hmmnrst@users.noreply.github.com"]
9
9
 
10
10
  spec.summary = %q{Quadratic class}
11
- spec.description = %q{Provides a numeric class Quadratic to represent a+b\u221ad exactly}
11
+ spec.description = %q{Provides a numeric class Quadratic to represent a+b√d exactly}
12
12
  spec.homepage = "https://github.com/hmmnrst/quadratic_number"
13
13
  spec.license = "MIT"
14
14
 
metadata CHANGED
@@ -1,67 +1,67 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quadratic_number
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Nomoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-01 00:00:00.000000000 Z
11
+ date: 2017-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.14'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.14'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
- description: Provides a numeric class Quadratic to represent a+b\u221ad exactly
55
+ description: Provides a numeric class Quadratic to represent a+b√d exactly
56
56
  email:
57
57
  - hmmnrst@users.noreply.github.com
58
58
  executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
- - .gitignore
63
- - .rspec
64
- - .travis.yml
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
65
  - Gemfile
66
66
  - LICENSE.txt
67
67
  - README.md
@@ -82,17 +82,17 @@ require_paths:
82
82
  - lib
83
83
  required_ruby_version: !ruby/object:Gem::Requirement
84
84
  requirements:
85
- - - '>='
85
+ - - ">="
86
86
  - !ruby/object:Gem::Version
87
87
  version: '0'
88
88
  required_rubygems_version: !ruby/object:Gem::Requirement
89
89
  requirements:
90
- - - '>='
90
+ - - ">="
91
91
  - !ruby/object:Gem::Version
92
92
  version: '0'
93
93
  requirements: []
94
94
  rubyforge_project:
95
- rubygems_version: 2.0.14
95
+ rubygems_version: 2.6.11
96
96
  signing_key:
97
97
  specification_version: 4
98
98
  summary: Quadratic class