Class: Tonal::Ratio::Approximation
- Inherits:
-
Object
- Object
- Tonal::Ratio::Approximation
- Extended by:
- Forwardable
- Defined in:
- lib/tonal/approximation.rb
Defined Under Namespace
Classes: Set
Constant Summary collapse
- DEFAULT_MAX_PRIME =
Float::INFINITY
- DEFAULT_MAX_GRID_SCALE =
100
- DEFAULT_MAX_GRID_BOUNDARY =
5
- DEFAULT_DEPTH =
Float::INFINITY
- DEFAULT_FRACTION_TREE_DEPTH =
10
- DEFAULT_SUPERPART_DEPTH =
20
- DEFAULT_NEIGHBORHOOD_DEPTH =
10
- DEFAULT_COMPLEXITY_AMOUNT =
50.0
- CONVERGENT_LIMIT =
10
Instance Attribute Summary collapse
-
#ratio ⇒ Object
readonly
Returns the value of attribute ratio.
Class Method Summary collapse
-
.neighbors(vacinity:, away: 1) ⇒ Array
An array of Tonal::Ratio neighbors in the scaled ratio’s grid neighborhood.
Instance Method Summary collapse
-
#by_continued_fraction(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT) ⇒ Tonal::Ratio::Approximation::Set
Of ratios within cent tolerance of self found using continued fraction approximation.
-
#by_neighborhood(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_NEIGHBORHOOD_DEPTH, max_prime: DEFAULT_MAX_PRIME, max_boundary: DEFAULT_MAX_GRID_BOUNDARY, max_scale: DEFAULT_MAX_GRID_SCALE) ⇒ Array
Of ratios within cent tolerance of self found on the ratio grid.
-
#by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_SUPERPART_DEPTH, max_prime: DEFAULT_MAX_PRIME, superpart: :upper) ⇒ Tonal::Ratio::Approximation::Set
Of superparticular approximations within cent tolerance of self.
-
#by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_FRACTION_TREE_DEPTH, max_prime: DEFAULT_MAX_PRIME) ⇒ Tonal::Ratio::Approximation::Set
Of fraction tree ratios within cent tolerance of self.
-
#initialize(ratio:) ⇒ Approximation
constructor
A new instance of Approximation.
-
#neighborhood(scale: 2**0, boundary: 1) ⇒ Array
Of bounding ratios in the ratio grid vacinity of antecedent/consequent scaled by scale.
Constructor Details
#initialize(ratio:) ⇒ Approximation
Returns a new instance of Approximation.
18 19 20 21 |
# File 'lib/tonal/approximation.rb', line 18 def initialize(ratio:) raise ArgumentError, "Tonal::Ratio required" unless ratio.kind_of?(Tonal::Ratio) @ratio = ratio end |
Instance Attribute Details
#ratio ⇒ Object (readonly)
Returns the value of attribute ratio.
16 17 18 |
# File 'lib/tonal/approximation.rb', line 16 def ratio @ratio end |
Class Method Details
.neighbors(vacinity:, away: 1) ⇒ Array
Returns an array of Tonal::Ratio neighbors in the scaled ratio’s grid neighborhood.
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/tonal/approximation.rb', line 141 def self.neighbors(vacinity:, away: 1) [vacinity, vacinity.class.new(vacinity.antecedent+away, vacinity.consequent), vacinity.class.new(vacinity.antecedent-away, vacinity.consequent), vacinity.class.new(vacinity.antecedent, vacinity.consequent+away), vacinity.class.new(vacinity.antecedent, vacinity.consequent-away), vacinity.class.new(vacinity.antecedent+away, vacinity.consequent+away), vacinity.class.new(vacinity.antecedent+away, vacinity.consequent-away), vacinity.class.new(vacinity.antecedent-away, vacinity.consequent+away), vacinity.class.new(vacinity.antecedent-away, vacinity.consequent-away)] end |
Instance Method Details
#by_continued_fraction(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT) ⇒ Tonal::Ratio::Approximation::Set
Returns of ratios within cent tolerance of self found using continued fraction approximation.
32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/tonal/approximation.rb', line 32 def by_continued_fraction(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT) self_in_cents = to_cents within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance) Set.new(ratio: ratio) do |ratios| ContinuedFraction.new(antecedent.to_f/consequent, conv_limit).convergents.each do |convergent| ratio2 = ratio.class.new(convergent.numerator,convergent.denominator) ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime) break if ratios.length >= depth end end end |
#by_neighborhood(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_NEIGHBORHOOD_DEPTH, max_prime: DEFAULT_MAX_PRIME, max_boundary: DEFAULT_MAX_GRID_BOUNDARY, max_scale: DEFAULT_MAX_GRID_SCALE) ⇒ Array
Returns of ratios within cent tolerance of self found on the ratio grid.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/tonal/approximation.rb', line 97 def by_neighborhood(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_NEIGHBORHOOD_DEPTH, max_prime: DEFAULT_MAX_PRIME, max_boundary: DEFAULT_MAX_GRID_BOUNDARY, max_scale: DEFAULT_MAX_GRID_SCALE) self_in_cents = to_cents within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance) Set.new(ratio: ratio) do |ratios| scale = 1 boundary = 1 while ratios.length <= depth && scale <= max_scale do while boundary <= max_boundary vacinity = ratio.respond_to?(:to_basic_ratio) ? to_basic_ratio.scale(scale) : ratio.scale(scale) self.class.neighbors(away: boundary, vacinity: vacinity).each do |neighbor| ratios << neighbor if ratio.class.within_cents?(self_in_cents, neighbor.to_cents, within) && neighbor.within_prime?(max_prime) && neighbor != ratio end boundary += 1 end boundary = 1 scale += 1 end end end |
#by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_SUPERPART_DEPTH, max_prime: DEFAULT_MAX_PRIME, superpart: :upper) ⇒ Tonal::Ratio::Approximation::Set
Returns of superparticular approximations within cent tolerance of self.
73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/tonal/approximation.rb', line 73 def by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_SUPERPART_DEPTH, max_prime: DEFAULT_MAX_PRIME, superpart: :upper) self_in_cents = to_cents within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance) Set.new(ratio: ratio) do |ratios| n = 1 while true do ratio2 = ratio.class.superparticular(n, factor: ratio.to_r, superpart:) ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime) && ratio2 != ratio break if ratios.length >= depth n += 1 end end end |
#by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_FRACTION_TREE_DEPTH, max_prime: DEFAULT_MAX_PRIME) ⇒ Tonal::Ratio::Approximation::Set
Returns of fraction tree ratios within cent tolerance of self.
52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/tonal/approximation.rb', line 52 def by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_FRACTION_TREE_DEPTH, max_prime: DEFAULT_MAX_PRIME) self_in_cents = to_cents within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance) Set.new(ratio: ratio) do |ratios| FractionTree.node(to_f).path.each do |node| ratio2 = ratio.class.new(node.number) ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime) break if ratios.length >= depth end end end |
#neighborhood(scale: 2**0, boundary: 1) ⇒ Array
Returns of bounding ratios in the ratio grid vacinity of antecedent/consequent scaled by scale.
125 126 127 128 129 130 131 132 133 |
# File 'lib/tonal/approximation.rb', line 125 def neighborhood(scale: 2**0, boundary: 1) scale = scale.round vacinity = ratio.respond_to?(:to_basic_ratio) ? to_basic_ratio.scale(scale) : ratio.scale(scale) SortedSet.new([].tap do |ratio_list| 1.upto(boundary) do |away| ratio_list << self.class.neighbors(away: away, vacinity: vacinity) end end.flatten).to_a end |