Class: FractionTree::Node
- Inherits:
-
Object
- Object
- FractionTree::Node
- Extended by:
- Forwardable
- Includes:
- Comparable
- Defined in:
- lib/fraction_tree/node.rb
Constant Summary collapse
- IDENTITY_MATRIX =
Matrix.identity(2)
- LEFT_MATRIX =
Matrix[[1,1]
- RIGHT_MATRIX =
Instance Attribute Summary collapse
-
#denominator ⇒ Object
readonly
Returns the value of attribute denominator.
-
#number ⇒ Object
(also: #to_r)
readonly
Returns the value of attribute number.
-
#numerator ⇒ Object
readonly
Returns the value of attribute numerator.
Class Method Summary collapse
-
.decimal_power(logarithmand) ⇒ Integer
The decimal power of the provided number.
-
.decode(string) ⇒ FractionTree::Node
The fraction decoded from the given string.
-
.encode(number, limit: Float::INFINITY) ⇒ String
The Stern-Brocot encoding of number.
-
.plus_minus(num, diff) ⇒ Array
Pair of numbers less and greater than the provided number by provided difference.
Instance Method Summary collapse
-
#+(rhs) ⇒ FractionTree::Node
Sum of self and another node.
-
#-(rhs) ⇒ FractionTree::Node
Difference of self and another node.
- #<=>(rhs) ⇒ Object
- #==(rhs) ⇒ Object
-
#child_with(num) ⇒ FractionTree::Node
Child of self and given number.
-
#common_ancestors_with(num) ⇒ Array
The ancestors shared by self and the given number.
-
#descendancy_from(depth: 5) ⇒ Array
Of fraction tree nodes, descending from parents of number.
-
#encoding(limit: Float::INFINITY) ⇒ String
Encoding of self.
-
#eql?(rhs) ⇒ Boolean
Needed for intersection operations to work.
- #hash ⇒ Object
-
#initialize(num) ⇒ Node
constructor
A new instance of Node.
- #inspect ⇒ Object (also: #to_s)
-
#neighbors(r = 10**(self.class.decimal_power(number.numerator)+2)) ⇒ Array
Of [FractionTree::Node], sequence of Farey neighbors to self.
-
#parents ⇒ Array
A pair of fraction tree nodes leading to the given number.
-
#path(limit: Float::INFINITY) ⇒ Array
Set of fraction tree nodes leading to the given number.
Constructor Details
#initialize(num) ⇒ Node
Returns a new instance of Node.
16 17 18 19 |
# File 'lib/fraction_tree/node.rb', line 16 def initialize(num) (@numerator, @denominator) = fraction_pair(num) @number = num end |
Instance Attribute Details
#denominator ⇒ Object (readonly)
Returns the value of attribute denominator.
10 11 12 |
# File 'lib/fraction_tree/node.rb', line 10 def denominator @denominator end |
#number ⇒ Object (readonly) Also known as: to_r
Returns the value of attribute number.
10 11 12 |
# File 'lib/fraction_tree/node.rb', line 10 def number @number end |
#numerator ⇒ Object (readonly)
Returns the value of attribute numerator.
10 11 12 |
# File 'lib/fraction_tree/node.rb', line 10 def numerator @numerator end |
Class Method Details
.decimal_power(logarithmand) ⇒ Integer
Returns the decimal power of the provided number.
85 86 87 |
# File 'lib/fraction_tree/node.rb', line 85 def decimal_power(logarithmand) Math.log10(logarithmand.abs).floor end |
.decode(string) ⇒ FractionTree::Node
Returns the fraction decoded from the given string.
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/fraction_tree/node.rb', line 28 def decode(string) result = IDENTITY_MATRIX string.split("").each do |direction| case direction when "L", "0", "l" result = result * LEFT_MATRIX when "R", "1", "r" result = result * RIGHT_MATRIX end end FractionTree.node(Rational(result.row(1).sum, result.row(0).sum)) end |
.encode(number, limit: Float::INFINITY) ⇒ String
Returns the Stern-Brocot encoding of number.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/fraction_tree/node.rb', line 47 def encode(number, limit: Float::INFINITY) return nil if (number.infinite? || number.zero?) m = number.numerator n = number.denominator return "I" if m == n "".tap do |string| while m != n && string.length < limit if m < n string << "L" n = n - m else string << "R" m = m - n end end end end |
.plus_minus(num, diff) ⇒ Array
Returns pair of numbers less and greater than the provided number by provided difference.
75 76 77 |
# File 'lib/fraction_tree/node.rb', line 75 def plus_minus(num, diff) [num - diff, num + diff] end |
Instance Method Details
#+(rhs) ⇒ FractionTree::Node
Returns sum of self and another node.
198 199 200 |
# File 'lib/fraction_tree/node.rb', line 198 def +(rhs) tree.node(Rational(self.numerator+rhs.numerator, self.denominator+rhs.denominator)) end |
#-(rhs) ⇒ FractionTree::Node
Returns difference of self and another node.
207 208 209 |
# File 'lib/fraction_tree/node.rb', line 207 def -(rhs) tree.node(Rational((self.numerator-rhs.numerator).abs, (self.denominator-rhs.denominator).abs)) end |
#<=>(rhs) ⇒ Object
216 217 218 |
# File 'lib/fraction_tree/node.rb', line 216 def <=>(rhs) self.number <=> rhs.number end |
#==(rhs) ⇒ Object
220 221 222 |
# File 'lib/fraction_tree/node.rb', line 220 def ==(rhs) self.number == rhs.number end |
#child_with(num) ⇒ FractionTree::Node
return nil if bc - ad |= 1, for a/b, c/d
Returns child of self and given number.
180 181 182 |
# File 'lib/fraction_tree/node.rb', line 180 def child_with(num) tree.child_of(number, num) end |
#common_ancestors_with(num) ⇒ Array
Returns the ancestors shared by self and the given number.
158 159 160 |
# File 'lib/fraction_tree/node.rb', line 158 def common_ancestors_with(num) path & tree.node(num).path end |
#descendancy_from(depth: 5) ⇒ Array
Returns of fraction tree nodes, descending from parents of number.
169 170 171 172 |
# File 'lib/fraction_tree/node.rb', line 169 def descendancy_from(depth: 5) (parent1, parent2) = parents tree.descendants_of(parent1.number, parent2.number, depth:) end |
#encoding(limit: Float::INFINITY) ⇒ String
Returns encoding of self.
189 190 191 |
# File 'lib/fraction_tree/node.rb', line 189 def encoding(limit: Float::INFINITY) self.class.encode(number, limit:) end |
#eql?(rhs) ⇒ Boolean
Needed for intersection operations to work. blog.mnishiguchi.com/ruby-intersection-of-object-arrays shortrecipes.blogspot.com/2006/10/ruby-intersection-of-two-arrays-of.html Also, allows using with Set, which uses Hash as storage and equality of its elements is determined according to Object#eql? and Object#hash.
229 230 231 |
# File 'lib/fraction_tree/node.rb', line 229 def eql?(rhs) rhs.instance_of?(self.class) && number == rhs.number end |
#hash ⇒ Object
233 234 235 236 237 |
# File 'lib/fraction_tree/node.rb', line 233 def hash p, q = 17, 37 p = q * @id.hash p = q * @name.hash end |
#inspect ⇒ Object Also known as: to_s
211 212 213 |
# File 'lib/fraction_tree/node.rb', line 211 def inspect "(#{numerator}/#{denominator})" end |
#neighbors(r = 10**(self.class.decimal_power(number.numerator)+2)) ⇒ Array
Returns of [FractionTree::Node], sequence of Farey neighbors to self. A Farey neighbor is a number c/d, who’s relationship to a/b is such that ad − bc = 1, when c/d < a/b and bc − ad = 1 when c/d > a/b.
138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/fraction_tree/node.rb', line 138 def neighbors(r = 10**(self.class.decimal_power(number.numerator)+2)) ratio = number.to_r denominator = ratio.denominator [].tap do |collection| (1..r-1).each do |i| lower, upper = self.class.plus_minus(ratio, Rational(1,i*denominator)) collection << tree.node(lower) if tree.neighbors?(ratio, lower) collection << tree.node(upper) if tree.neighbors?(ratio, upper) end end end |
#parents ⇒ Array
Returns a pair of fraction tree nodes leading to the given number.
127 128 129 130 |
# File 'lib/fraction_tree/node.rb', line 127 def parents tmp = path [tmp[-2], tmp[-2..-1].inject(&:-)].sort end |
#path(limit: Float::INFINITY) ⇒ Array
Returns set of fraction tree nodes leading to the given number.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/fraction_tree/node.rb', line 96 def path(limit: Float::INFINITY) return nil if infinite? || zero? ln = tree.node(FractionTree.left_node) rn = tree.node(FractionTree.right_node) mn = ln + rn return [ln, rn, mn] if mn == tree.node(number) result = IDENTITY_MATRIX m = numerator n = denominator [].tap do |p| p << ln << rn << mn while m != n && p.length < limit if m < n result = result * LEFT_MATRIX n = n - m else result = result * RIGHT_MATRIX m = m - n end p << tree.node(Rational(result.row(1).sum,result.row(0).sum)) end end end |