vector_number 0.6.0 → 0.7.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.
@@ -15,15 +15,15 @@ class VectorNumber
15
15
  # @example
16
16
  # v = VectorNumber["a", "b", 6]
17
17
  # units = []
18
- # v.each { |u, c| units << u unless u.is_a?(Numeric) } # => (1⋅'a' + 1⋅'b' + 6)
18
+ # v.each { |u, c| units << u unless VectorNumber.numeric_unit?(u) } # => (1⋅"a" + 1⋅"b" + 6)
19
19
  # units # => ["a", "b"]
20
20
  # @example Enumerator
21
21
  # v.each.size # => 3
22
- # (v.each + [["d", 0]]).map(&:first) # => ["a", "b", 1, "d"]
22
+ # (v.each + [["d", 0]]).map(&:first) # => ["a", "b", unit/1, "d"]
23
23
  # v.each_pair.peek # => ["a", 1]
24
24
  #
25
25
  # @overload each
26
- # @yieldparam unit [Object]
26
+ # @yieldparam unit [Any]
27
27
  # @yieldparam coefficient [Numeric]
28
28
  # @yieldreturn [void]
29
29
  # @return [VectorNumber] self
@@ -35,6 +35,7 @@ class VectorNumber
35
35
  def each(&block)
36
36
  return to_enum { size } unless block_given?
37
37
 
38
+ # @type var block: ^([unit_type, coefficient_type]) -> untyped
38
39
  @data.each(&block)
39
40
  self
40
41
  end
@@ -44,10 +45,10 @@ class VectorNumber
44
45
  # Get a list of units with non-zero coefficients.
45
46
  #
46
47
  # @example
47
- # VectorNumber["a", "b", 6].units # => ["a", "b", 1]
48
+ # VectorNumber["a", "b", 6].units # => ["a", "b", unit/1]
48
49
  # VectorNumber.new.keys # => []
49
50
  #
50
- # @return [Array<Object>]
51
+ # @return [Array<Any>]
51
52
  def units = @data.keys
52
53
 
53
54
  alias keys units
@@ -63,24 +64,27 @@ class VectorNumber
63
64
 
64
65
  alias values coefficients
65
66
 
66
- # Get mutable hash with vector's data.
67
- #
68
- # Returned hash has a default value of 0.
67
+ # Get a list of coefficients corresponding to +units+.
69
68
  #
70
69
  # @example
71
- # VectorNumber["a", "b", 6].to_h # => {"a"=>1, "b"=>1, 1=>6}
72
- # VectorNumber["a", "b", 6].to_h["c"] # => 0
70
+ # VectorNumber["a", "b", 6].coefficients_at("a", "b") # => [1, 1]
71
+ # VectorNumber["a", "b", 6].coefficients_at("a", "c") # => [1, 0]
72
+ # VectorNumber["a", "b", 6].coefficients_at("c", "b", "c") # => [0, 1, 0]
73
+ # VectorNumber["a", "b", 6].coefficients_at) # => []
73
74
  #
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
81
- end
75
+ # @see #fetch_coefficients
76
+ #
77
+ # @param units [Array<Any>]
78
+ # @return [Array<Numeric>]
79
+ #
80
+ # @since 0.7.0
81
+ def coefficients_at(*units)
82
+ @data.values_at(*units) # : Array[coefficient_type]
82
83
  end
83
84
 
85
+ # @since 0.7.0
86
+ alias values_at coefficients_at
87
+
84
88
  # Get the coefficient for the unit.
85
89
  #
86
90
  # If the +unit?(unit)+ is false, 0 is returned.
@@ -89,13 +93,123 @@ class VectorNumber
89
93
  #
90
94
  # @example
91
95
  # VectorNumber["a", "b", 6]["a"] # => 1
96
+ # VectorNumber["a", "b", 6][VectorNumber::R] # => 6
92
97
  # VectorNumber["a", "b", 6]["c"] # => 0
93
98
  #
94
- # @param unit [Object]
99
+ # @see #assoc
100
+ # @see #fetch
101
+ #
102
+ # @param unit [Any]
95
103
  # @return [Numeric]
96
104
  #
