Generator embedding optimization: Difference between revisions
ArrowHead294 (talk | contribs) m Reformat markup, update links |
m Linking |
||
| (4 intermediate revisions by 3 users not shown) | |||
| Line 3: | Line 3: | ||
Two of these four specialized methods were briefly discussed in D&D's guide, along with the general method, because these specialized methods are actually even quicker and easier than the general method. These two are the only held-intervals method, and the pseudoinverse method. But there's still plenty more insight to be had into how and why exactly these methods work, in particular for the pseudoinverse method, so we'll be doing a much deeper dive into it in this article here than was done in D&D's guide. | Two of these four specialized methods were briefly discussed in D&D's guide, along with the general method, because these specialized methods are actually even quicker and easier than the general method. These two are the only held-intervals method, and the pseudoinverse method. But there's still plenty more insight to be had into how and why exactly these methods work, in particular for the pseudoinverse method, so we'll be doing a much deeper dive into it in this article here than was done in D&D's guide. | ||
The other two of these four specialized | The other two of these four specialized methods—the zero-damage method, and the coinciding-damage method—are significantly more challenging to understand than the general method. Most students of RTT would not gain enough musical insight by familiarizing themselves with them to have justified the investment. This is why these two methods were not discussed in D&D's guide. However, if you feel compelled to understand the nuts and bolts of these methods anyway, then those sections of the article may well appeal to you. | ||
This article is titled "Generator embedding optimization" because of a key feature these four specialized methods share: they can all give their solutions as [[generator embedding matrix|generator embedding]]s, i.e. lists of [[prime-count vector]]s, one for each generator, where typically these prime-count vectors have non-integer entries (and are thus not [[JI]]). This is different from the general method, which can only give [[generator tuning map]]s, i.e. sizes in cents for each generator. As we'll see, a tuning optimization method's ability to give solutions as generator embeddings is equivalent to its ability to give solutions that are exact. | This article is titled "Generator embedding optimization" because of a key feature these four specialized methods share: they can all give their solutions as [[generator embedding matrix|generator embedding]]s, i.e. lists of [[prime-count vector]]s, one for each generator, where typically these prime-count vectors have non-integer entries (and are thus not [[JI]]). This is different from the general method, which can only give [[generator tuning map]]s, i.e. sizes in cents for each generator. As we'll see, a tuning optimization method's ability to give solutions as generator embeddings is equivalent to its ability to give solutions that are exact. | ||
| Line 182: | Line 182: | ||
== Generator embedding == | == Generator embedding == | ||
So, substituting <math>\mathrm{U}</math> in for <math>\mathrm{H}</math> in the formula we learned from the D&D's guide article: | So, substituting <math>\mathrm{U}</math> in for <math>\mathrm{H}</math> in the formula we learned [[Dave Keenan & Douglas Blumeyer's guide to RTT/Tuning computation#Only held-intervals method|from the D&D's guide article]]: | ||
| Line 212: | Line 212: | ||
G = \mathrm{U}(M\mathrm{U})^{-1} | G = \mathrm{U}(M\mathrm{U})^{-1} | ||
</math> | </math> | ||
= Pseudoinverse method = | = Pseudoinverse method = | ||
| Line 4,416: | Line 4,415: | ||
As discussed in [[Dave Keenan & Douglas Blumeyer's guide to RTT | As discussed in [[Dave Keenan & Douglas Blumeyer's guide to RTT/Tuning fundamentals#Absolute errors]], these vertical bars mean to take the absolute value of each entry of this vector, not to take its magnitude. | ||
As discussed elsewhere, we can simplify this to: | As discussed elsewhere, we can simplify this to: | ||
| Line 4,814: | Line 4,813: | ||
But sometimes we have a tie between tunings for least average damage, though. For example, if we had we done a unity-weight tuning, in which case <math>W = I</math>, and included the interval <math>\frac85</math> in our set, we would have found that quarter-comma meantone tied with another tuning, one with generators of <math>\sqrt[5]{\frac{2560}{81}}</math> and <math>\sqrt[5]{\frac{200}{27}}</math>, which are approximately 1195.7 ¢ and 693.352 ¢. | But sometimes we have a tie between tunings for least average damage, though. For example, if we had we done a unity-weight tuning, in which case <math>W = I</math>, and included the interval <math>\frac85</math> in our set, we would have found that quarter-comma meantone tied with another tuning, one with generators of <math>\sqrt[5]{\frac{2560}{81}}</math> and <math>\sqrt[5]{\frac{200}{27}}</math>, which are approximately 1195.7 ¢ and 693.352 ¢. | ||
In this case, we fall back to our general method, which is equipped to find the true optimum somewhere in between these two extreme ends of goodness, albeit as an approximate solution.<ref group="note">The article for the minimax tuning scheme, [[Target tunings]], suggests that you fall back to the miniRMS method to tie-break between these, but that sort of misses the point of the problem. The two tied points are on extreme opposite ends of the slice of good solutions, and the optimum solution lies somewhere in between them. We don't want the tie-break to choose one or the other extreme; we want to find a better solution somewhere in between them.</ref> This method is discussed here: [[Dave Keenan & Douglas Blumeyer's guide to RTT/Tuning computation#Tie_breaking:_power_limit_method|power limit method]]. Or, if you'd like a refresher on how to think about non-unique tunings, please see [[Dave Keenan & Douglas Blumeyer's guide to RTT | In this case, we fall back to our general method, which is equipped to find the true optimum somewhere in between these two extreme ends of goodness, albeit as an approximate solution.<ref group="note">The article for the minimax tuning scheme, [[Target tunings]], suggests that you fall back to the miniRMS method to tie-break between these, but that sort of misses the point of the problem. The two tied points are on extreme opposite ends of the slice of good solutions, and the optimum solution lies somewhere in between them. We don't want the tie-break to choose one or the other extreme; we want to find a better solution somewhere in between them.</ref> This method is discussed here: [[Dave Keenan & Douglas Blumeyer's guide to RTT/Tuning computation#Tie_breaking:_power_limit_method|power limit method]]. Or, if you'd like a refresher on how to think about non-unique tunings, please see [[Dave Keenan & Douglas Blumeyer's guide to RTT/Tuning fundamentals#Non-unique tunings]]. | ||
We note that there may be a way to find an exact solution to a nested miniaverage, in a similar fashion to the nested minimax discussed in the coinciding-damage method section below, but it raises some conceptual issues about what a nested miniaverage even means.<ref group="note">There does not seem to be any consensus about how to identify a true optimum in the case of multiple solutions when <math>p=1</math>. See https://en.wikipedia.org/wiki/Least_absolute_deviations#Properties, https://www.researchgate.net/publication/223752233_Dealing_with_the_multiplicity_of_solutions_of_the_l1_and_l_regression_models, and https://stats.stackexchange.com/questions/275931/is-it-possible-to-force-least-absolute-deviations-lad-regression-to-return-the.</ref> We have done some pondering of this problem but it remains open; we didn't prioritize solving it, on account of the fact that nobody uses miniaverage tunings anyway. | We note that there may be a way to find an exact solution to a nested miniaverage, in a similar fashion to the nested minimax discussed in the coinciding-damage method section below, but it raises some conceptual issues about what a nested miniaverage even means.<ref group="note">There does not seem to be any consensus about how to identify a true optimum in the case of multiple solutions when <math>p=1</math>. See https://en.wikipedia.org/wiki/Least_absolute_deviations#Properties, https://www.researchgate.net/publication/223752233_Dealing_with_the_multiplicity_of_solutions_of_the_l1_and_l_regression_models, and https://stats.stackexchange.com/questions/275931/is-it-possible-to-force-least-absolute-deviations-lad-regression-to-return-the.</ref> We have done some pondering of this problem but it remains open; we didn't prioritize solving it, on account of the fact that nobody uses miniaverage tunings anyway. | ||
== With held-intervals == | == With held-intervals == | ||
The zero-damage method is easily modified to handle held-intervals along with target-intervals.<ref>In fact, the Target tunings page of the wiki uses this more complicated approach in order to realize pure octaves, and so the authors of this page had to reverse engineer from it how to make it work ''without'' any held-intervals.</ref> In short, rather than assembling our set of unchanged-interval bases <math>\mathrm{U}_1</math> through <math>\mathrm{U}_n</math> (where <math>n = {{k}\choose{r}}</math>) corresponding to the zero-damage points by finding every combination of <math>r</math> different ones of our <math>k</math> target-intervals (one for each generator to be responsible for tuning exactly), instead we must first reserve <math>h</math> (''held''-unchanged-interval count) columns of each <math>\mathrm{U}_n</math> for the held-intervals, leaving only the remaining <math>r - h</math> columns to be assembled from the target-intervals as normal. So, we'll only have <math>{{k}\choose{r - h}}</math> candidate tunings / zero-damage points / unchanged-interval bases in this case. | The zero-damage method is easily modified to handle held-intervals along with target-intervals.<ref group="note">In fact, the Target tunings page of the wiki uses this more complicated approach in order to realize pure octaves, and so the authors of this page had to reverse engineer from it how to make it work ''without'' any held-intervals.</ref> In short, rather than assembling our set of unchanged-interval bases <math>\mathrm{U}_1</math> through <math>\mathrm{U}_n</math> (where <math>n = {{k}\choose{r}}</math>) corresponding to the zero-damage points by finding every combination of <math>r</math> different ones of our <math>k</math> target-intervals (one for each generator to be responsible for tuning exactly), instead we must first reserve <math>h</math> (''held''-unchanged-interval count) columns of each <math>\mathrm{U}_n</math> for the held-intervals, leaving only the remaining <math>r - h</math> columns to be assembled from the target-intervals as normal. So, we'll only have <math>{{k}\choose{r - h}}</math> candidate tunings / zero-damage points / unchanged-interval bases in this case. | ||
In other words, if <math>\mathrm{U}_n</math> is one of the unchanged-interval bases characterizing a candidate miniaverage tuning, then it must contain <math>\mathrm{H}</math> itself, the held-interval basis, which does not yet fully characterize our tuning, leaving some wiggle room (otherwise we'd just use the "[[#Only held-intervals method|only held-intervals]]" approach, discussed later). | In other words, if <math>\mathrm{U}_n</math> is one of the unchanged-interval bases characterizing a candidate miniaverage tuning, then it must contain <math>\mathrm{H}</math> itself, the held-interval basis, which does not yet fully characterize our tuning, leaving some wiggle room (otherwise we'd just use the "[[#Only held-intervals method|only held-intervals]]" approach, discussed later). | ||
| Line 5,190: | Line 5,189: | ||
And convert those to generator tuning maps: {{map|1200 701.955}}, {{map|1200 696.578}}, and {{map|1200 694.786}}. Note that every one of these has a pure-octave period. Then check the damage sums: 353.942 ¢(U), 89.083 ¢(U), and 110.390 ¢(U), respectively. So that tells us that we want the middle result of these three, {{map|1200 696.578}}, as the minimization of the <math>1</math>-mean of unity-weight damage to the 6-TILT, when we're constrained to the octave being unchanged. | And convert those to generator tuning maps: {{map|1200 701.955}}, {{map|1200 696.578}}, and {{map|1200 694.786}}. Note that every one of these has a pure-octave period. Then check the damage sums: 353.942 ¢(U), 89.083 ¢(U), and 110.390 ¢(U), respectively. So that tells us that we want the middle result of these three, {{map|1200 696.578}}, as the minimization of the <math>1</math>-mean of unity-weight damage to the 6-TILT, when we're constrained to the octave being unchanged. | ||
For a rank-3 temperament, with 2 held-intervals, we'd again have 8 choose 1 = 8 tunings to check. With 1 held-interval, we'd have 8 choose 2 = 28 tunings to check. | For a rank-3 temperament, with 2 held-intervals, we'd again have 8 choose 1 = 8 tunings to check. With 1 held-interval, we'd have 8 choose 2 = 28 tunings to check. | ||
== For all-interval tuning schemes == | == For all-interval tuning schemes == | ||
| Line 7,558: | Line 7,557: | ||
=== Advanced tie-breaking example: Setup === | === Advanced tie-breaking example: Setup === | ||
To help illustrate advanced tie-breaking, we're going to look at a minimax-C tuning of [[augmented]] temperament, with mapping {{rket|{{map|3 0 7}} {{map|0 1 0}}}}. In particular, we're going to use the somewhat arbitrary target-interval set <math>\{ \frac32, \frac52, \frac53, \frac83, \frac95, \frac{16}{5}, \frac{15}{8}, \frac{18}{5} \}</math>. As a rank-2 temperament, we're going to be searching 3D tuning damage space. This temperament divides the octave into three parts, so our ballpark <math>g_1</math> is 400 ¢, and our second generator <math>g_2</math> is a free generator for prime 3, so it's going to be ballpark its pure tuning of 1901.955 ¢. | To help illustrate advanced tie-breaking, we're going to look at a minimax-C tuning of [[augmented (temperament)|augmented]] temperament, with mapping {{rket|{{map|3 0 7}} {{map|0 1 0}}}}. In particular, we're going to use the somewhat arbitrary target-interval set <math>\{ \frac32, \frac52, \frac53, \frac83, \frac95, \frac{16}{5}, \frac{15}{8}, \frac{18}{5} \}</math>. As a rank-2 temperament, we're going to be searching 3D tuning damage space. This temperament divides the octave into three parts, so our ballpark <math>g_1</math> is 400 ¢, and our second generator <math>g_2</math> is a free generator for prime 3, so it's going to be ballpark its pure tuning of 1901.955 ¢. | ||
Here's an aerial view on the tuning damage space, where we've "clipped" every damage graph hyper-V where it has gone out-of-bounds, above 150 ¢(C) damage; that is, we've colored it in grey and flattened it across the top of the box of our visualization. This lets us focus in clearly on the region of real interest, which is where all target-intervals' damages are less than this cap at the same time. This is the multicolored crater in the middle here: | Here's an aerial view on the tuning damage space, where we've "clipped" every damage graph hyper-V where it has gone out-of-bounds, above 150 ¢(C) damage; that is, we've colored it in grey and flattened it across the top of the box of our visualization. This lets us focus in clearly on the region of real interest, which is where all target-intervals' damages are less than this cap at the same time. This is the multicolored crater in the middle here: | ||