vector_number 0.4.3 → 0.6.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.
@@ -1,152 +1,142 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class VectorNumber
4
- # Methods for converting to different number classes.
5
- module Converting
6
- # Return real part of the number.
7
- #
8
- # @example
9
- # VectorNumber[23, "a"].real # => 23
10
- # VectorNumber["a"].real # => 0
11
- #
12
- # @return [Integer, Float, Rational, BigDecimal]
13
- #
14
- # @since 0.1.0
15
- def real = @data[R]
16
-
17
- # Return imaginary part of the number.
18
- #
19
- # @example
20
- # VectorNumber[23, "a"].imaginary # => 0
21
- # VectorNumber["a", Complex(1, 2r)].imag # => (2/1)
22
- #
23
- # @return [Integer, Float, Rational, BigDecimal]
24
- #
25
- # @since 0.1.0
26
- def imaginary = @data[I]
27
-
28
- # @since 0.2.1
29
- alias imag imaginary
30
-
31
- # Return value as an Integer, truncating it, if only real part is non-zero.
32
- #
33
- # @example
34
- # VectorNumber[13.5].to_i # => 13
35
- # VectorNumber[13r/12].to_int # => 1
36
- # [1.1, 2.2, 3.3][VectorNumber[2]] # => 3.3
37
- # VectorNumber[2, 2i].to_i # RangeError
38
- # VectorNumber[2, :i].to_f # RangeError
39
- #
40
- # Integer(VectorNumber[2]) # => 2
41
- # Integer(VectorNumber[2, "i"]) # RangeError
42
- #
43
- # @return [Integer]
44
- # @raise [RangeError] if any non-real part is non-zero
45
- #
46
- # @since 0.1.0
47
- def to_i
48
- numeric?(1) ? real.to_i : raise_convert_error(Integer)
49
- end
50
-
51
- # @since 0.1.0
52
- alias to_int to_i
53
-
54
- # Return value as a Float if only real part is non-zero.
55
- #
56
- # @example
57
- # VectorNumber[13.5].to_f # => 13.5
58
- # VectorNumber[13r/12].to_f # => 1.0833333333333333
59
- # VectorNumber[2, 2i].to_f # RangeError
60
- # VectorNumber[2, :i].to_f # RangeError
61
- #
62
- # Float(VectorNumber[2]) # => 2.0
63
- # Float(VectorNumber[2, "i"]) # RangeError
64
- #
65
- # @return [Float]
66
- # @raise [RangeError] if any non-real part is non-zero
67
- #
68
- # @since 0.1.0
69
- def to_f
70
- numeric?(1) ? real.to_f : raise_convert_error(Float)
71
- end
72
-
73
- # Return value as a Rational if only real part is non-zero.
74
- #
75
- # @example
76
- # VectorNumber[13.5].to_r # => (27/2)
77
- # VectorNumber[13r/12].to_r # => (13/12)
78
- # VectorNumber[2, 2i].to_r # RangeError
79
- # VectorNumber[2, :i].to_r # RangeError
80
- #
81
- # Rational(VectorNumber[2]) # => (2/1)
82
- # Rational(VectorNumber[2, "i"]) # RangeError
83
- #
84
- # @return [Rational]
85
- # @raise [RangeError] if any non-real part is non-zero
86
- #
87
- # @since 0.1.0
88
- def to_r
89
- numeric?(1) ? real.to_r : raise_convert_error(Rational)
90
- end
91
-
92
- # Return value as a BigDecimal if only real part is non-zero.
93
- #
94
- # @example
95
- # VectorNumber[13.5].to_d # => 0.135e2
96
- # VectorNumber[13r/12].to_d # ArgumentError
97
- # VectorNumber[13r/12].to_d(5) # => 0.10833e1
98
- # VectorNumber[2, 2i].to_d # RangeError
99
- # VectorNumber[2, :i].to_d # RangeError
100
- #
101
- # # This does't work without NumericRefinements:
102
- # BigDecimal(VectorNumber[2]) # TypeError
103
- # # #to_s can be used as a workaround if refinements aren't used:
104
- # BigDecimal(VectorNumber[2].to_s) # => 0.2e1
105
- # BigDecimal(VectorNumber[2, "i"].to_s) # => ArgumentError
106
- #
107
- # @param ndigits [Integer] precision
108
- # @return [BigDecimal]
109
- # @raise [RangeError] if any non-real part is non-zero
110
- # @raise [NameError] if BigDecimal is not defined
111
- #
112
- # @see Kernel.BigDecimal
113
- # @see NumericRefinements
114
- #
115
- # @since 0.1.0
116
- def to_d(ndigits = nil)
117
- if numeric?(1)
118
- return BigDecimal(real, ndigits) if ndigits
119
- return BigDecimal(real, Float::DIG) if real.is_a?(Float)
120
-
121
- BigDecimal(real)
122
- else
123
- raise_convert_error(BigDecimal)
124
- end
125
- end
126
-
127
- # Return value as a Complex if only real and/or imaginary parts are non-zero.
128
- #
129
- # @example
130
- # VectorNumber[13.5].to_c # => (13.5+0i)
131
- # VectorNumber[13r/12].to_c # => ((13/12)+0i)
132
- # VectorNumber[2, 2i].to_c # => (2+2i)
133
- # VectorNumber[2, :i].to_c # RangeError
134
- #
135
- # Complex(VectorNumber[2]) # => (2+0i)
136
- # Complex(VectorNumber[2, "i"]) # RangeError
137
- #
138
- # @return [Complex]
139
- # @raise [RangeError] if any non-real, non-imaginary part is non-zero
140
- #
141
- # @since 0.1.0
142
- def to_c
143
- numeric?(2) ? Complex(real, imaginary) : raise_convert_error(Complex)
144
- end
145
-
146
- private
147
-
148
- def raise_convert_error(klass)
149
- raise RangeError, "can't convert #{self} into #{klass}", caller
150
- end
4
+ # @group Converting to different numeric classes
5
+
6
+ # Return real part of the number.
7
+ #
8
+ # @example
9
+ # VectorNumber[23, "a"].real # => 23
10
+ # VectorNumber["a"].real # => 0
11
+ #
12
+ # @return [Integer, Float, Rational, BigDecimal]
13
+ def real = @data[R]
14
+
15
+ # Return imaginary part of the number.
16
+ #
17
+ # @example
18
+ # VectorNumber[23, "a"].imaginary # => 0
19
+ # VectorNumber["a", Complex(1, 2r)].imag # => (2/1)
20
+ #
21
+ # @return [Integer, Float, Rational, BigDecimal]
22
+ def imaginary = @data[I]
23
+
24
+ # @since 0.2.1
25
+ alias imag imaginary
26
+
27
+ # Return value as an Integer, truncating it, if only real part is non-zero.
28
+ #
29
+ # @example
30
+ # VectorNumber[13.5].to_i # => 13
31
+ # VectorNumber[13r/12].to_int # => 1
32
+ # [1.1, 2.2, 3.3][VectorNumber[2]] # => 3.3
33
+ # VectorNumber[2, 2i].to_i # RangeError
34
+ # VectorNumber[2, :i].to_f # RangeError
35
+ #
36
+ # Integer(VectorNumber[2]) # => 2
37
+ # Integer(VectorNumber[2, "i"]) # RangeError
38
+ #
39
+ # @return [Integer]
40
+ # @raise [RangeError] if any non-real part is non-zero
41
+ def to_i
42
+ raise_convert_error(Integer) unless numeric?(1)
43
+
44
+ real.to_i
45
+ end
46
+
47
+ alias to_int to_i
48
+
49
+ # Return value as a Float if only real part is non-zero.
50
+ #
51
+ # @example
52
+ # VectorNumber[13.5].to_f # => 13.5
53
+ # VectorNumber[13r/12].to_f # => 1.0833333333333333
54
+ # VectorNumber[2, 2i].to_f # RangeError
55
+ # VectorNumber[2, :i].to_f # RangeError
56
+ #
57
+ # Float(VectorNumber[2]) # => 2.0
58
+ # Float(VectorNumber[2, "i"]) # RangeError
59
+ #
60
+ # @return [Float]
61
+ # @raise [RangeError] if any non-real part is non-zero
62
+ def to_f
63
+ raise_convert_error(Float) unless numeric?(1)
64
+
65
+ real.to_f
66
+ end
67
+
68
+ # Return value as a Rational if only real part is non-zero.
69
+ #
70
+ # @example
71
+ # VectorNumber[13.5].to_r # => (27/2)
72
+ # VectorNumber[13r/12].to_r # => (13/12)
73
+ # VectorNumber[2, 2i].to_r # RangeError
74
+ # VectorNumber[2, :i].to_r # RangeError
75
+ #
76
+ # Rational(VectorNumber[2]) # => (2/1)
77
+ # Rational(VectorNumber[2, "i"]) # RangeError
78
+ #
79
+ # @return [Rational]
80
+ # @raise [RangeError] if any non-real part is non-zero
81
+ def to_r
82
+ raise_convert_error(Rational) unless numeric?(1)
83
+
84
+ real.to_r
85
+ end
86
+
87
+ # Return value as a BigDecimal if only real part is non-zero.
88
+ #
89
+ # @example
90
+ # VectorNumber[13.5].to_d # => 0.135e2
91
+ # VectorNumber[13r/12].to_d # ArgumentError
92
+ # VectorNumber[13r/12].to_d(5) # => 0.10833e1
93
+ # VectorNumber[2, 2i].to_d # RangeError
94
+ # VectorNumber[2, :i].to_d # RangeError
95
+ #
96
+ # # This does't work without NumericRefinements:
97
+ # BigDecimal(VectorNumber[2]) # TypeError
98
+ # # #to_s can be used as a workaround if refinements aren't used:
99
+ # BigDecimal(VectorNumber[2].to_s) # => 0.2e1
100
+ # BigDecimal(VectorNumber[2, "i"].to_s) # => ArgumentError
101
+ #
102
+ # @param ndigits [Integer] precision
103
+ # @return [BigDecimal]
104
+ # @raise [RangeError] if any non-real part is non-zero
105
+ # @raise [NameError] if BigDecimal is not defined
106
+ #
107
+ # @see Kernel.BigDecimal
108
+ # @see NumericRefinements
109
+ def to_d(ndigits = nil)
110
+ raise_convert_error(BigDecimal) unless numeric?(1)
111
+
112
+ return BigDecimal(real, ndigits) if ndigits
113
+ return BigDecimal(real, Float::DIG) if real.is_a?(Float)
114
+
115
+ BigDecimal(real)
116
+ end
117
+
118
+ # Return value as a Complex if only real and/or imaginary parts are non-zero.
119
+ #
120
+ # @example
121
+ # VectorNumber[13.5].to_c # => (13.5+0i)
122
+ # VectorNumber[13r/12].to_c # => ((13/12)+0i)
123
+ # VectorNumber[2, 2i].to_c # => (2+2i)
124
+ # VectorNumber[2, :i].to_c # RangeError
125
+ #
126
+ # Complex(VectorNumber[2]) # => (2+0i)
127
+ # Complex(VectorNumber[2, "i"]) # RangeError
128
+ #
129
+ # @return [Complex]
130
+ # @raise [RangeError] if any non-real, non-imaginary part is non-zero
131
+ def to_c
132
+ raise_convert_error(Complex) unless numeric?(2)
133
+
134
+ Complex(real, imaginary)
135
+ end
136
+
137
+ private
138
+
139
+ def raise_convert_error(klass)
140
+ raise RangeError, "can't convert #{self} into #{klass}", caller
151
141
  end