97
105
  # @since 0.2.4
98
- def [](unit) = @data[unit]
106
+ def [](unit)
107
+ @data[unit]
108
+ end
109
+
110
+ # Get a 2-element array containing a given unit and associated coefficient.
111
+ #
112
+ # @example
113
+ # VectorNumber["a", "b", 6].assoc("a") # => ["a", 1]
114
+ # VectorNumber["a", "b", 6].assoc(VectorNumber::R) # => [unit/1, 6]
115
+ # VectorNumber["a", "b", 6].assoc("c") # => ["c", 0]
116
+ #
117
+ # @see #[]
118
+ #
119
+ # @param unit [Any]
120
+ # @return [Array(Any, Numeric)]
121
+ #
122
+ # @since 0.7.0
123
+ def assoc(unit)
124
+ @data.assoc(unit) || [unit, 0]
125
+ end
126
+
127
+ # Finds and returns the object in nested objects that is specified by +identifiers+.
128
+ #
129
+ # As nested objects for a VectorNumber are numeric coefficients,
130
+ # digging deeper will most probably result in an error.
131
+ #
132
+ # @example
133
+ # VectorNumber["a", "b", 6].dig("a") # => 1
134
+ # VectorNumber["a", "b", 6].dig("c") # => 0
135
+ # VectorNumber["a", "b", 6].dig("a", 1) # TypeError
136
+ # { 1 => VectorNumber["a", "b", 6] }.dig(1, "a") # => 1
137
+ #
138
+ # @param identifiers [Array<Any>]
139
+ # @return [Numeric]
140
+ #
141
+ # @since 0.7.0
142
+ def dig(*identifiers)
143
+ @data.dig(*identifiers)
144
+ end
145
+
146
+ # Get the coefficient for the unit, treating 0 coefficients as missing.
147
+ #
148
+ # If +self.unit?(unit)+ is +true+, returns the associated coefficient.
149
+ # Otherwise:
150
+ # - if neither block, not +default_value+ is given, raises +KeyError+;
151
+ # - if block is given, returns the result of the block;
152
+ # - if +default_value+ is given, returns +default_value+.
153
+ #
154
+ # @example
155
+ # VectorNumber["a", "b", 6].fetch("a") # => 1
156
+ # VectorNumber["a", "b", 6].fetch("c") # KeyError
157
+ # VectorNumber["a", "b", 6].fetch("c", "default") # => "default"
158
+ # VectorNumber["a", "b", 6].fetch("c") { |u| "default #{u}" } # => "default c"
159
+ #
160
+ # @see #[]
161
+ # @see #fetch_coefficients
162
+ # @see #unit?
163
+ #
164
+ # @overload fetch(unit)
165
+ # @param unit [Any]
166
+ # @return [Numeric]
167
+ # @overload fetch(unit, default_value)
168
+ # @param unit [Any]
169
+ # @param default_value [Any]
170
+ # @return [Any]
171
+ # @overload fetch(unit)
172
+ # @param unit [Any]
173
+ # @yieldparam unit [Any]
174
+ # @yieldreturn [Any]
175
+ # @return [Any]
176
+ # @raise [KeyError] if default value was needed, but not provided
177
+ #
178
+ # @since 0.7.0
179
+ def fetch(...)
180
+ @data.fetch(...) # steep:ignore UnresolvedOverloading
181
+ end
182
+
183
+ # Get coefficients for multiple units in the same way as {#fetch}.
184
+ #
185
+ # @example
186
+ # VectorNumber["a", "b", 6].fetch_coefficients(VectorNumber::R, "a") # => [6, 1]
187
+ # VectorNumber["a", "b", 6].fetch_coefficients("a", "c") # KeyError
188
+ # VectorNumber["a", "b", 6].fetch_coefficients("a", "c") { 0 } # => [1, 0]
189
+ # VectorNumber["a", "b", 6].fetch_coefficients("a", "a", "a") # => [1, 1, 1]
190
+ # VectorNumber["a", "b", 6].fetch_coefficients # => []
191
+ #
192
+ # @see #coefficients_at
193
+ # @see #fetch
194
+ # @see #unit?
195
+ #
196
+ # @overload fetch_coefficients(*units)
197
+ # @param units [Array<Any>]
198
+ # @return [Array<Numeric>]
199
+ # @overload fetch_coefficients(*units)
200
+ # @param units [Array<Any>]
201
+ # @yieldparam unit [Any]
202
+ # @yieldreturn [Any]
203
+ # @return [Array<Any>]
204
+ # @raise [KeyError] if default value was needed, but not provided
205
+ #
206
+ # @since 0.7.0
207
+ def fetch_coefficients(...)
208
+ @data.fetch_values(...) # steep:ignore UnresolvedOverloading
209
+ end
210
+
211
+ # @since 0.7.0
212
+ alias fetch_values fetch_coefficients
99
213
 
