vector_number 0.4.2 → 0.5.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/README.md +2 -2
- data/lib/vector_number/comparing.rb +110 -107
- data/lib/vector_number/converting.rb +152 -147
- data/lib/vector_number/enumerating.rb +107 -108
- data/lib/vector_number/math_converting.rb +113 -109
- data/lib/vector_number/mathing.rb +305 -312
- data/lib/vector_number/numeric_refinements.rb +22 -3
- data/lib/vector_number/querying.rb +143 -136
- data/lib/vector_number/stringifying.rb +79 -82
- data/lib/vector_number/version.rb +1 -1
- data/lib/vector_number.rb +125 -55
- data/sig/vector_number.rbs +128 -161
- metadata +6 -6
|
@@ -1,128 +1,127 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class VectorNumber
|
|
4
|
-
#
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
#
|
|
11
|
+
# @since 0.1.0
|
|
12
|
+
include ::Enumerable
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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 [Numeric]
|
|
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?
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
@data.each(&block)
|
|
43
|
+
self
|
|
44
|
+
end
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
# @since 0.1.0
|
|
47
|
+
alias each_pair each
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
# @since 0.1.0
|
|
61
|
+
alias keys units
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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<Numeric>]
|
|
70
|
+
#
|
|
71
|
+
# @since 0.1.0
|
|
72
|
+
def coefficients = @data.values
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
# @since 0.1.0
|
|
75
|
+
alias values coefficients
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
end
|
|
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 => Numeric}]
|
|
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
|
|
95
94
|
end
|
|
95
|
+
end
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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 [Numeric]
|
|
109
|
+
#
|
|
110
|
+
# @since 0.2.4
|
|
111
|
+
def [](unit) = @data[unit]
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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)
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
end
|
|
125
|
+
# @since 0.2.4
|
|
126
|
+
alias key? unit?
|
|
128
127
|
end
|
|
@@ -1,121 +1,125 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class VectorNumber
|
|
4
|
-
#
|
|
5
|
-
module MathConverting
|
|
6
|
-
# Calculate the absolute value of the vector, i.e. 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
|
|
4
|
+
# @group Mathematical operations
|
|
19
5
|
|
|
20
|
-
|
|
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
|
|
21
19
|
|
|
22
|
-
|
|
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
|
|
20
|
+
alias magnitude abs
|
|
35
21
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def truncate(digits = 0)
|
|
50
|
-
new { _1.truncate(digits) }
|
|
51
|
-
end
|
|
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
|
|
52
35
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
36
|
+
# Return a new vector with every coefficient truncated using their +#truncate+.
|
|
37
|
+
#
|
|
38
|
+
# @example
|
|
39
|
+
# VectorNumber[5.39].truncate # => (5)
|
|
40
|
+
# VectorNumber[-5.35i].truncate # => (-5i)
|
|
41
|
+
# VectorNumber[-5.35i, "i"].truncate # => (-5i + 1⋅'i')
|
|
42
|
+
# VectorNumber[-5.35i, "i"].truncate(1) # => (-5.3i + 1⋅'i')
|
|
43
|
+
# VectorNumber[-5.35i, "i"].truncate(-1) # => (0)
|
|
44
|
+
#
|
|
45
|
+
# @param digits [Integer]
|
|
46
|
+
# @return [VectorNumber]
|
|
47
|
+
#
|
|
48
|
+
# @since 0.2.1
|
|
49
|
+
def truncate(digits = 0)
|
|
50
|
+
new { _1.truncate(digits) }
|
|
51
|
+
end
|
|
69
52
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
53
|
+
# Return a new vector with every coefficient rounded using their +#ceil+.
|
|
54
|
+
#
|
|
55
|
+
# @example
|
|
56
|
+
# VectorNumber[5.39].ceil # => (6)
|
|
57
|
+
# VectorNumber[-5.35i].ceil # => (-5i)
|
|
58
|
+
# VectorNumber[-5.35i, "i"].ceil # => (-5i + 1⋅'i')
|
|
59
|
+
# VectorNumber[-5.35i, "i"].ceil(1) # => (-5.3i + 1⋅'i')
|
|
60
|
+
# VectorNumber[-5.35i, "i"].ceil(-1) # => (10⋅'i')
|
|
61
|
+
#
|
|
62
|
+
# @param digits [Integer]
|
|
63
|
+
# @return [VectorNumber]
|
|
64
|
+
#
|
|
65
|
+
# @since 0.2.2
|
|
66
|
+
def ceil(digits = 0)
|
|
67
|
+
new { _1.ceil(digits) }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Return a new vector with every coefficient rounded using their +#floor+.
|
|
71
|
+
#
|
|
72
|
+
# @example
|
|
73
|
+
# VectorNumber[5.39].floor # => (5)
|
|
74
|
+
# VectorNumber[-5.35i].floor # => (-6i)
|
|
75
|
+
# VectorNumber[-5.35i, "i"].floor # => (-6i + 1⋅'i')
|
|
76
|
+
# VectorNumber[-5.35i, "i"].floor(1) # => (-5.4i + 1⋅'i')
|
|
77
|
+
# VectorNumber[-5.35i, "i"].floor(-1) # => (-10i)
|
|
78
|
+
#
|
|
79
|
+
# @param digits [Integer]
|
|
80
|
+
# @return [VectorNumber]
|
|
81
|
+
#
|
|
82
|
+
# @since 0.2.2
|
|
83
|
+
def floor(digits = 0)
|
|
84
|
+
new { _1.floor(digits) }
|
|
85
|
+
end
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
87
|
+
# Return a new vector with every coefficient rounded using their +#round+.
|
|
88
|
+
#
|
|
89
|
+
# In the case of +BigDecimal+ coefficients, the +half+ parameter is converted
|
|
90
|
+
# to the corresponding +BigDecimal+ rounding mode
|
|
91
|
+
# (one of +:half_up+, +:half_down+, or +:half_even+).
|
|
92
|
+
# Other modes can not be specified.
|
|
93
|
+
#
|
|
94
|
+
# @example
|
|
95
|
+
# VectorNumber[-4.5i, "i"].round(half: :up) # => (-5i + 1⋅'i')
|
|
96
|
+
# VectorNumber[-4.5i, "i"].round(half: :even) # => (-4i + 1⋅'i')
|
|
97
|
+
# VectorNumber[-5.5i, "i"].round(half: :even) # => (-6i + 1⋅'i')
|
|
98
|
+
# VectorNumber[-5.5i, "i"].round(half: :down) # => (-5i + 1⋅'i')
|
|
99
|
+
# VectorNumber[-5.35i, "i"].round(1) # => (-5.4i + 1⋅'i')
|
|
100
|
+
# VectorNumber[-5.35i, "i"].round(-1) # => (-10i)
|
|
101
|
+
#
|
|
102
|
+
# @param digits [Integer]
|
|
103
|
+
# @param half [Symbol, nil] one of +:up+, +:down+ or +:even+,
|
|
104
|
+
# see +Float#round+ for meaning
|
|
105
|
+
# @return [VectorNumber]
|
|
106
|
+
#
|
|
107
|
+
# @see Float#round
|
|
108
|
+
#
|
|
109
|
+
# @since 0.2.2
|
|
110
|
+
def round(digits = 0, half: :up)
|
|
111
|
+
if defined?(BigDecimal)
|
|
112
|
+
bd_mode =
|
|
113
|
+
case half
|
|
114
|
+
when :down then :half_down
|
|
115
|
+
when :even then :half_even
|
|
116
|
+
else :half_up
|
|
117
|
+
end
|
|
118
|
+
new { _1.is_a?(BigDecimal) ? _1.round(digits, bd_mode) : _1.round(digits, half: half) }
|
|
119
|
+
# :nocov:
|
|
120
|
+
else
|
|
121
|
+
new { _1.round(digits, half: half) }
|
|
119
122
|
end
|
|
123
|
+
# :nocov:
|
|
120
124
|
end
|
|
121
125
|
end
|