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_MIN_PRIME =
2- DEFAULT_MAX_PRIME =
Float::INFINITY
- DEFAULT_MAX_GRID_SCALE =
100- DEFAULT_MAX_GRID_BOUNDARY =
5- DEFAULT_DEPTH =
Float::INFINITY
- DEFAULT_TREE_PATH_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, min_prime: DEFAULT_MIN_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, min_prime: DEFAULT_MIN_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, min_prime: DEFAULT_MIN_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_TREE_PATH_DEPTH, max_prime: DEFAULT_MAX_PRIME, min_prime: DEFAULT_MIN_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.
19 20 21 22 |
# File 'lib/tonal/approximation.rb', line 19 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.
17 18 19 |
# File 'lib/tonal/approximation.rb', line 17 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.
149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/tonal/approximation.rb', line 149 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, min_prime: DEFAULT_MIN_PRIME, conv_limit: CONVERGENT_LIMIT) ⇒ Tonal::Ratio::Approximation::Set
Returns of ratios within cent tolerance of self found using continued fraction approximation.
34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/tonal/approximation.rb', line 34 def by_continued_fraction(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, min_prime: DEFAULT_MIN_PRIME, conv_limit: CONVERGENT_LIMIT) return Set.new(ratio: ratio){|ratios| ratios << ratio} if (antecedent == 1) && (consequent == 1) 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.max_prime <= max_prime) && (ratio2.min_prime >= min_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, min_prime: DEFAULT_MIN_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.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/tonal/approximation.rb', line 105 def by_neighborhood(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_NEIGHBORHOOD_DEPTH, max_prime: DEFAULT_MAX_PRIME, min_prime: DEFAULT_MIN_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 (neighbor != ratio) && ratio.class.within_cents?(self_in_cents, neighbor.to_cents, within) && (neighbor.max_prime <= max_prime) && (neighbor.min_prime >= min_prime) 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, min_prime: DEFAULT_MIN_PRIME, superpart: :upper) ⇒ Tonal::Ratio::Approximation::Set
Returns of superparticular approximations within cent tolerance of self.
80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/tonal/approximation.rb', line 80 def by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_SUPERPART_DEPTH, max_prime: DEFAULT_MAX_PRIME, min_prime: DEFAULT_MIN_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 != ratio) && (ratio2.max_prime <= max_prime) && (ratio2.min_prime <= min_prime) break if ratios.length >= depth n += 1 end end end |
#by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_TREE_PATH_DEPTH, max_prime: DEFAULT_MAX_PRIME, min_prime: DEFAULT_MIN_PRIME) ⇒ Tonal::Ratio::Approximation::Set
Returns of fraction tree ratios within cent tolerance of self.
56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/tonal/approximation.rb', line 56 def by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_TREE_PATH_DEPTH, max_prime: DEFAULT_MAX_PRIME, min_prime: DEFAULT_MIN_PRIME) return Set.new(ratio: ratio){|ratios| ratios << ratio} if (antecedent == 1) && (consequent == 1) 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| next if node.number.infinite? ratio2 = ratio.class.new(node.number) ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && (ratio2.max_prime <= max_prime) && (ratio2.min_prime >= min_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.
133 134 135 136 137 138 139 140 141 |
# File 'lib/tonal/approximation.rb', line 133 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 |