100
214
  # Check if a unit has a non-zero coefficient.
101
215
  #
@@ -103,12 +217,113 @@ class VectorNumber
103
217
  # VectorNumber["a", "b", 6].unit?("a") # => true
104
218
  # VectorNumber["a", "b", 6].key?("c") # => false
105
219
  #
106
- # @param unit [Object]
220
+ # @param unit [Any]
107
221
  # @return [Boolean]
108
222
  #
109
223
  # @since 0.2.4
110
- def unit?(unit) = @data.key?(unit)
224
+ def unit?(unit)
225
+ @data.key?(unit)
226
+ end
111
227
 
112
228
  # @since 0.2.4
113
229
  alias key? unit?
230
+
231
+ # Return a new VectorNumber with coefficients transformed
232
+ # by the mapping hash and/or a block.
233
+ #
234
+ # An optional +mapping+ argument can be provided to map coefficients to new coefficients.
235
+ # Any coefficient not given in +mapping+ will be mapped using the provided block,
236
+ # or remain the same if no block is given.
237
+ # If neither +mapping+ nor block is given, an enumerator is returned.
238
+ #
239
+ # @example
240
+ # VectorNumber["a", "b", 6].transform_coefficients { _1 * 2 } # => (2⋅"a" + 2⋅"b" + 12)
241
+ # VectorNumber["a", "b", 6].transform_values(1 => 2) # => (2⋅"a" - 2⋅"b" + 6)
242
+ # VectorNumber["a", "b", 6].transform_coefficients(1 => 2) { _1 / 2 } # => (2⋅"a" - 2⋅"b" + 3)
243
+ # VectorNumber["a", "b", 6].transform_values # => Enumerator
244
+ #
245
+ # @overload transform_coefficients(mapping)
246
+ # @param mapping [Hash{Numeric => Numeric}]
247
+ # @return [VectorNumber]
248
+ # @overload transform_coefficients
249
+ # @yieldparam coefficient [Numeric]
250
+ # @yieldreturn [Numeric]
251
+ # @return [VectorNumber]
252
+ # @overload transform_coefficients(mapping)
253
+ # @param mapping [Hash{Numeric => Numeric}]
254
+ # @yieldparam coefficient [Numeric]
255
+ # @yieldreturn [Numeric]
256
+ # @return [VectorNumber]
257
+ # @overload transform_coefficients
258
+ # @return [Enumerator]
259
+ #
260
+ # @since 0.7.0
261
+ def transform_coefficients(mapping = nil, &transform)
262
+ if mapping
263
+ if block_given?
264
+ # @type var transform: ^(coefficient_type) -> coefficient_type
265
+ new { |c| mapping.fetch(c) { yield(c) } }
266
+ else
267
+ new { |c| mapping.fetch(c, c) }
268
+ end
269
+ elsif block_given?
270
+ # @type var transform: ^(coefficient_type) -> coefficient_type
271
+ new(&transform)
272
+ else
273
+ to_enum(:transform_coefficients) { size } # rubocop:disable Lint/ToEnumArguments
274
+ end
275
+ end
276
+
277
+ # @since 0.7.0
278
+ alias transform_values transform_coefficients
279
+
280
+ # Return a new VectorNumber with units transformed
281
+ # by the mapping hash and/or a block.
282
+ #
283
+ # An optional +mapping+ argument can be provided to map units to new units.
284
+ # Any unit not given in +mapping+ will be mapped using the provided block,
285
+ # or remain the same if no block is given.
286
+ # If neither +mapping+ nor block is given, an enumerator is returned.
287
+ #
288
+ # @example
289
+ # VectorNumber["a", "b", 6].transform_units("a" => "c") # => (1⋅"c" + 1⋅"b" + 6)
290
+ # VectorNumber["a", "b", 6].transform_keys { _1.is_a?(String) ? _1.to_sym : _1 }
291
+ # # => (1⋅:a + 1⋅:b + 6)
292
+ # VectorNumber["a", "b", 6].transform_units("a" => "c") { _1.to_s }
293
+ # # => (1⋅"c" + 1⋅"b" + 6⋅"")
294
+ # VectorNumber["a", "b", 6].transform_keys # => Enumerator
295
+ #
296
+ # @overload transform_units(mapping)
297
+ # @param mapping [Hash{Any => Any}]
298
+ # @return [VectorNumber]
299
+ # @overload transform_units
300
+ # @yieldparam unit [Any]
301
+ # @yieldreturn [Any]
302
+ # @return [VectorNumber]
303
+ # @overload transform_units(mapping)
304
+ # @param mapping [Hash{Any => Any}]
305
+ # @yieldparam unit [Any]
306
+ # @yieldreturn [Any]
307
+ # @return [VectorNumber]
308
+ # @overload transform_units
309
+ # @return [Enumerator]
310
+ #
311
+ # @since 0.7.0
312
+ def transform_units(mapping = nil, &transform)
313
+ if block_given?
314
+ # @type var transform: ^(unit_type unit) -> unit_type
315
+ if mapping
316
+ new(@data.transform_keys(mapping, &transform))
317
+ else
318
+ new(@data.transform_keys(&transform))
319
+ end
320
+ elsif mapping
321
+ new(@data.transform_keys(mapping))
322
+ else
323
+ to_enum(:transform_units) { size } # rubocop:disable Lint/ToEnumArguments
324
+ end
325
+ end
326
+
327
+ # @since 0.7.0
328
+ alias transform_keys transform_units
114
329
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class VectorNumber
4
- # @group Mathematical operations
4
+ # @group Arithmetic operations
5
5
  #
