vector_number 0.3.0 → 0.3.1

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
  SHA256:
3
- metadata.gz: c55a93e873d8e98092a5be77940f3f91cf06e90abb973f16d2fc91f0df0276ca
4
- data.tar.gz: 446cb27d60ff3b588ffbc6fa49489013d6a2cfc8e6f2b577abc4a40b47587658
3
+ metadata.gz: b935cacefb185478f7f923046b28589c6da2763574c315f19c6b8050cd5835e1
4
+ data.tar.gz: a93dd71a4de2d07255962e13a81a357c92f5a1653d916e95d5a54a99afa984a6
5
5
  SHA512:
6
- metadata.gz: 2a069408f786816659721505e8e09d50aeaf891e6dcc85c35d008a161500548e74c3cb0224a8992521c3e9385cb8cabe6c9b565874981c0098d5fb5c081ee65f
7
- data.tar.gz: 99c2b90210dfceaeec85f6f8fd897074296c27ba6e9a6cb8ffcd0d407b3f65482b445b721fd5a41139a339d5d54f8ce81f4860dfdffccc0db1909002744fa8fe
6
+ metadata.gz: 9d6ea64b09d12434470d65c7ff808b63b9ccc59cb1e479bc7659ed973a8f03a3fb137dfe3641163dc56b06163b7d0c472ed74af2f49f6623b866eff90961aa7c
7
+ data.tar.gz: 85a927c88c99533e434a185a239f2d129567adf8d2e8c4d8d62e6239560d889e24fc7d3e478039b6d8c4213596e9ea7a61da5d0ab867162f9fbe7bee4edf05e5
data/CHANGELOG.md CHANGED
@@ -6,6 +6,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ## [Next]
9
+ ## [v0.3.1] — 2025-06-21
10
+
11
+ This is mostly a documentation update with a side of improved gemspec.
12
+
13
+ **Changed**
14
+ - Improve method documentation and unify documentation style across the board.
15
+ - Improve gemspec:
16
+ - change source code and changelog links to point to a tagged commit;
17
+ - add links to bugtracker and documentation (for appropriate version);
18
+ - properly add CHANGELOG.md to doc generation.
19
+ - Improve documentation for NumericRefinements to include examples and more info.
20
+ - `#dup` is now an alias of `#+@` with no change in function.
21
+ - `#abs` is now calculated from `#abs2` instead of the other way around to reduce errors.
22
+
23
+ **Fixed**
24
+ - Correct broken changelog link in gem metadata.
25
+
26
+ [Compare v0.3.0...main](https://github.com/trinistr/vector_number/compare/v0.3.0...main)
27
+
9
28
  ## [v0.3.0] — 2025-05-12
10
29
 
11
30
  **Added**
@@ -18,7 +37,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
18
37
  When creating new vector through any operation, participating vector's options
19
38
  are copied to the new one. When several vectors are present, only first one matters.
20
39
  - Both `#+@` and `#dup` are now aliases of `#itself` instead of full methods.
21
- - [🚀 CI] Refactor workflows to reduce duplication.
40
+ - [🚀 CI] "CI" workflow now reports status of all checks,
41
+ excluding allowed-to-fail workflows (currently JRuby and TruffleRuby).
42
+
43
+ [Compare v0.2.6...v0.3.0](https://github.com/trinistr/vector_number/compare/v0.2.6...v0.3.0)
22
44
 
23
45
  ## [v0.2.6] — 2025-04-30
24
46
 
@@ -33,11 +55,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
33
55
  **Changed**
34
56
  - [🚀 CI] Add Ruby 3.4 to CI.
35
57
 
58
+ [Compare v0.2.5...v0.2.6](https://github.com/trinistr/vector_number/compare/v0.2.5...v0.2.6)
59
+
36
60
  ## [v0.2.5] — 2025-02-26
37
61
 
38
62
  Technical update after release to rubygems.org.
39
63
  README was updated to reflect this change.
40
64
 
65
+ [Compare v0.2.4...v0.2.5](https://github.com/trinistr/vector_number/compare/v0.2.4...v0.2.5)
66
+
41
67
  ## [v0.2.4] — 2025-02-26
42
68
 
43
69
  **Added**
@@ -55,11 +81,15 @@ README was updated to reflect this change.
55
81
  **Fixed**
56
82
  - `#dup` and `#clone` now behave exactly like Numeric versions, preventing unfreezing.
57
83
 
84
+ [Compare v0.2.3...v0.2.4](https://github.com/trinistr/vector_number/compare/v0.2.3...v0.2.4)
85
+
58
86
  ## [v0.2.3] — 2024-10-15
59
87
 
60
88
  **Fixed**
61
89
  - BigDecimal tests are now properly skipped when BigDecimal is not available, instead of always.
62
90
 
91
+ [Compare v0.2.2...v0.2.3](https://github.com/trinistr/vector_number/compare/v0.2.2...v0.2.3)
92
+
63
93
  ## [v0.2.2] — 2024-10-07
64
94
 
65
95
  **Added**
@@ -74,6 +104,8 @@ README was updated to reflect this change.
74
104
  **Fixed**
75
105
  - `Kernel#BigDecimal` refinement now correctly works without `ndigits` argument.
76
106
 
107
+ [Compare v0.2.1...v0.2.2](https://github.com/trinistr/vector_number/compare/v0.2.1...v0.2.2)
108
+
77
109
  ## [v0.2.1] — 2024-08-24
78
110
 
79
111
  **Added**
@@ -90,6 +122,8 @@ README was updated to reflect this change.
90
122
  - Remove `#to_str`, as VectorNumber is not a String-like object.
91
123
  - Due to the above, `Kernel.BigDecimal` no longer works without refinements.
92
124
 
125
+ [Compare v0.2.0...v0.2.1](https://github.com/trinistr/vector_number/compare/v0.2.0...v0.2.1)
126
+
93
127
  ## [v0.2.0] — 2024-08-19
94
128
 
95
129
  **Added**
@@ -97,8 +131,20 @@ README was updated to reflect this change.
97
131
  - Addition and subtraction are supported.
98
132
  - VectorNumbers are mostly interoperable with core numbers.
99
133
 
134
+ [Compare v0.1.0...v0.2.0](https://github.com/trinistr/vector_number/compare/v0.1.0...v0.2.0)
135
+
100
136
  ## [v0.1.0] — 2024-05-09
101
137
 
102
138
  - Initial work.
103
139
 
140
+ [Next]: https://github.com/trinistr/vector_number/tree/main
141
+ [v0.3.0]: https://github.com/trinistr/vector_number/tree/v0.3.0
142
+ [v0.2.6]: https://github.com/trinistr/vector_number/tree/v0.2.6
143
+ [v0.2.5]: https://github.com/trinistr/vector_number/tree/v0.2.5
144
+ [v0.2.4]: https://github.com/trinistr/vector_number/tree/v0.2.4
145
+ [v0.2.3]: https://github.com/trinistr/vector_number/tree/v0.2.3
146
+ [v0.2.2]: https://github.com/trinistr/vector_number/tree/v0.2.2
147
+ [v0.2.1]: https://github.com/trinistr/vector_number/tree/v0.2.1
148
+ [v0.2.0]: https://github.com/trinistr/vector_number/tree/v0.2.0
149
+ [v0.1.0]: https://github.com/trinistr/vector_number/tree/v0.1.0
104
150
  [🚀 CI]: https://github.com/trinistr/vector_number/actions/workflows/CI.yaml
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024-2025 Alexandr Bulancov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,26 +1,35 @@
1
1
  # VectorNumber
2
2
 
3
+ > [!TIP]
4
+ > You may be viewing documentation for an older (or newer) version of the gem.
5
+ > Check badges below to see what the latest released version is.
6
+ > Look at [Changelog](https://github.com/trinistr/vector_number/blob/main/CHANGELOG.md)
7
+ > to see all versions, including unreleased changes!
8
+
9
+ Latest: [![Gem Version](https://badge.fury.io/rb/vector_number.svg?icon=si%3Arubygems)](https://rubygems.org/gems/vector_number)
3
10
  [![CI](https://github.com/trinistr/vector_number/actions/workflows/CI.yaml/badge.svg)](https://github.com/trinistr/vector_number/actions/workflows/CI.yaml)
4
11
 
5
- A library to add together anything: be it a number, string or random Object, it can be added together in an infinite-dimensional vector space, with math operations available on results.
12
+ ***
6
13
 
7
- This is similar in a sense to hypercomplex numbers, such as quaternions, but with a focus on arbitrary dimensions.
14
+ A library to add together anything: be it a number, string or random Object, it can be added together with math operations available on results in a real vector space, though some operations are modeled on hypercomplex numbers.
8
15
 
9
16
  Similar projects:
10
- - [vector_space](https://github.com/tomstuart/vector_space) aims to provide typed vector spaces with limited dimensions and nice formatting.
11
- - [named_vector](https://rubygems.org/gems/named_vector) provides simple vectors with named dimensions.
12
- - Various quaternion libraries.
17
+ - [vector_space](https://github.com/tomstuart/vector_space) aims to provide typed vector spaces with limited dimensions and nice formatting;
18
+ - [named_vector](https://rubygems.org/gems/named_vector) provides simple vectors with named dimensions;
19
+ - various quaternion libraries like [quaternion](https://github.com/tanahiro/quaternion) or [rmath3d](https://github.com/vaiorabbit/rmath3d).
20
+
21
+ However, none of them have been updated in *years*.
13
22
 
14
23
  ## Installation
15
24
 
16
25
  VectorNumber does not have any dependencies and does not include extensions.
17
26
 
18
- Install with `gem` (available from 0.2.4):
27
+ Install with `gem` (available from [0.2.4](https://github.com/trinistr/vector_number/tree/v0.2.4)):
19
28
  ```sh
20
29
  gem install vector_number
21
30
  ```
22
31
 
23
- If using `bundler`, add gem to your Gemfile:
32
+ If using Bundler, add gem to your Gemfile:
24
33
  ```ruby
25
34
  gem "vector_number"
26
35
  ```
@@ -2,17 +2,33 @@
2
2
 
3
3
  class VectorNumber
4
4
  # Methods for comparing with other numbers.
5
+ #
6
+ # +Comparable+ is included for parity with numbers.
7
+ # @example using Comparable methods
8
+ # VectorNumber[12] < 0 # => false
9
+ # VectorNumber[12, "a"] < 0 # ArgumentError
10
+ # (VectorNumber[12]..VectorNumber[15]).include?(13) # => true
5
11
  module Comparing
12
+ # @since 0.2.0
6
13
  include ::Comparable
7
14
 
8
15
  # Compare to +other+ for equality.
9
16
  #
10
17
  # Values are considered equal if
11
18
  # - +other+ is a VectorNumber and it is +eql?+ to this one, or
12
- # - +other+ is a Numeric equal in value to this number.
19
+ # - +other+ is a Numeric equal in value to this (real or complex) number.
20
+ #
21
+ # @example
22
+ # VectorNumber[3.13] == 3.13 # => true
23
+ # VectorNumber[1.4, 1.5i] == Complex(1.4, 1.5) # => true
24
+ # VectorNumber["a", "b", "c"] == VectorNumber["c", "b", "a"] # => true
25
+ # VectorNumber["a", 14] == 14 # => false
26
+ # VectorNumber["a"] == "a" # => false
13
27
  #
14
28
  # @param other [Object]
15
29
  # @return [Boolean]
30
+ #
31
+ # @since 0.2.0
16
32
  def ==(other)
17
33
  return true if eql?(other)
18
34
 
@@ -25,8 +41,24 @@ class VectorNumber
25
41
  end
26
42
  end
27
43
 
44
+ # Compare to +other+ for strict equality.
45
+ #
46
+ # Values are considered equal only if +other+ is a VectorNumber
47
+ # and it has exactly the same units and coefficients, though possibly in a different order.
48
+ #
49
+ # Note that {#options} are not considered for equality.
50
+ #
51
+ # @example
52
+ # VectorNumber["a", "b", "c"].eql? VectorNumber["c", "b", "a"] # => true
53
+ # VectorNumber[3.13].eql? 3.13 # => false
54
+ # VectorNumber[1.4, 1.5i].eql? Complex(1.4, 1.5) # => false
55
+ # VectorNumber["a", 14].eql? 14 # => false
56
+ # VectorNumber["a"].eql? "a" # => false
57
+ #
28
58
  # @param other [Object]
29
59
  # @return [Boolean]
60
+ #
61
+ # @since 0.1.0
30
62
  def eql?(other)
31
63
  return true if equal?(other)
32
64
 
@@ -37,8 +69,29 @@ class VectorNumber
37
69
  end
38
70
  end
39
71
 
72
+ # Compare to +other+ and return -1, 0, or 1
73
+ # if +self+ is less than, equal, or larger than +other+.
74
+ #
75
+ # @example
76
+ # VectorNumber[130] <=> 12 # => 1
77
+ # 1 <=> VectorNumber[13] # => -1
78
+ # VectorNumber[12.1] <=> Complex(12.1, 0) # => 0
79
+ # # This doesn't work as expected without NumericRefinements:
80
+ # Complex(12.1, 0) <=> VectorNumber[12.1] # => nil
81
+ #
82
+ # # Any non-real comparison returns nil:
83
+ # VectorNumber[12.1] <=> Complex(12.1, 1) # => nil
84
+ # VectorNumber[12.1i] <=> 2 # => nil
85
+ # VectorNumber["a"] <=> 2 # => nil
86
+ #
40
87
  # @param other [Object]
41
- # @return [Integer, nil]
88
+ # @return [-1, 0, 1]
89
+ # @return [nil] if +self+ or +other+ isn't a real number.
90
+ #
91
+ # @see Comparable
92
+ # @see NumericRefinements
93
+ #
94
+ # @since 0.2.0
42
95
  def <=>(other)
43
96
  return nil unless numeric?(1)
44
97
 
@@ -4,47 +4,115 @@ class VectorNumber
4
4
  # Methods for converting to different number classes.
5
5
  module Converting
6
6
  # Return real part of the number.
7
+ #
8
+ # @example
9
+ # VectorNumber[23, "a"].real # => 23
10
+ # VectorNumber["a"].real # => 0
11
+ #
7
12
  # @return [Integer, Float, Rational, BigDecimal]
8
- def real
9
- @data[R]
10
- end
13
+ #
14
+ # @since 0.1.0
15
+ def real = @data[R]
11
16
 
12
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
+ #
13
23
  # @return [Integer, Float, Rational, BigDecimal]
14
- def imaginary
15
- @data[I]
16
- end
24
+ #
25
+ # @since 0.1.0
26
+ def imaginary = @data[I]
17
27
 
28
+ # @since 0.2.1
18
29
  alias imag imaginary
19
30
 
20
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
+ #
21
43
  # @return [Integer]
22
44
  # @raise [RangeError] if any non-real part is non-zero
45
+ #
46
+ # @since 0.1.0
23
47
  def to_i
24
48
  numeric?(1) ? real.to_i : raise_convert_error(Integer)
25
49
  end
26
50
 
51
+ # @since 0.1.0
27
52
  alias to_int to_i
28
53
 
29
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
+ #
30
65
  # @return [Float]
31
66
  # @raise [RangeError] if any non-real part is non-zero
67
+ #
68
+ # @since 0.1.0
32
69
  def to_f
33
70
  numeric?(1) ? real.to_f : raise_convert_error(Float)
34
71
  end
35
72
 
36
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
+ #
37
84
  # @return [Rational]
38
85
  # @raise [RangeError] if any non-real part is non-zero
86
+ #
87
+ # @since 0.1.0
39
88
  def to_r
40
89
  numeric?(1) ? real.to_r : raise_convert_error(Rational)
41
90
  end
42
91
 
43
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
+ #
44
107
  # @param ndigits [Integer] precision
45
108
  # @return [BigDecimal]
46
109
  # @raise [RangeError] if any non-real part is non-zero
47
110
  # @raise [NameError] if BigDecimal is not defined
111
+ #
112
+ # @see Kernel.BigDecimal
113
+ # @see NumericRefinements
114
+ #
115
+ # @since 0.1.0
48
116
  def to_d(ndigits = nil)
49
117
  if numeric?(1)
50
118
  return BigDecimal(real, ndigits) if ndigits
@@ -57,8 +125,20 @@ class VectorNumber
57
125
  end
58
126
 
59
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
+ #
60
138
  # @return [Complex]
61
139
  # @raise [RangeError] if any non-real, non-imaginary part is non-zero
140
+ #
141
+ # @since 0.1.0
62
142
  def to_c
63
143
  numeric?(2) ? Complex(real, imaginary) : raise_convert_error(Complex)
64
144
  end
@@ -2,11 +2,28 @@
2
2
 
3
3
  class VectorNumber
4
4
  # Methods for enumerating values of the number.
5
+ #
6
+ # +Enumerable+ is included so its methods can be used.
7
+ # @example using Enumerable methods
8
+ # VectorNumber["a", "b", 6].include?(["a", 1]) # => true
9
+ # VectorNumber["a", "b", 6].select { |u, c| u.is_a?(String) } # => [["a", 1], ["b", 1]]
5
10
  module Enumerating
11
+ # @since 0.1.0
6
12
  include ::Enumerable
7
13
 
8
14
  # Iterate through every pair of unit and coefficient.
9
- # Returns {::Enumerator} if no block is given.
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", (0+0i), "d"]
25
+ # v.each_pair.peek # => ["a", 1]
26
+ #
10
27
  # @overload each
11
28
  # @yieldparam unit [Object]
12
29
  # @yieldparam coefficient [Integer, Float, Rational, BigDecimal]
@@ -14,6 +31,11 @@ class VectorNumber
14
31
  # @return [VectorNumber] self
15
32
  # @overload each
16
33
  # @return [Enumerator]
34
+ #
35
+ # @see Enumerable
36
+ # @see Enumerator
37
+ #
38
+ # @since 0.1.0
17
39
  def each(&)
18
40
  return to_enum { size } unless block_given?
19
41
 
@@ -21,24 +43,50 @@ class VectorNumber
21
43
  self
22
44
  end
23
45
 
46
+ # @since 0.1.0
24
47
  alias each_pair each
25
48
 
49
+ # Get a list of units with non-zero coefficients.
50
+ #
51
+ # @example
52
+ # VectorNumber["a", "b", 6].units # => ["a", "b", (0+0i)]
53
+ # VectorNumber.new.keys # => []
54
+ #
26
55
  # @return [Array<Object>]
27
- def units
28
- @data.keys
29
- end
56
+ #
57
+ # @since 0.1.0
58
+ def units = @data.keys
30
59
 
60
+ # @since 0.1.0
31
61
  alias keys units
32
62
 
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
+ #
33
69
  # @return [Array<Integer, Float, Rational, BigDecimal>]
34
- def coefficients
35
- @data.values
36
- end
70
+ #
71
+ # @since 0.1.0
72
+ def coefficients = @data.values
37
73
 
74
+ # @since 0.1.0
38
75
  alias values coefficients
39
76
 
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, (0+0i)=>6}
83
+ # VectorNumber["a", "b", 6].to_h["c"] # => 0
84
+ #
40
85
  # @return [Hash{Object => Integer, Float, Rational, BigDecimal}]
86
+ #
87
+ # @since 0.1.0
41
88
  def to_h(&)
89
+ # TODO: Remove block argument.
42
90
  if block_given?
43
91
  @data.to_h(&)
44
92
  else
@@ -52,20 +100,29 @@ class VectorNumber
52
100
  # Note that units for real and imaginary parts are
53
101
  # VectorNumber::R and VectorNumber::I respectively.
54
102
  #
103
+ # @example
104
+ # VectorNumber["a", "b", 6]["a"] # => 1
105
+ # VectorNumber["a", "b", 6]["c"] # => 0
106
+ #
55
107
  # @param unit [Object]
56
108
  # @return [Integer, Float, Rational, BigDecimal]
57
- def [](unit)
58
- @data[unit] || 0
59
- end
109
+ #
110
+ # @since 0.2.4
111
+ def [](unit) = @data[unit]
60
112
 
61
113
  # Check if a unit has a non-zero coefficient.
62
114
  #
115
+ # @example
116
+ # VectorNumber["a", "b", 6].unit?("a") # => true
117
+ # VectorNumber["a", "b", 6].key?("c") # => false
118
+ #
63
119
  # @param unit [Object]
64
120
  # @return [Boolean]
65
- def unit?(unit)
66
- @data.key?(unit)
67
- end
121
+ #
122
+ # @since 0.2.4
123
+ def unit?(unit) = @data.key?(unit)
68
124
 
125
+ # @since 0.2.4
69
126
  alias key? unit?
70
127
  end
71
128
  end
@@ -3,45 +3,105 @@
3
3
  class VectorNumber
4
4
  # Various mathematical operations that are also conversions.
5
5
  module MathConverting
6
- # Return the absolute value of the vector, i.e. its length.
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
+ #
7
13
  # @return [Float]
14
+ #
15
+ # @since 0.2.2
8
16
  def abs
9
- Math.sqrt(coefficients.sum(&:abs2)) # rubocop:disable Naming/VariableNumber
17
+ Math.sqrt(abs2)
10
18
  end
11
19
 
12
20
  alias magnitude abs
13
21
 
14
- # Return the square of absolute value.
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
+ #
15
29
  # @return [Float]
16
- def abs2 # rubocop:disable Naming/VariableNumber
17
- abs**2
30
+ #
31
+ # @since 0.2.2
32
+ def abs2
33
+ coefficients.sum(&:abs2)
18
34
  end
19
35
 
20
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
+ #
21
45
  # @param digits [Integer]
22
46
  # @return [VectorNumber]
47
+ #
48
+ # @since 0.2.1
23
49
  def truncate(digits = 0)
24
50
  new { _1.truncate(digits) }
25
51
  end
26
52
 
27
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
+ #
28
62
  # @param digits [Integer]
29
63
  # @return [VectorNumber]
64
+ #
65
+ # @since 0.2.2
30
66
  def ceil(digits = 0)
31
67
  new { _1.ceil(digits) }
32
68
  end
33
69
 
34
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
+ #
35
79
  # @param digits [Integer]
36
80
  # @return [VectorNumber]
81
+ #
82
+ # @since 0.2.2
37
83
  def floor(digits = 0)
38
84
  new { _1.floor(digits) }
39
85
  end
40
86
 
41
87
  # Return a new vector with every coefficient rounded using their +#round+.
88
+ #
89
+ # @example
90
+ # VectorNumber[-4.5i, "i"].round(half: :up) # => (-5i + 1⋅'i')
91
+ # VectorNumber[-4.5i, "i"].round(half: :even) # => (-4i + 1⋅'i')
92
+ # VectorNumber[-5.5i, "i"].round(half: :even) # => (-6i + 1⋅'i')
93
+ # VectorNumber[-5.5i, "i"].round(half: :down) # => (-5i + 1⋅'i')
94
+ # VectorNumber[-5.35i, "i"].round(1) # => (-5.4i + 1⋅'i')
95
+ # VectorNumber[-5.35i, "i"].round(-1) # => (-10i)
96
+ #
42
97
  # @param digits [Integer]
43
- # @param half [Symbol, nil] one of +:up+, +:down+ or +:even+, see +Float#round+ for meaning
98
+ # @param half [Symbol, nil] one of +:up+, +:down+ or +:even+,
99
+ # see +Float#round+ for meaning
44
100
  # @return [VectorNumber]
101
+ #
102
+ # @see Float#round
103
+ #
104
+ # @since 0.2.2
45
105
  def round(digits = 0, half: :up)
46
106
  if defined?(BigDecimal)
47
107
  bd_mode =