152
142
  end
@@ -1,128 +1,114 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class VectorNumber
4
- # Methods for enumerating values of the number.
5
- #
4
+ # @group Hash-like operations
5
+
6
6
  # +Enumerable+ is included so its methods can be used.
7
7
  # @example using Enumerable methods
8
8
  # VectorNumber["a", "b", 6].include?(["a", 1]) # => true
9
9
  # VectorNumber["a", "b", 6].select { |u, c| u.is_a?(String) } # => [["a", 1], ["b", 1]]
10
- module Enumerating
11
- # @since 0.1.0
12
- include ::Enumerable
10
+ include ::Enumerable
13
11
 
14
- # Iterate through every pair of unit and coefficient.
15
- # Returns +Enumerator+ (with set +size+) if no block is given.
16
- #
17
- # @example
18
- # v = VectorNumber["a", "b", 6]
19
- # units = []
20
- # v.each { |u, c| units << u unless u.is_a?(Numeric) } # => (1⋅'a' + 1⋅'b' + 6)
21
- # units # => ["a", "b"]
22
- # @example Enumerator
23
- # v.each.size # => 3
24
- # (v.each + [["d", 0]]).map(&:first) # => ["a", "b", 1, "d"]
25
- # v.each_pair.peek # => ["a", 1]
26
- #
27
- # @overload each
28
- # @yieldparam unit [Object]
29
- # @yieldparam coefficient [Integer, Float, Rational, BigDecimal]
30
- # @yieldreturn [void]
31
- # @return [VectorNumber] self
32
- # @overload each
33
- # @return [Enumerator]
34
- #
35
- # @see Enumerable
36
- # @see Enumerator
37
- #
38
- # @since 0.1.0
39
- def each(&block)
40
- return to_enum { size } unless block_given?
12
+ # Iterate through every pair of unit and coefficient.
13
+ # Returns +Enumerator+ (with set +size+) if no block is given.
14
+ #
15
+ # @example
16
+ # v = VectorNumber["a", "b", 6]
17
+ # units = []
18
+ # v.each { |u, c| units << u unless u.is_a?(Numeric) } # => (1⋅'a' + 1⋅'b' + 6)
19
+ # units # => ["a", "b"]
20
+ # @example Enumerator
21
+ # v.each.size # => 3
22
+ # (v.each + [["d", 0]]).map(&:first) # => ["a", "b", 1, "d"]
23
+ # v.each_pair.peek # => ["a", 1]
24
+ #
25
+ # @overload each
26
+ # @yieldparam unit [Object]
27
+ # @yieldparam coefficient [Numeric]
28
+ # @yieldreturn [void]
29
+ # @return [VectorNumber] self
30
+ # @overload each
31
+ # @return [Enumerator]
32
+ #
33
+ # @see Enumerable
34
+ # @see Enumerator
35
+ def each(&block)
36
+ return to_enum { size } unless block_given?
41
37
 