6
6
  # All operators (like +*+) have aliases (like +mult+)
7
7
  # to make method chaining easier and more natural.
@@ -18,7 +18,7 @@ class VectorNumber
18
18
  # 5.coerce(VectorNumber["a"]) # RangeError
19
19
  # 5 + VectorNumber["a"] # => (5 + 1⋅"a")
20
20
  #
21
- # @param other [Object]
21
+ # @param other [Any]
22
22
  # @return [Array(VectorNumber, VectorNumber)]
23
23
  #
24
24
  # @since 0.2.0
@@ -59,7 +59,7 @@ class VectorNumber
59
59
  # 10 + VectorNumber[5] # => (15)
60
60
  # 10 + VectorNumber["a"] # => (10 + 1⋅"a")
61
61
  #
62
- # @param other [Object]
62
+ # @param other [Any]
63
63
  # @return [VectorNumber]
64
64
  #
65
65
  # @since 0.2.0
@@ -82,18 +82,18 @@ class VectorNumber
82
82
  # 3 - VectorNumber[5] # => (-2)
83
83
  # 3 - VectorNumber["a"] # => (3 - 1⋅"a")
84
84
  #
85
- # @param other [Object]
85
+ # @param other [Any]
86
86
  # @return [VectorNumber]
87
87
  #
88
88
  # @since 0.2.0
89
89
  def -(other)
90
- self + new([other], &:-@)
90
+ new([self, new([other], &:-@)])
91
91
  end
92
92
 
93
93
  # @since 0.3.0
94
94
  alias sub -
95
95
 
96
- # Multiply all coefficients by a real +other+, returning new vector.
96
+ # Multiply all coefficients by a real +other+, returning new vector scaled by +other+.
97
97
  #
98
98
  # This effectively multiplies {#magnitude} by +other+.
99
99
  #
@@ -107,7 +107,7 @@ class VectorNumber
107
107
  # 2 * VectorNumber[5] # => (10)
