Class: FractionTree
- Inherits:
-
Object
- Object
- FractionTree
- Defined in:
- lib/fraction_tree.rb
Direct Known Subclasses
Defined Under Namespace
Classes: Node
Constant Summary collapse
- DEFAULT_TREE_DEPTH =
20
Class Method Summary collapse
-
.base_segment ⇒ Array
The boundary nodes of the tree.
-
.child_of(number1, number2, strict_neighbors: true) ⇒ FractionTree::Node
The mediant child of the given numbers Return nil if bc - ad |= 1, for a/b, c/d.
-
.common_ancestors_between(number1, number2) ⇒ Array
The ancestors shared by the given descendants.
-
.descendancy_from(number, depth = 5) ⇒ Array
The descendants of number starting at its parents.
-
.descendants_of(parent1, parent2, depth = 5, strict_neighbors: true) ⇒ Array
Of nodes descended from parent1 and parent2 Return empty array if bc - ad |= 1, for a/b, c/d.
-
.numeric_sequence ⇒ Array
Of numerators of the fraction tree nodes.
-
.parents_of(number) ⇒ Array
A pair of fraction tree nodes leading to the given number.
-
.path_to(number, find_parents: false, segment: base_segment) ⇒ Array
Set of fraction nodes leading to the given number.
-
.quotient_walk(number, limit: 10, segment: computed_base_segment(number)) ⇒ Array
Of FractionTree::Nodes leading quotient-wise to number.
-
.sequence(depth = 5, segment: base_segment) ⇒ Array
A sequence of fraction tree nodes.
-
.tree(depth = DEFAULT_TREE_DEPTH) ⇒ Array
A multi-dimensional array with the elements of fraction tree, organized by level/row.
Class Method Details
.base_segment ⇒ Array
Returns the boundary nodes of the tree.
11 12 13 |
# File 'lib/fraction_tree.rb', line 11 def base_segment [Node.new(0,1), Node.new(1,0)] end |
.child_of(number1, number2, strict_neighbors: true) ⇒ FractionTree::Node
The mediant child of the given numbers Return nil if bc - ad |= 1, for a/b, c/d
132 133 134 135 |
# File 'lib/fraction_tree.rb', line 132 def child_of(number1, number2, strict_neighbors: true) return nil unless farey_neighbors?(number1, number2) || !strict_neighbors Node.new(number1.numerator, number1.denominator) + Node.new(number2.numerator, number2.denominator) end |
.common_ancestors_between(number1, number2) ⇒ Array
Returns the ancestors shared by the given descendants.
106 107 108 |
# File 'lib/fraction_tree.rb', line 106 def common_ancestors_between(number1, number2) path_to(number1) & path_to(number2) end |
.descendancy_from(number, depth = 5) ⇒ Array
Returns the descendants of number starting at its parents.
118 119 120 121 |
# File 'lib/fraction_tree.rb', line 118 def descendancy_from(number, depth=5) parent1, parent2 = parents_of(number) descendants_of(parent1, parent2, depth) end |
.descendants_of(parent1, parent2, depth = 5, strict_neighbors: true) ⇒ Array
Of nodes descended from parent1 and parent2 Return empty array if bc - ad |= 1, for a/b, c/d
146 147 148 149 150 |
# File 'lib/fraction_tree.rb', line 146 def descendants_of(parent1, parent2, depth=5, strict_neighbors: true) return [] unless farey_neighbors?(parent1, parent2) || !strict_neighbors segment = [Node.new(parent1.numerator, parent1.denominator), Node.new(parent2.numerator, parent2.denominator)] sequence(depth, segment: segment) end |
.numeric_sequence ⇒ Array
Returns of numerators of the fraction tree nodes. Also known as the Stern-Brocot sequence.
185 186 187 188 189 190 191 192 193 |
# File 'lib/fraction_tree.rb', line 185 def numeric_sequence return enum_for :numeric_sequence unless block_given? a=[1,1] 0.step do |i| yield a[i] a << a[i]+a[i+1] << a[i+1] end end |
.parents_of(number) ⇒ Array
Returns a pair of fraction tree nodes leading to the given number. For irrational numbers, the parent nodes are one of an infinite series, whose nearness is determined by the limits of the system.
94 95 96 |
# File 'lib/fraction_tree.rb', line 94 def parents_of(number) path_to(number, find_parents: true) end |
.path_to(number, find_parents: false, segment: base_segment) ⇒ Array
Returns set of fraction nodes leading to the given number.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/fraction_tree.rb', line 63 def path_to(number, find_parents: false, segment: base_segment) return Node.new(number.numerator, number.denominator) if number.zero? q = Node.new(number.numerator, number.denominator) l = segment.first h = segment.last not_found = true parents = [] results = [] while not_found m = (l + h) if m < q l = m elsif m > q h = m else parents << l << h not_found = false end results << m end find_parents == false ? results : parents end |
.quotient_walk(number, limit: 10, segment: computed_base_segment(number)) ⇒ Array
Returns of FractionTree::Nodes leading quotient-wise to number.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/fraction_tree.rb', line 160 def quotient_walk(number, limit: 10, segment: computed_base_segment(number)) = ContinuedFraction.new(number, limit).quotients.drop(1) comparing_node = Node.new(number.numerator, number.denominator) segment.tap do |arr| held_node = arr[-2] moving_node = arr[-1] .each do |q| (1..q).each do |i| arr << held_node + moving_node # We don't want to walk past the number when it's a rational number and we've reached it break if arr.include?(comparing_node) moving_node = arr[-1] end held_node = arr[-2] end end end |
.sequence(depth = 5, segment: base_segment) ⇒ Array
Returns a sequence of fraction tree nodes.
53 54 55 |
# File 'lib/fraction_tree.rb', line 53 def sequence(depth=5, segment: base_segment) [segment.first]+_sequence(depth, segment:)+[segment.last] end |
.tree(depth = DEFAULT_TREE_DEPTH) ⇒ Array
Returns a multi-dimensional array with the elements of fraction tree, organized by level/row.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/fraction_tree.rb', line 25 def tree(depth=DEFAULT_TREE_DEPTH) Array.new(depth, 0).tap do |sbt| row = 0 sbt[row] = base_segment i = 2 while i <= depth do figure_from = sbt[0..row].flatten.sort new_frow = Array.new(2**(i-2), 0) idx = 0 figure_from.each_cons(2) do |left,right| new_frow[idx] = Node.new(left.numerator+right.numerator, left.denominator+right.denominator) idx += 1 end row += 1 sbt[row] = new_frow i += 1 end end end |