tonal-tools 4.0.1 → 5.1.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 +4 -4
- data/data/commas.yml +1 -1
- data/lib/tonal/approximation.rb +37 -25
- data/lib/tonal/attributions.rb +1 -1
- data/lib/tonal/cents.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc49345ed34f38eed1600818c0b28910a5525a22c8388338c5739650339c9ec1
|
4
|
+
data.tar.gz: a63830d52d1ed45aa575c6ee2d924c547a74260697853680928fbc0a586d1cfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8111bb7846cc0dc220742313c253f6d719d31213ac05c35443eb4dc27058ec236b6bd13b946ad6870ca38b5e48f853385532bc2513f8897c3e5df10c3be3afed
|
7
|
+
data.tar.gz: cb3b394f94d175c127b874bba207fc4933e49a91197c48822ea8968578ec57d0dd42730b19eb2a7d6a57eebf44b77615d8b84094d2b3419f88d30b5ae34f1e03
|
data/data/commas.yml
CHANGED
data/lib/tonal/approximation.rb
CHANGED
@@ -4,6 +4,9 @@ class Tonal::Ratio
|
|
4
4
|
DEFAULT_MAX_GRID_SCALE = 100
|
5
5
|
DEFAULT_MAX_GRID_BOUNDARY = 5
|
6
6
|
DEFAULT_DEPTH = Float::INFINITY
|
7
|
+
DEFAULT_FRACTION_TREE_DEPTH = 10
|
8
|
+
DEFAULT_SUPERPART_DEPTH = 20
|
9
|
+
DEFAULT_NEIGHBORHOOD_DEPTH = 10
|
7
10
|
DEFAULT_COMPLEXITY_AMOUNT = 50.0
|
8
11
|
CONVERGENT_LIMIT = 10
|
9
12
|
|
@@ -20,7 +23,7 @@ class Tonal::Ratio
|
|
20
23
|
# @return [Tonal::Ratio::Approximation::Set] of ratios within cent tolerance of self found using continued fraction approximation
|
21
24
|
# @example
|
22
25
|
# Tonal::Ratio.ed(12,1).approximate.by_continued_fraction
|
23
|
-
# => (4771397596969315/4503599627370496): [(
|
26
|
+
# => (4771397596969315/4503599627370496): [(17/16), (18/17), (89/84), (196/185), (1461/1379), (1657/1564), (3118/2943), (7893/7450), (18904/17843)]
|
24
27
|
# @param cents_tolerance the cents tolerance used to scope the collection
|
25
28
|
# @param depth the maximum number of ratios in the collection
|
26
29
|
# @param max_prime the maximum prime number to allow in the collection
|
@@ -29,11 +32,11 @@ class Tonal::Ratio
|
|
29
32
|
def by_continued_fraction(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT)
|
30
33
|
self_in_cents = to_cents
|
31
34
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
32
|
-
Set.new(ratio: ratio)
|
35
|
+
Set.new(ratio: ratio) do |ratios|
|
33
36
|
ContinuedFraction.new(antecedent.to_f/consequent, conv_limit).convergents.each do |convergent|
|
34
37
|
ratio2 = ratio.class.new(convergent.numerator,convergent.denominator)
|
35
|
-
|
36
|
-
break if
|
38
|
+
ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
|
39
|
+
break if ratios.length >= depth
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
@@ -41,21 +44,21 @@ class Tonal::Ratio
|
|
41
44
|
# @return [Tonal::Ratio::Approximation::Set] of ratios within cent tolerance of self found using a quotient walk on the fraction tree
|
42
45
|
# @example
|
43
46
|
# Tonal::Ratio.ed(12,1).approximate.by_quotient_walk(max_prime: 89)
|
44
|
-
# => (4771397596969315/4503599627370496): [(
|
47
|
+
# => (4771397596969315/4503599627370496): [(17/16), (18/17), (35/33), (53/50), (71/67), (89/84), (196/185)]
|
45
48
|
# @param cents_tolerance the cents tolerance used to scope the collection
|
46
49
|
# @param depth the maximum number of ratios in the collection
|
47
50
|
# @param max_prime the maximum prime number to allow in the collection
|
48
51
|
# @param conv_limit the number of convergents to limit the ContinuedFraction method
|
49
52
|
#
|
50
|
-
def by_quotient_walk(cents_tolerance: Tonal::Cents::TOLERANCE, depth:
|
53
|
+
def by_quotient_walk(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_FRACTION_TREE_DEPTH, max_prime: DEFAULT_MAX_PRIME, conv_limit: CONVERGENT_LIMIT)
|
51
54
|
self_in_cents = to_cents
|
52
55
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
53
56
|
|
54
|
-
Set.new(ratio: ratio)
|
57
|
+
Set.new(ratio: ratio) do |ratios|
|
55
58
|
FractionTree.quotient_walk(to_f, limit: conv_limit).each do |node|
|
56
59
|
ratio2 = ratio.class.new(node.weight)
|
57
|
-
|
58
|
-
break if
|
60
|
+
ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
|
61
|
+
break if ratios.length >= depth
|
59
62
|
end
|
60
63
|
end
|
61
64
|
end
|
@@ -63,19 +66,19 @@ class Tonal::Ratio
|
|
63
66
|
# @return [Tonal::Ratio::Approximation::Set] of fraction tree ratios within cent tolerance of self
|
64
67
|
# @example
|
65
68
|
# Tonal::Ratio.ed(12,1).approximate.by_tree_path(max_prime: 17)
|
66
|
-
# => (4771397596969315/4503599627370496): [(
|
69
|
+
# => (4771397596969315/4503599627370496): [(17/16), (18/17), (35/33)]
|
67
70
|
# @param cents_tolerance the cents tolerance used to scope the collection
|
68
71
|
# @param depth the maximum number of ratios in the collection
|
69
72
|
# @param max_prime the maximum prime number to allow in the collection
|
70
73
|
#
|
71
|
-
def by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth:
|
74
|
+
def by_tree_path(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_FRACTION_TREE_DEPTH, max_prime: DEFAULT_MAX_PRIME)
|
72
75
|
self_in_cents = to_cents
|
73
76
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
74
|
-
Set.new(ratio: ratio)
|
77
|
+
Set.new(ratio: ratio) do |ratios|
|
75
78
|
FractionTree.path_to(to_f).each do |node|
|
76
79
|
ratio2 = ratio.class.new(node.weight)
|
77
|
-
|
78
|
-
break if
|
80
|
+
ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime)
|
81
|
+
break if ratios.length >= depth
|
79
82
|
end
|
80
83
|
end
|
81
84
|
end
|
@@ -83,21 +86,21 @@ class Tonal::Ratio
|
|
83
86
|
# @return [Tonal::Ratio::Approximation::Set] of superparticular approximations within cent tolerance of self
|
84
87
|
# @example
|
85
88
|
# Tonal::Ratio.new(3/2r).approximate.by_superparticular
|
86
|
-
# => (3/2): [(
|
89
|
+
# => (3/2): [(1041/692), (1044/694), (1047/696), (1050/698), (1053/700), (1056/702), (1059/704), (1062/706), (1065/708), (1068/710), (1071/712), (1074/714), (1077/716), (1080/718), (1083/720), (1086/722), (1089/724), (1092/726), (1095/728), (1098/730)]
|
87
90
|
# @param cents_tolerance the cents tolerance used to scope the collection
|
88
91
|
# @param depth the maximum number of ratios in the collection
|
89
92
|
# @param max_prime the maximum prime number to allow in the collection
|
90
93
|
# @param superpart if the superior part is the numerator or denominator
|
91
94
|
#
|
92
|
-
def by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth:
|
95
|
+
def by_superparticular(cents_tolerance: Tonal::Cents::TOLERANCE, depth: DEFAULT_SUPERPART_DEPTH, max_prime: DEFAULT_MAX_PRIME, superpart: :upper)
|
93
96
|
self_in_cents = to_cents
|
94
97
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
95
|
-
Set.new(ratio: ratio)
|
98
|
+
Set.new(ratio: ratio) do |ratios|
|
96
99
|
n = 1
|
97
100
|
while true do
|
98
101
|
ratio2 = ratio.class.superparticular(n, factor: ratio.to_r, superpart:)
|
99
|
-
|
100
|
-
break if
|
102
|
+
ratios << ratio2 if ratio.class.within_cents?(self_in_cents, ratio2.to_cents, within) && ratio2.within_prime?(max_prime) && ratio2 != ratio
|
103
|
+
break if ratios.length >= depth
|
101
104
|
n += 1
|
102
105
|
end
|
103
106
|
end
|
@@ -113,18 +116,18 @@ class Tonal::Ratio
|
|
113
116
|
# @param max_boundary the maximum distance grid ratios will be from the scaled ratio
|
114
117
|
# @param max_scale the maximum self will be scaled
|
115
118
|
#
|
116
|
-
def by_neighborhood(cents_tolerance: Tonal::Cents::TOLERANCE, depth:
|
119
|
+
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)
|
117
120
|
self_in_cents = to_cents
|
118
121
|
within = cents_tolerance.kind_of?(Tonal::Cents) ? cents_tolerance : Tonal::Cents.new(cents: cents_tolerance)
|
119
|
-
Set.new(ratio: ratio)
|
122
|
+
Set.new(ratio: ratio) do |ratios|
|
120
123
|
scale = 1
|
121
124
|
boundary = 1
|
122
125
|
|
123
|
-
while
|
126
|
+
while ratios.length <= depth && scale <= max_scale do
|
124
127
|
while boundary <= max_boundary
|
125
128
|
vacinity = ratio.respond_to?(:to_basic_ratio) ? to_basic_ratio.scale(scale) : ratio.scale(scale)
|
126
129
|
self.class.neighbors(away: boundary, vacinity: vacinity).each do |neighbor|
|
127
|
-
|
130
|
+
ratios << neighbor if ratio.class.within_cents?(self_in_cents, neighbor.to_cents, within) && neighbor.within_prime?(max_prime) && neighbor != ratio
|
128
131
|
end
|
129
132
|
boundary += 1
|
130
133
|
end
|
@@ -171,19 +174,28 @@ class Tonal::Ratio
|
|
171
174
|
|
172
175
|
class Set
|
173
176
|
extend Forwardable
|
174
|
-
def_delegators :@ratios, :count, :length, :min, :max, :entries, :all?, :any?, :reject, :map
|
177
|
+
def_delegators :@ratios, :count, :length, :min, :max, :entries, :all?, :any?, :reject, :map, :find_index
|
175
178
|
|
176
179
|
attr_reader :ratios, :ratio
|
177
180
|
|
178
181
|
def initialize(ratio:)
|
179
182
|
@ratio = ratio
|
180
|
-
@ratios =
|
183
|
+
@ratios = ::Set.new
|
184
|
+
yield @ratios if block_given?
|
181
185
|
end
|
182
186
|
alias :approximations :entries
|
183
187
|
|
184
188
|
def inspect
|
185
189
|
"#{ratio}: #{entries}"
|
186
190
|
end
|
191
|
+
|
192
|
+
def sort_by(&)
|
193
|
+
self.class.new(ratio: ratio) do |ratios|
|
194
|
+
entries.sort_by(&).each do |ratio|
|
195
|
+
ratios << ratio
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
187
199
|
end
|
188
200
|
end
|
189
201
|
end
|
data/lib/tonal/attributions.rb
CHANGED
data/lib/tonal/cents.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tonal-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jose Hales-Garcia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yaml
|