vector_number 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +61 -3
- data/LICENSE.txt +21 -0
- data/README.md +19 -10
- data/lib/vector_number/comparing.rb +55 -2
- data/lib/vector_number/converting.rb +86 -6
- data/lib/vector_number/enumerating.rb +70 -13
- data/lib/vector_number/math_converting.rb +66 -6
- data/lib/vector_number/mathing.rb +207 -33
- data/lib/vector_number/numeric_refinements.rb +33 -9
- data/lib/vector_number/querying.rb +84 -15
- data/lib/vector_number/stringifying.rb +31 -2
- data/lib/vector_number/version.rb +2 -2
- data/lib/vector_number.rb +114 -45
- data/sig/vector_number.rbs +3 -3
- metadata +16 -5
@@ -5,12 +5,21 @@ class VectorNumber
|
|
5
5
|
# Mostly modeled after {::Complex}.
|
6
6
|
module Querying
|
7
7
|
# Whether this VectorNumber can be considered strictly numeric, e.g. real or complex.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# VectorNumber[2].numeric? # => true
|
11
|
+
# VectorNumber[2, 3i].numeric? # => true
|
12
|
+
# VectorNumber[2, "a"].numeric? # => false
|
13
|
+
# VectorNumber[2, 3i].numeric?(1) # => false
|
14
|
+
#
|
8
15
|
# @param dimensions [Integer] number of dimensions to consider "numeric"
|
9
16
|
# - 0 — zero
|
10
17
|
# - 1 — real number
|
11
18
|
# - 2 — complex number, etc.
|
12
19
|
# @return [Boolean]
|
13
20
|
# @raise [ArgumentError] if +dimensions+ is negative
|
21
|
+
#
|
22
|
+
# @since 0.2.0
|
14
23
|
def numeric?(dimensions = 2)
|
15
24
|
raise ArgumentError, "`dimensions` must be non-negative" unless dimensions >= 0
|
16
25
|
|
@@ -18,64 +27,124 @@ class VectorNumber
|
|
18
27
|
end
|
19
28
|
|
20
29
|
# Whether this VectorNumber contains any non-numeric parts.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# VectorNumber[2].nonnumeric? # => false
|
33
|
+
# VectorNumber[2, 3i].nonnumeric? # => false
|
34
|
+
# VectorNumber[2, "a"].nonnumeric? # => true
|
35
|
+
# VectorNumber[2, 3i].nonnumeric?(1) # => true
|
36
|
+
#
|
21
37
|
# @param (see #numeric?)
|
22
38
|
# @return (see #numeric?)
|
23
39
|
# @raise (see #numeric?)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
!numeric?(dimensions)
|
28
|
-
end
|
40
|
+
#
|
41
|
+
# @since 0.2.1
|
42
|
+
def nonnumeric?(dimensions = 2) = !numeric?(dimensions)
|
29
43
|
|
30
44
|
# Returns +true+ if all coefficients are finite, +false+ otherwise.
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# VectorNumber[2].finite? # => true
|
48
|
+
# VectorNumber[Float::NAN].finite? # => false
|
49
|
+
# VectorNumber["a"].mult(Float::INFINITY).finite? # => false
|
50
|
+
#
|
31
51
|
# @return [Boolean]
|
52
|
+
#
|
53
|
+
# @since 0.1.0
|
32
54
|
def finite?
|
33
55
|
all? { |_u, v| v.finite? }
|
34
56
|
end
|
35
57
|
|
36
58
|
# Returns +1+ if any coefficients are infinite, +nil+ otherwise.
|
59
|
+
#
|
60
|
+
# This behavior is the same as +Complex+'s.
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# VectorNumber[2].infinite? # => nil
|
64
|
+
# VectorNumber[Float::NAN].infinite? # => 1
|
65
|
+
# VectorNumber["a"].mult(-Float::INFINITY).infinite? # => 1
|
66
|
+
#
|
37
67
|
# @return [1, nil]
|
68
|
+
#
|
69
|
+
# @since 0.1.0
|
38
70
|
def infinite?
|
39
71
|
finite? ? nil : 1 # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
|
40
72
|
end
|
41
73
|
|
42
74
|
# Returns +true+ if there are no non-zero coefficients, and +false+ otherwise.
|
75
|
+
#
|
76
|
+
# @example
|
77
|
+
# VectorNumber["c"].zero? # => false
|
78
|
+
# VectorNumber[].zero? # => true
|
79
|
+
#
|
43
80
|
# @return [Boolean]
|
44
|
-
|
45
|
-
|
46
|
-
|
81
|
+
#
|
82
|
+
# @since 0.1.0
|
83
|
+
def zero? = size.zero?
|
47
84
|
|
48
85
|
# Returns +self+ if there are any non-zero coefficients, +nil+ otherwise.
|
86
|
+
#
|
87
|
+
# This behavior is the same as +Numeric+'s.
|
88
|
+
#
|
89
|
+
# @example
|
90
|
+
# VectorNumber["ab", "cd"].nonzero? # => (1⋅'ab' + 1⋅'cd')
|
91
|
+
# VectorNumber[].nonzero? # => nil
|
92
|
+
#
|
49
93
|
# @return [VectorNumber, nil]
|
94
|
+
#
|
95
|
+
# @since 0.1.0
|
50
96
|
def nonzero?
|
51
97
|
zero? ? nil : self # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
|
52
98
|
end
|
53
99
|
|
54
100
|
# Returns +true+ if number is non-zero and all non-zero coefficients are positive,
|
55
101
|
# and +false+ otherwise.
|
102
|
+
#
|
103
|
+
# @example
|
104
|
+
# VectorNumber["a"].positive? # => true
|
105
|
+
# VectorNumber[2].neg.positive? # => false
|
106
|
+
# (VectorNumber["1"] - VectorNumber[1]).positive? # => false
|
107
|
+
# VectorNumber[0].positive? # => false
|
108
|
+
#
|
56
109
|
# @return [Boolean]
|
110
|
+
#
|
111
|
+
# @since 0.1.0
|
57
112
|
def positive?
|
58
113
|
!zero? && all? { |_u, c| c.positive? }
|
59
114
|
end
|
60
115
|
|
61
116
|
# Returns +true+ if number is non-zero and all non-zero coefficients are negative,
|
62
117
|
# and +false+ otherwise.
|
118
|
+
#
|
119
|
+
# @example
|
120
|
+
# VectorNumber["a"].neg.negative? # => true
|
121
|
+
# VectorNumber[-2].neg.negative? # => false
|
122
|
+
# (VectorNumber["1"] - VectorNumber[1]).negative? # => false
|
123
|
+
# VectorNumber[0].negative? # => false
|
124
|
+
#
|
63
125
|
# @return [Boolean]
|
126
|
+
#
|
127
|
+
# @since 0.1.0
|
64
128
|
def negative?
|
65
129
|
!zero? && all? { |_u, c| c.negative? }
|
66
130
|
end
|
67
131
|
|
68
|
-
# Always returns +false+, as vectors are
|
132
|
+
# Always returns +false+, as vectors are not real numbers.
|
133
|
+
#
|
134
|
+
# This behavior is the same as +Complex+'s.
|
135
|
+
#
|
69
136
|
# @see #numeric?
|
137
|
+
#
|
70
138
|
# @return [false]
|
71
|
-
|
72
|
-
|
73
|
-
|
139
|
+
#
|
140
|
+
# @since 0.1.0
|
141
|
+
def real? = false
|
74
142
|
|
75
143
|
# Always returns +false+, as vectors are not +Integer+s.
|
144
|
+
#
|
76
145
|
# @return [false]
|
77
|
-
|
78
|
-
|
79
|
-
|
146
|
+
#
|
147
|
+
# @since 0.2.1
|
148
|
+
def integer? = false
|
80
149
|
end
|
81
150
|
end
|
@@ -4,21 +4,37 @@ class VectorNumber
|
|
4
4
|
# Methods and options for string representation.
|
5
5
|
module Stringifying
|
6
6
|
# Predefined symbols for multiplication to display between unit and coefficient.
|
7
|
+
#
|
7
8
|
# @return [Hash{Symbol => String}]
|
9
|
+
#
|
10
|
+
# @since 0.1.0
|
8
11
|
MULT_STRINGS = {
|
9
12
|
asterisk: "*", # U+002A
|
10
13
|
cross: "×", # U+00D7
|
11
14
|
dot: "⋅", # U+22C5
|
12
15
|
invisible: "", # U+2062, zero-width multiplication operator
|
13
16
|
space: " ",
|
14
|
-
none: ""
|
17
|
+
none: "",
|
15
18
|
}.freeze
|
16
19
|
|
20
|
+
# Get a string representation of the vector.
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# VectorNumber[5, "s"].to_s # => "5 + 1⋅'s'"
|
24
|
+
# VectorNumber["s", 5].to_s # => "1⋅'s' + 5"
|
25
|
+
# @example with :mult argument
|
26
|
+
# VectorNumber[5, "s"].to_s(mult: :asterisk) # => "5 + 1*'s'"
|
27
|
+
# @example :mult option specified for the vector
|
28
|
+
# VectorNumber[5, "s", mult: :none].to_s # => "5 + 1's'"
|
29
|
+
#
|
17
30
|
# @param mult [Symbol, String]
|
18
31
|
# text to use between coefficient and unit,
|
19
32
|
# can be one of the keys in {MULT_STRINGS} or an arbitrary string
|
20
33
|
# @return [String]
|
21
|
-
# @raise [ArgumentError]
|
34
|
+
# @raise [ArgumentError]
|
35
|
+
# if +mult+ is not a String and is not in {MULT_STRINGS}'s keys
|
36
|
+
#
|
37
|
+
# @since 0.1.0
|
22
38
|
def to_s(mult: options[:mult])
|
23
39
|
return "0" if zero?
|
24
40
|
|
@@ -34,7 +50,18 @@ class VectorNumber
|
|
34
50
|
result
|
35
51
|
end
|
36
52
|
|
53
|
+
# Get a string representation of the vector.
|
54
|
+
#
|
55
|
+
# This is similar to +Complex#inspect+: it returns result of {#to_s} in round brackets.
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# VectorNumber[5, "s"].inspect # => "(5 + 1⋅'s')"
|
59
|
+
#
|
37
60
|
# @return [String]
|
61
|
+
#
|
62
|
+
# @see to_s
|
63
|
+
#
|
64
|
+
# @since 0.1.0
|
38
65
|
def inspect
|
39
66
|
# TODO: Probably make this independent of options.
|
40
67
|
"(#{self})"
|
@@ -47,6 +74,8 @@ class VectorNumber
|
|
47
74
|
# @param mult [Symbol, String]
|
48
75
|
# @return [String]
|
49
76
|
# @raise [ArgumentError] if +mult+ is not in {MULT_STRINGS}'s keys
|
77
|
+
#
|
78
|
+
# @since 0.1.0
|
50
79
|
def value_to_s(unit, coefficient, mult:)
|
51
80
|
if !mult.is_a?(String) && !MULT_STRINGS.key?(mult)
|
52
81
|
raise ArgumentError, "unknown key #{mult.inspect}", caller
|
data/lib/vector_number.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "vector_number/
|
4
|
-
require_relative "vector_number/mathing"
|
5
|
-
require_relative "vector_number/math_converting"
|
3
|
+
require_relative "vector_number/comparing"
|
6
4
|
require_relative "vector_number/converting"
|
7
5
|
require_relative "vector_number/enumerating"
|
8
|
-
require_relative "vector_number/
|
6
|
+
require_relative "vector_number/math_converting"
|
7
|
+
require_relative "vector_number/mathing"
|
9
8
|
require_relative "vector_number/querying"
|
10
9
|
require_relative "vector_number/stringifying"
|
10
|
+
require_relative "vector_number/version"
|
11
11
|
|
12
12
|
# A class to add together anything.
|
13
13
|
class VectorNumber
|
@@ -19,41 +19,87 @@ class VectorNumber
|
|
19
19
|
include Querying
|
20
20
|
include Stringifying
|
21
21
|
|
22
|
+
# Keys for possible options.
|
23
|
+
# Unknown options will be rejected when creating a vector.
|
24
|
+
#
|
22
25
|
# @return [Array<Symbol>]
|
26
|
+
#
|
27
|
+
# @since 0.2.0
|
23
28
|
KNOWN_OPTIONS = %i[mult].freeze
|
24
29
|
|
30
|
+
# Default values for options.
|
31
|
+
#
|
25
32
|
# @return [Hash{Symbol => Object}]
|
33
|
+
#
|
34
|
+
# @since 0.2.0
|
26
35
|
DEFAULT_OPTIONS = { mult: :dot }.freeze
|
27
36
|
|
28
37
|
# Get a unit for +n+th numeric dimension, where 1 is real, 2 is imaginary.
|
29
|
-
|
38
|
+
#
|
39
|
+
# @since 0.2.0
|
40
|
+
UNIT = ->(n) { n }.freeze
|
30
41
|
# Constant for real unit.
|
42
|
+
#
|
43
|
+
# @since 0.2.0
|
31
44
|
R = UNIT[1]
|
32
45
|
# Constant for imaginary unit.
|
46
|
+
#
|
47
|
+
# @since 0.1.0
|
33
48
|
I = UNIT[2]
|
34
49
|
|
35
|
-
#
|
36
|
-
# @return [Integer]
|
37
|
-
attr_reader :size
|
38
|
-
# @return [Hash{Symbol => Object}]
|
39
|
-
attr_reader :options
|
40
|
-
|
41
|
-
# Create new VectorNumber from +values+.
|
50
|
+
# Create new VectorNumber from a list of values, possibly specifying options.
|
42
51
|
#
|
43
52
|
# @example
|
44
|
-
# VectorNumber[1, 2, 3]
|
45
|
-
# VectorNumber[[1, 2, 3]]
|
46
|
-
# VectorNumber[
|
53
|
+
# VectorNumber[1, 2, 3] # => (6)
|
54
|
+
# VectorNumber[[1, 2, 3]] # => (1⋅[1, 2, 3])
|
55
|
+
# VectorNumber["b", VectorNumber::I, mult: :asterisk] # => (1*'b' + 1i)
|
56
|
+
# VectorNumber[] # => (0)
|
57
|
+
# VectorNumber["b", VectorNumber["b"]] # => (2⋅'b')
|
58
|
+
# VectorNumber["a", "b", "a"] # => (2⋅'a' + 1⋅'b')
|
59
|
+
#
|
47
60
|
# @param values [Array<Object>] values to put in the number
|
48
61
|
# @param options [Hash{Symbol => Object}] options for the number
|
62
|
+
# @option options [Symbol, String] :mult Multiplication symbol,
|
63
|
+
# either a key from {MULT_STRINGS} or a literal string to use
|
49
64
|
# @return [VectorNumber]
|
65
|
+
#
|
66
|
+
# @since 0.1.0
|
50
67
|
def self.[](*values, **options)
|
51
68
|
new(values, options)
|
52
69
|
end
|
53
70
|
|
54
|
-
#
|
71
|
+
# Number of non-zero dimensions.
|
72
|
+
#
|
73
|
+
# @return [Integer]
|
74
|
+
#
|
75
|
+
# @since 0.1.0
|
76
|
+
attr_reader :size
|
77
|
+
|
78
|
+
# Options used for this vector.
|
79
|
+
#
|
80
|
+
# @see KNOWN_OPTIONS
|
81
|
+
#
|
82
|
+
# @return [Hash{Symbol => Object}]
|
83
|
+
#
|
84
|
+
# @since 0.1.0
|
85
|
+
attr_reader :options
|
86
|
+
|
87
|
+
# Create new VectorNumber from +values+, possibly specifying +options+,
|
88
|
+
# possibly modifying coefficients with a block.
|
89
|
+
#
|
90
|
+
# @example
|
91
|
+
# VectorNumber.new(1, 2, 3) # ArgumentError
|
92
|
+
# VectorNumber.new([1, 2, 3]) # => (6)
|
93
|
+
# VectorNumber.new(["b", VectorNumber::I], mult: :asterisk) # => (1*'b' + 1i)
|
94
|
+
# VectorNumber.new # => (0)
|
95
|
+
# @example with a block
|
96
|
+
# VectorNumber.new(["a", "b", "c", 3]) { _1 * 2 } # => (2⋅'a' + 2⋅'b' + 2⋅'c' + 6)
|
97
|
+
# VectorNumber.new(["a", "b", "c", 3], &:-@) # => (-1⋅'a' - 1⋅'b' - 1⋅'c' - 3)
|
98
|
+
# VectorNumber.new(["a", "b", "c", 3], &:digits) # RangeError
|
99
|
+
#
|
100
|
+
# @param values [Array, VectorNumber, Hash{Object => Integer, Float, Rational, BigDecimal}, nil]
|
55
101
|
# values for this number, hashes are treated like plain vector numbers
|
56
|
-
# @param options [Hash{Symbol => Object}]
|
102
|
+
# @param options [Hash{Symbol => Object}, nil]
|
57
103
|
# options for this number, if +values+ is a VectorNumber or contains it,
|
58
104
|
# these will be merged with options from its +options+
|
59
105
|
# @option options [Symbol, String] :mult
|
@@ -62,7 +108,7 @@ class VectorNumber
|
|
62
108
|
# @yieldreturn [Integer, Float, Rational, BigDecimal] new coefficient
|
63
109
|
# @raise [RangeError] if any pesky non-reals get where they shouldn't
|
64
110
|
def initialize(values = nil, options = nil, &)
|
65
|
-
# @type var options: Hash[Symbol,
|
111
|
+
# @type var options: Hash[Symbol, Object]
|
66
112
|
initialize_from(values)
|
67
113
|
apply_transform(&)
|
68
114
|
finalize_contents
|
@@ -75,13 +121,18 @@ class VectorNumber
|
|
75
121
|
# Return self.
|
76
122
|
#
|
77
123
|
# @return [VectorNumber]
|
78
|
-
|
124
|
+
#
|
125
|
+
# @since 0.2.0
|
126
|
+
def +@ = self
|
127
|
+
# @since 0.2.4
|
128
|
+
alias dup +@
|
79
129
|
|
80
130
|
# Return self.
|
81
131
|
#
|
82
|
-
# Raises ArgumentError if +freeze+ is not +true+ or +nil+.
|
83
|
-
#
|
84
132
|
# @return [VectorNumber]
|
133
|
+
# @raise [ArgumentError] if +freeze+ is not +true+ or +nil+.
|
134
|
+
#
|
135
|
+
# @since 0.2.4
|
85
136
|
def clone(freeze: true)
|
86
137
|
case freeze
|
87
138
|
when true, nil
|
@@ -96,6 +147,7 @@ class VectorNumber
|
|
96
147
|
private
|
97
148
|
|
98
149
|
# Create new VectorNumber from a value or self, optionally applying a transform.
|
150
|
+
#
|
99
151
|
# @param from [Object] self if not specified
|
100
152
|
# @yieldparam coefficient [Integer, Float, Rational, BigDecimal]
|
101
153
|
# @yieldreturn [Integer, Float, Rational, BigDecimal] new coefficient
|
@@ -104,29 +156,42 @@ class VectorNumber
|
|
104
156
|
self.class.new(from, options, &)
|
105
157
|
end
|
106
158
|
|
159
|
+
# Check if +other+ is a real number.
|
160
|
+
#
|
161
|
+
# Currently this is either a +real?+ Numeric or +numeric?(1)+ VectorNumber.
|
162
|
+
#
|
107
163
|
# @param value [Object]
|
108
164
|
# @return [Boolean]
|
165
|
+
#
|
166
|
+
# @since 0.1.0
|
109
167
|
def real_number?(value)
|
110
168
|
(value.is_a?(Numeric) && value.real?) || (value.is_a?(self.class) && value.numeric?(1))
|
111
169
|
end
|
112
170
|
|
113
171
|
# @param values [Array, Hash{Object => Integer, Float, Rational, BigDecimal}, VectorNumber, nil]
|
114
172
|
# @return [void]
|
173
|
+
#
|
174
|
+
# @since 0.1.0
|
115
175
|
def initialize_from(values)
|
116
|
-
@data =
|
176
|
+
@data = values.to_h and return if values.is_a?(VectorNumber)
|
117
177
|
|
178
|
+
@data = Hash.new(0)
|
118
179
|
case values
|
119
|
-
when VectorNumber, Hash
|
120
|
-
add_vector_to_data(values)
|
121
180
|
when Array
|
122
181
|
values.each { |value| add_value_to_data(value) }
|
182
|
+
when Hash
|
183
|
+
add_vector_to_data(values)
|
184
|
+
when nil
|
185
|
+
# Do nothing, as there are no values.
|
123
186
|
else
|
124
|
-
|
187
|
+
raise ArgumentError, "unsupported type for values: #{values.class}"
|
125
188
|
end
|
126
189
|
end
|
127
190
|
|
128
191
|
# @param value [VectorNumber, Numeric, Object]
|
129
192
|
# @return [void]
|
193
|
+
#
|
194
|
+
# @since 0.1.0
|
130
195
|
def add_value_to_data(value)
|
131
196
|
case value
|
132
197
|
when Numeric
|
@@ -140,13 +205,19 @@ class VectorNumber
|
|
140
205
|
|
141
206
|
# @param value [Numeric]
|
142
207
|
# @return [void]
|
208
|
+
#
|
209
|
+
# @since 0.1.0
|
143
210
|
def add_numeric_value_to_data(value)
|
144
211
|
@data[R] += value.real
|
145
|
-
|
212
|
+
# Most numbers will be real, and this extra condition appreciably speeds up addition,
|
213
|
+
# while having no noticeable impact on complex numbers.
|
214
|
+
@data[I] += value.imaginary unless value.real?
|
146
215
|
end
|
147
216
|
|
148
217
|
# @param vector [VectorNumber, Hash{Object => Integer, Float, Rational, BigDecimal}]
|
149
218
|
# @return [void]
|
219
|
+
#
|
220
|
+
# @since 0.1.0
|
150
221
|
def add_vector_to_data(vector)
|
151
222
|
vector.each_pair do |unit, coefficient|
|
152
223
|
raise RangeError, "#{coefficient} is not a real number" unless real_number?(coefficient)
|
@@ -159,6 +230,8 @@ class VectorNumber
|
|
159
230
|
# @yieldreturn [Integer, Float, Rational, BigDecimal]
|
160
231
|
# @return [void]
|
161
232
|
# @raise [RangeError]
|
233
|
+
#
|
234
|
+
# @since 0.1.0
|
162
235
|
def apply_transform
|
163
236
|
return unless block_given?
|
164
237
|
|
@@ -173,44 +246,40 @@ class VectorNumber
|
|
173
246
|
# @param options [Hash{Symbol => Object}, nil]
|
174
247
|
# @param values [Object] initializing object
|
175
248
|
# @return [void]
|
249
|
+
#
|
250
|
+
# @since 0.1.0
|
176
251
|
def save_options(options, values:)
|
177
252
|
@options =
|
178
|
-
case
|
179
|
-
in
|
180
|
-
values.options
|
181
|
-
in [{} | nil, [*, VectorNumber => vector, *]]
|
182
|
-
vector.options
|
183
|
-
in Hash, VectorNumber
|
253
|
+
case values
|
254
|
+
in VectorNumber
|
184
255
|
merge_options(values.options, options)
|
185
|
-
in
|
256
|
+
in Array[*, VectorNumber => vector, *]
|
186
257
|
merge_options(vector.options, options)
|
187
|
-
in Hash, _ unless options.empty?
|
188
|
-
merge_options(default_options, options)
|
189
258
|
else
|
190
|
-
|
259
|
+
merge_options(DEFAULT_OPTIONS, options)
|
191
260
|
end
|
192
261
|
end
|
193
262
|
|
263
|
+
# @param base_options [Hash{Symbol => Object}]
|
264
|
+
# @param added_options [Hash{Symbol => Object}, nil]
|
265
|
+
# @return [Hash{Symbol => Object}]
|
266
|
+
#
|
267
|
+
# @since 0.3.0
|
194
268
|
def merge_options(base_options, added_options)
|
269
|
+
return base_options if !added_options || added_options.empty?
|
195
270
|
# Optimization for the common case of passing options through #new.
|
196
271
|
return base_options if added_options.equal?(base_options)
|
197
272
|
|
198
|
-
base_options.merge(added_options).slice(*
|
273
|
+
base_options.merge(added_options).slice(*KNOWN_OPTIONS)
|
199
274
|
end
|
200
275
|
|
201
276
|
# Compact coefficients, calculate size and freeze data.
|
202
277
|
# @return [void]
|
278
|
+
#
|
279
|
+
# @since 0.1.0
|
203
280
|
def finalize_contents
|
204
281
|
@data.delete_if { |_u, c| c.zero? }
|
205
282
|
@data.freeze
|
206
283
|
@size = @data.size
|
207
284
|
end
|
208
|
-
|
209
|
-
def default_options
|
210
|
-
DEFAULT_OPTIONS
|
211
|
-
end
|
212
|
-
|
213
|
-
def known_options
|
214
|
-
KNOWN_OPTIONS
|
215
|
-
end
|
216
285
|
end
|
data/sig/vector_number.rbs
CHANGED
@@ -55,7 +55,8 @@ class VectorNumber
|
|
55
55
|
?{ (coefficient_type coefficient) -> coefficient_type }
|
56
56
|
-> void
|
57
57
|
|
58
|
-
def
|
58
|
+
def +@: () -> self
|
59
|
+
alias dup +@
|
59
60
|
|
60
61
|
def clone: (?freeze: bool?) -> self
|
61
62
|
|
@@ -76,6 +77,7 @@ class VectorNumber
|
|
76
77
|
def apply_transform: () ?{ (coefficient_type value) -> coefficient_type } -> void
|
77
78
|
|
78
79
|
def save_options: (options_type? options, values: in_value_type) -> void
|
80
|
+
def merge_options: (options_type base_options, options_type added_options) -> options_type
|
79
81
|
def default_options: () -> options_type
|
80
82
|
def known_options: () -> list[Symbol]
|
81
83
|
|
@@ -87,8 +89,6 @@ class VectorNumber
|
|
87
89
|
|
88
90
|
def coerce: (in_value_type) -> [vector_type, self]
|
89
91
|
|
90
|
-
def +@: () -> self
|
91
|
-
|
92
92
|
def -@: () -> vector_type
|
93
93
|
alias neg -@
|
94
94
|
|
metadata
CHANGED
@@ -1,21 +1,26 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vector_number
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandr Bulancov
|
8
|
+
autorequire:
|
8
9
|
bindir: exe
|
9
10
|
cert_chain: []
|
10
|
-
date: 2025-
|
11
|
+
date: 2025-07-07 00:00:00.000000000 Z
|
11
12
|
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
12
15
|
executables: []
|
13
16
|
extensions: []
|
14
17
|
extra_rdoc_files:
|
15
18
|
- README.md
|
16
19
|
- CHANGELOG.md
|
20
|
+
- LICENSE.txt
|
17
21
|
files:
|
18
22
|
- CHANGELOG.md
|
23
|
+
- LICENSE.txt
|
19
24
|
- README.md
|
20
25
|
- lib/vector_number.rb
|
21
26
|
- lib/vector_number/comparing.rb
|
@@ -33,12 +38,17 @@ licenses:
|
|
33
38
|
- MIT
|
34
39
|
metadata:
|
35
40
|
homepage_uri: https://github.com/trinistr/vector_number
|
36
|
-
|
37
|
-
|
41
|
+
bug_tracker_uri: https://github.com/trinistr/vector_number/issues
|
42
|
+
documentation_uri: https://rubydoc.info/gems/vector_number/0.4.0
|
43
|
+
source_code_uri: https://github.com/trinistr/vector_number/tree/v0.4.0
|
44
|
+
changelog_uri: https://github.com/trinistr/vector_number/blob/v0.4.0/CHANGELOG.md
|
38
45
|
rubygems_mfa_required: 'true'
|
46
|
+
post_install_message:
|
39
47
|
rdoc_options:
|
40
48
|
- "--main"
|
41
49
|
- README.md
|
50
|
+
- "--files"
|
51
|
+
- CHANGELOG.md,LICENSE.txt
|
42
52
|
require_paths:
|
43
53
|
- lib
|
44
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -52,7 +62,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
62
|
- !ruby/object:Gem::Version
|
53
63
|
version: '0'
|
54
64
|
requirements: []
|
55
|
-
rubygems_version: 3.
|
65
|
+
rubygems_version: 3.4.19
|
66
|
+
signing_key:
|
56
67
|
specification_version: 4
|
57
68
|
summary: A library to add together anything.
|
58
69
|
test_files: []
|