108
108
  # 2 * VectorNumber["a"] # => (2⋅"a")
109
109
  #
110
- # @param other [Integer, Float, Rational, BigDecimal, VectorNumber]
110
+ # @param other [Numeric, VectorNumber]
111
111
  # @return [VectorNumber]
112
112
  # @raise [RangeError] if +other+ is not a number or +other+ can't be multiplied by this one
113
113
  #
@@ -117,7 +117,7 @@ class VectorNumber
117
117
  other = other.real
118
118
  # @type var other: Float
119
119
  new { _1 * other }
120
- elsif real_number?(self) && other.is_a?(self.class)
120
+ elsif real_number?(self) && VectorNumber === other
121
121
  # @type var other: untyped
122
122
  other * self
123
123
  else
@@ -128,23 +128,23 @@ class VectorNumber
128
128
  # @since 0.3.0
129
129
  alias mult *
130
130
 
131
- # Divide all coefficients by a real +other+, returning new vector.
131
+ # Divide all coefficients by a real +other+, returning new vector scaled by reciprocal of +other+.
132
132
  #
133
- # This effectively multiplies {#magnitude} by reciprocal of +other+.
133
+ # This effectively divides {#magnitude} by +other+.
134
134
  # @note This method never does integer division.
135
135
  #
136
136
  # @example
137
137
  # VectorNumber[10] / 2 # => (5)
138
- # VectorNumber["a", "b", 6].quo(2) # => (1/2⋅"a" + 1/2⋅"b" + 3/1)
139
- # VectorNumber["a"] / VectorNumber[2] # => (1/2⋅"a")
138
+ # VectorNumber["a", "b", 6].quo(2) # => ((1/2)⋅"a" + (1/2)⋅"b" + (3/1))
139
+ # VectorNumber["a"] / VectorNumber[2] # => ((1/2)⋅"a")
140
140
  # # Can't divide by a non-real:
141
141
  # VectorNumber["a"] / VectorNumber["b"] # RangeError
142
142
  # @example numeric types can be divided in reverse
143
- # 2 / VectorNumber[10] # => (1/5)
143
+ # 2 / VectorNumber[10] # => ((1/5))
144
144
  # # Can't divide by a non-real:
145
145
  # 2 / VectorNumber["a"] # RangeError
146
146
  #
147
- # @param other [Integer, Float, Rational, BigDecimal, VectorNumber]
147
+ # @param other [Numeric, VectorNumber]
148
148
  # @return [VectorNumber]
149
149
  # @raise [RangeError] if +other+ is not a number or is not a real number
150
150
  # @raise [ZeroDivisionError] if +other+ is zero
@@ -180,7 +180,7 @@ class VectorNumber
180
180
  # 2.fdiv(VectorNumber[10]) # => 0.2 (Float)
181
181
  # 2.0.fdiv(VectorNumber[10]) # => (0.2) (VectorNumber)
182
182
  #
183
- # @param other [Integer, Float, Rational, BigDecimal, VectorNumber]
183
+ # @param other [Numeric, VectorNumber]
184
184
  # @return [VectorNumber]
185
185
  # @raise [RangeError] if +other+ is not a number or is not a real number
186
186
  # @raise [ZeroDivisionError] if +other+ is zero
@@ -190,18 +190,19 @@ class VectorNumber
190
190
  check_divisibility(other)
191
191
 
192
192
  other = other.real
193
- new { _1.fdiv(other) }
193
+ new { _1.fdiv(other) } # steep:ignore BlockBodyTypeMismatch
194
194
  end
195
195
 
196
196
  # Divide all coefficients by a real +other+,
197
197
  # converting results to integers using +#floor+.
198
198
  #
199
- # This is requal to +(self / other).floor+.
199
+ # This is equal to +(self / other).floor+.
200
200
  #
201
201
  # @example
202
202
  # VectorNumber[10].div(3) # => (3)
203
203
  # VectorNumber["a"].div(2) # => (0)
204
204
  # VectorNumber["a"].div(VectorNumber[2]) # => (0)
205
+ # VectorNumber[-10, "string"].div(100) # => (-1)
205
206
  # # Can't divide by a non-real:
206
207
  # VectorNumber["a"].div(VectorNumber["b"]) # RangeError
207
208
  # @example numeric types can be divided in reverse
@@ -213,7 +214,7 @@ class VectorNumber
213
214
  # @see #%
214
215
  # @see #floor
215
216
  #
216
- # @param other [Integer, Float, Rational, BigDecimal, VectorNumber]
217
+ # @param other [Numeric, VectorNumber]
217
218
  # @return [VectorNumber]
218
219
  # @raise [RangeError] if +other+ is not a number or is not a real number
219
220
  # @raise [ZeroDivisionError] if +other+ is zero
@@ -223,9 +224,42 @@ class VectorNumber
223
224
  check_divisibility(other)
224
225
 
225
226
  other = other.real
227
+ # @type var other: Float
226
228
  new { _1.div(other) }
227
229
  end
228
230
 
231
+ # Divide all coefficients by a real +other+,
232
+ # converting results to integers using +#ceil+.
233
+ #
234
+ # This is equal to +(self / other).ceil+.
235
+ #
236
+ # @example
237
+ # VectorNumber[10].ceildiv(3) # => (4)
238
+ # VectorNumber["a"].ceildiv(2) # => (1⋅"a")
239
+ # (VectorNumber["a"] - 3).ceildiv(2) # => (1⋅"a" - 1)
240
+ # VectorNumber[-10, "string"].ceildiv(100) # => (1⋅"string")
241
+ # # Can't divide by a non-real:
242
+ # VectorNumber["a"].ceildiv(VectorNumber["b"]) # RangeError
243
+ #
244
+ # @see #div
245
+ # @see #ceil
246
+ # @see Integer#ceildiv
247
+ #
248
+ # @param other [Numeric, VectorNumber]
249
+ # @return [VectorNumber]
250
+ # @raise [RangeError] if +other+ is not a number or is not a real number
251
+ # @raise [ZeroDivisionError] if +other+ is zero
252
+ #
253
+ # @since 0.7.0
254
+ def ceildiv(other)
255
+ check_divisibility(other)
256
+
257
+ other = other.real
258
+ other = Rational(other) if other.integer?
259
+ # @type var other: Float
260
+ new { (_1 / other).ceil }
261
+ end
262
+
229
263
  # Return the modulus of dividing self by a real +other+ as a vector.
230
264
  #
231
265
  # This is equal to +self - other * (self/other).floor+,
@@ -250,7 +284,7 @@ class VectorNumber
250
284
  # @see #remainder
251
285
  # @see Numeric#%
252
286
  #
253
- # @param other [Integer, Float, Rational, BigDecimal, VectorNumber]
287
+ # @param other [Numeric, VectorNumber]
254
288
  # @return [VectorNumber]
255
289
  # @raise [RangeError] if +other+ is not a number or is not a real number
256
290
  # @raise [ZeroDivisionError] if +other+ is zero
@@ -260,6 +294,7 @@ class VectorNumber
260
294
  check_divisibility(other)
261
295
 
262
296
  other = other.real
297
+ # @type var other: Float
263
298
  new { _1 % other }
264
299
  end
265
300
 
@@ -283,7 +318,7 @@ class VectorNumber
283
318
  # @see #div
284
319
  # @see #%
285
320
  #
286
- # @param other [Integer, Float, Rational, BigDecimal, VectorNumber]
321
+ # @param other [Numeric, VectorNumber]
287
322
  # @return [Array(VectorNumber, VectorNumber)]
288
323
  # @raise [RangeError] if +other+ is not a number or is not a real number
289
324
  # @raise [ZeroDivisionError] if +other+ is zero
@@ -314,7 +349,7 @@ class VectorNumber
314
349
  # @see #%
315
350
  # @see Numeric#remainder
316
351
  #
317
- # @param other [Integer, Float, Rational, BigDecimal, VectorNumber]
352
+ # @param other [Numeric, VectorNumber]
318
353
  # @return [VectorNumber]
319
354
  # @raise [RangeError] if +other+ is not a number or is not a real number
320
355
  # @raise [ZeroDivisionError] if +other+ is zero