42
- @data.each(&block)
43
- self
44
- end
38
+ @data.each(&block)
39
+ self
40
+ end
45
41
 
46
- # @since 0.1.0
47
- alias each_pair each
42
+ alias each_pair each
48
43
 
49
- # Get a list of units with non-zero coefficients.
50
- #
51
- # @example
52
- # VectorNumber["a", "b", 6].units # => ["a", "b", 1]
53
- # VectorNumber.new.keys # => []
54
- #
55
- # @return [Array<Object>]
56
- #
57
- # @since 0.1.0
58
- def units = @data.keys
44
+ # Get a list of units with non-zero coefficients.
45
+ #
46
+ # @example
47
+ # VectorNumber["a", "b", 6].units # => ["a", "b", 1]
48
+ # VectorNumber.new.keys # => []
49
+ #
50
+ # @return [Array<Object>]
51
+ def units = @data.keys
59
52
 
60
- # @since 0.1.0
61
- alias keys units
53
+ alias keys units
62
54
 
63
- # Get a list of non-zero coefficients.
64
- #
65
- # @example
66
- # VectorNumber["a", "b", 6].coefficients # => [1, 1, 6]
67
- # VectorNumber.new.values # => []
68
- #
69
- # @return [Array<Integer, Float, Rational, BigDecimal>]
70
- #
71
- # @since 0.1.0
72
- def coefficients = @data.values
55
+ # Get a list of non-zero coefficients.
56
+ #
57
+ # @example
58
+ # VectorNumber["a", "b", 6].coefficients # => [1, 1, 6]
59
+ # VectorNumber.new.values # => []
60
+ #
61
+ # @return [Array<Numeric>]
62
+ def coefficients = @data.values
73
63
 
74
- # @since 0.1.0
75
- alias values coefficients
64
+ alias values coefficients
76
65
 
77
- # Get mutable hash with vector's data.
78
- #
79
- # Returned hash has a default value of 0.
80
- #
81
- # @example
82
- # VectorNumber["a", "b", 6].to_h # => {"a"=>1, "b"=>1, 1=>6}
83
- # VectorNumber["a", "b", 6].to_h["c"] # => 0
84
- #
85
- # @return [Hash{Object => Integer, Float, Rational, BigDecimal}]
86
- #
87
- # @since 0.1.0
88
- def to_h(&block)
89
- # TODO: Remove block argument.
90
- if block_given?
91
- @data.to_h(&block)
92
- else
93
- @data.dup
94
- end
66
+ # Get mutable hash with vector's data.
67
+ #
68
+ # Returned hash has a default value of 0.
69
+ #
70
+ # @example
71
+ # VectorNumber["a", "b", 6].to_h # => {"a"=>1, "b"=>1, 1=>6}
72
+ # VectorNumber["a", "b", 6].to_h["c"] # => 0
73
+ #
74
+ # @return [Hash{Object => Numeric}]
75
+ def to_h(&block)
76
+ # TODO: Remove block argument.
77
+ if block_given?
78
+ @data.to_h(&block)
79
+ else
80
+ @data.dup
95
81
  end