@@ -324,6 +359,7 @@ class VectorNumber
324
359
  check_divisibility(other)
325
360
 
326
361
  other = other.real
362
+ # @type var other: Float
327
363
  new { _1.remainder(other) }
328
364
  end
329
365
 
@@ -332,7 +368,11 @@ class VectorNumber
332
368
  # @raise [RangeError] unless +other+ is a real number
333
369
  # @raise [ZeroDivisionError]
334
370
  def check_divisibility(other)
335
- raise RangeError, "can't divide #{self} by #{other.inspect}", caller unless real_number?(other)
371
+ unless real_number?(other)
372
+ raise RangeError,
373
+ "can't divide #{self} by #{Kernel.instance_method(:inspect).bind_call(other)}",
374
+ caller
375
+ end
336
376
  raise ZeroDivisionError, "divided by 0", caller if other.zero?
337
377
  end
338
378
  end
@@ -47,7 +47,9 @@ class VectorNumber
47
47
  # @raise (see #numeric?)
48
48
  #
49
49
  # @since 0.2.1
50
- def nonnumeric?(dimensions = 2) = !numeric?(dimensions)
50
+ def nonnumeric?(dimensions = 2)
51
+ !numeric?(dimensions)
52
+ end
51
53
 
52
54
  # Returns +true+ if all coefficients are finite, +false+ otherwise.
53
55
  #
@@ -1,37 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class VectorNumber
4
- # @group Mathematical operations
5
-
6
- # Calculate the absolute value of the vector (its length).
7
- #
8
- # @example
9
- # VectorNumber[5.3].abs # => 5.3
10
- # VectorNumber[-5.3i].magnitude # => 5.3
11
- # VectorNumber[-5.3i, "i"].abs # => 5.3935146240647205
12
- #
13
- # @return [Float]
14
- #
15
- # @since 0.2.2
16
- def abs
17
- Math.sqrt(abs2)
18
- end
19
-
20
- alias magnitude abs
21
-
22
- # Calculate the square of absolute value.
23
- #
24
- # @example
25
- # VectorNumber[5.3].abs2 # => 5.3
26
- # VectorNumber[-5.3i].abs2 # => 5.3
27
- # VectorNumber[-5.3i, "i"].abs2 # => 29.09
28
- #
29
- # @return [Float]
30
- #
31
- # @since 0.2.2
32
- def abs2
33
- coefficients.sum(&:abs2)
34
- end
4
+ # @group Rounding
35
5
 
36
6
  # Return a new vector with every coefficient truncated using their +#truncate+.
37
7
  #
@@ -81,7 +51,8 @@ class VectorNumber
81
51
  #
82
52
  # @since 0.2.2
83
53
  def floor(digits = 0)
84
- new { _1.floor(digits) }
54
+ # Why is there a problem here, but not in #truncate and #ceil? I dunno.
55
+ new { _1.floor(digits) } # steep:ignore BlockBodyTypeMismatch
85
56
  end
86
57
 
87
58
  # Return a new vector with every coefficient rounded using their +#round+.
@@ -107,7 +78,7 @@ class VectorNumber
107
78
  # @see Float#round
108
79
  #
109
80
  # @since 0.2.2
110
- def round(digits = 0, half: :up)
81
+ def round(digits = 0, half: :up) # rubocop:disable Metrics/MethodLength
111
82
  if defined?(BigDecimal)
112
83
  bd_mode =
113
84
  case half
@@ -115,10 +86,16 @@ class VectorNumber
115
86
  when :even then :half_even
116
87
  else :half_up
117
88
  end
118
- new { _1.is_a?(BigDecimal) ? _1.round(digits, bd_mode) : _1.round(digits, half: half) }
89
+ new do |c|
90
+ if BigDecimal === c
91
+ c.round(digits, bd_mode)
92
+ else
93
+ c.round(digits, half: half) # steep:ignore UnresolvedOverloading
94
+ end
95
+ end
119
96
  # :nocov:
120
97
  else
121
- new { _1.round(digits, half: half) }
98
+ new { _1.round(digits, half: half) } # steep:ignore UnresolvedOverloading
122
99
  end
123
100
  # :nocov:
124
101
  end