82
+ end
96
83
 
97
- # Get the coefficient for the unit.
98
- #
99
- # If the +unit?(unit)+ is false, 0 is returned.
100
- # Note that units for real and imaginary parts are
101
- # VectorNumber::R and VectorNumber::I respectively.
102
- #
103
- # @example
104
- # VectorNumber["a", "b", 6]["a"] # => 1
105
- # VectorNumber["a", "b", 6]["c"] # => 0
106
- #
107
- # @param unit [Object]
108
- # @return [Integer, Float, Rational, BigDecimal]
109
- #
110
- # @since 0.2.4
111
- def [](unit) = @data[unit]
84
+ # Get the coefficient for the unit.
85
+ #
86
+ # If the +unit?(unit)+ is false, 0 is returned.
87
+ # Note that units for real and imaginary parts are
88
+ # VectorNumber::R and VectorNumber::I respectively.
89
+ #
90
+ # @example
91
+ # VectorNumber["a", "b", 6]["a"] # => 1
92
+ # VectorNumber["a", "b", 6]["c"] # => 0
93
+ #
94
+ # @param unit [Object]
95
+ # @return [Numeric]
96
+ #
97
+ # @since 0.2.4
98
+ def [](unit) = @data[unit]
112
99
 
113
- # Check if a unit has a non-zero coefficient.
114
- #
115
- # @example
116
- # VectorNumber["a", "b", 6].unit?("a") # => true
117
- # VectorNumber["a", "b", 6].key?("c") # => false
118
- #
119
- # @param unit [Object]
120
- # @return [Boolean]
121
- #
122
- # @since 0.2.4
123
- def unit?(unit) = @data.key?(unit)
100
+ # Check if a unit has a non-zero coefficient.
101
+ #
102
+ # @example
103
+ # VectorNumber["a", "b", 6].unit?("a") # => true
104
+ # VectorNumber["a", "b", 6].key?("c") # => false
105
+ #
106
+ # @param unit [Object]
107
+ # @return [Boolean]
108
+ #
109
+ # @since 0.2.4
110
+ def unit?(unit) = @data.key?(unit)
124
111
 
125
- # @since 0.2.4
126
- alias key? unit?
127
- end
112
+ # @since 0.2.4
113
+ alias key? unit?
128
114
  end