Generator preimage: Difference between revisions
Cmloegcmluin (talk | contribs) →Method using the Smith Normal Form: clarify, because diagonal matrices are typically square |
Cmloegcmluin (talk | contribs) leaving original art by Gene alone, I've revised the material I've added in the past (a brief intro, explanations of algorithms, examples, implementations) to use nomenclature I feel ls less confusing and ambiguous |
||
| Line 1: | Line 1: | ||
Every [[generator]] of a [[regular temperament]] has a preimage, which is an infinite set of JI intervals that map to it. A [[transversal]] means a selection of one representative element from each of a list of sets. So if for each generator in our temperament's list of generators we choose one JI interval that maps to it, then we have a generators preimage transversal for that temperament. | |||
=Definition= | =Technical Definition= | ||
Given a reduced list of [[Harmonic_Limit|p-limit]] vals V, we may define a set of transversal generators for V as a set of p-limit intervals q such that one of the vals of V maps q to 1 and the rest map it to 0. By ''reduced'' is meant that the GCD of the elements of each of the vals is 1--or in other words, none of the vals are [[contorted]]--and that they are [[linearly independent]], so that if there are r vals, the rank of V as a matrix is r. | Given a reduced list of [[Harmonic_Limit|p-limit]] vals V, we may define a set of transversal generators for V as a set of p-limit intervals q such that one of the vals of V maps q to 1 and the rest map it to 0. By ''reduced'' is meant that the GCD of the elements of each of the vals is 1--or in other words, none of the vals are [[contorted]]--and that they are [[linearly independent]], so that if there are r vals, the rank of V as a matrix is r. | ||
| Line 8: | Line 8: | ||
q ≅ t1^v1(q) * t2^v2(q) * ... * tr^vr(q) | q ≅ t1^v1(q) * t2^v2(q) * ... * tr^vr(q) | ||
In this way the transversal generators provide a | In this way the transversal generators provide a transversal of the p-limit, and hence the name. | ||
=Examples= | =Examples= | ||
| Line 21: | Line 21: | ||
For another example, consider [<1 1 1 2|, <0 2 1 1|, <0 0 2 1|] which is the [[Normal_lists|normal val list]] for breed temperament, the temperament tempering out 2401/2400. A corresponding list of transversal generators is [2, 49/40, 10/7]. | For another example, consider [<1 1 1 2|, <0 2 1 1|, <0 0 2 1|] which is the [[Normal_lists|normal val list]] for breed temperament, the temperament tempering out 2401/2400. A corresponding list of transversal generators is [2, 49/40, 10/7]. | ||
=Finding the transversal | =Finding the generators preimage transversal= | ||
Two methods for finding transversal | Two methods for finding the generators preimage transversal have been developed. The first was developed by [[Gene Ward Smith]] sometime in or before June 2011, which uses the [[Hermite normal form]]. The second was developed by [[User:Sintel|Sintel]] in December 2021, which uses the [[Smith normal form]]. | ||
== Method using the Smith Normal Form == | == Method using the Smith Normal Form == | ||
So we want to find a generators | So we want to find a generators preimage transversal <math>T</math> for a mapping <math>M</math> where: | ||
<math> | <math>MT = I,</math> | ||
and where <math>I</math> is the identity matrix. When this is the case, then for each generator of the temperament represented by <math>M</math>, a different column of <math> | and where <math>I</math> is the identity matrix. When this is the case, then for each generator of the temperament represented by <math>M</math>, a different column of <math>T</math> as a prime-count vector represents an interval that <math>M</math> maps to that generator. And when this <math>T</math> has all integer entries, then these generators are all JI. | ||
Essentially we need a way to do: | Essentially we need a way to do: | ||
| Line 39: | Line 39: | ||
<math> | <math> | ||
M^{-1} | M^{-1}MT = M^{-1}I \\ | ||
\cancel{M^{-1}M} | \cancel{M^{-1}M}T = M^{-1}I \\ | ||
T = M^{-1} | |||
</math> | </math> | ||
| Line 82: | Line 82: | ||
<math> | <math> | ||
(L^{-1}DR^{-1}) | (L^{-1}DR^{-1})T = I | ||
</math> | </math> | ||
And we can proceed to solve this for our target <math> | And we can proceed to solve this for our target <math>T</math>. The rest is busywork. First, left-multiply by <math>L</math>: | ||
<math> | <math> | ||
LL^{-1}DR^{-1} | LL^{-1}DR^{-1}T = LI \\ | ||
\cancel{LL^{-1}}DR^{-1} | \cancel{LL^{-1}}DR^{-1}T = LI \\ | ||
DR^{-1} | DR^{-1}T = L | ||
</math> | </math> | ||
| Line 100: | Line 100: | ||
<math> | <math> | ||
D^{T}DR^{-1} | D^{T}DR^{-1}T = D^{T}L \\ | ||
\cancel{D^{T}D}R^{-1} | \cancel{D^{T}D}R^{-1}T = D^{T}L \\ | ||
R^{-1} | R^{-1}T = D^{T}L | ||
</math> | </math> | ||
| Line 110: | Line 110: | ||
<math> | <math> | ||
RR^{-1} | RR^{-1}T = RD^{T}L \\ | ||
\cancel{RR^{-1}} | \cancel{RR^{-1}}T = RD^{T}L \\ | ||
T = RD^{T}L | |||
</math> | </math> | ||
And there's our answer! It's still not necessarily giving the simplest or best JI generators, but arriving at those is an independent problem (perhaps by choosing a complexity metric and minimizing it though linear combinations with the commas and the other generators). | And there's our answer! It's still not necessarily giving the simplest or best JI generators, but arriving at those is an independent problem (perhaps by choosing a complexity metric and minimizing it though linear combinations with the commas and the other generators, or perhaps using LLL). | ||
=== Example === | === Example === | ||
| Line 161: | Line 161: | ||
And so some | And so some a transversal of the preimages of its generators are <math>RD^{T}L</math>: | ||
| Line 192: | Line 192: | ||
=== Wolfram Language implementation === | === Wolfram Language implementation === | ||
{{Databox| | {{Databox|jiT[]| | ||
<syntaxhighlight lang="mathematica"> | <syntaxhighlight lang="mathematica"> | ||
jiT[m_] := Module[{decomp, left, snf, right}, | |||
decomp = SmithDecomposition[m]; | decomp = SmithDecomposition[m]; | ||
left = Part[decomp, 1]; | left = Part[decomp, 1]; | ||
| Line 206: | Line 206: | ||
== Method using the Hermite Normal Form == | == Method using the Hermite Normal Form == | ||
We can find transversal | We can find a generators preimage transversal for V by the following procedure: | ||
<ul><li>Take the transpose of the [[Tenney-Euclidean_Tuning#The pseudoinverse|pseudoinverse]] of V, call that U</li><li>Find a basis for the commas of V</li><li>For each row U[i] of U, clear denominators and append the monzos of the comma basis for V</li><li>[[Saturation|Saturate]] the result to a list of monzos, call that S</li><li>Apply the ith val V[i] (dot product) to each element of S</li><li>Insert V[i].S[j] in front of the elements of S[j] as the first element, obtaining the jth element T[j] of a modified list T</li><li>Hermite reduce the modified list T, take the first row, and remove the first element (which should be a 1.)</li><li>Consider the rest to be a monzo and convert it to a rational number</li><li>This is a corresponding transveral generator to the ith val V[i] of V; it may be reduced to an equivalent generator of minimal [[Tenney_Height|Tenney height]] by multiplying by the commas of V</li></ul> | <ul><li>Take the transpose of the [[Tenney-Euclidean_Tuning#The pseudoinverse|pseudoinverse]] of V, call that U</li><li>Find a basis for the commas of V</li><li>For each row U[i] of U, clear denominators and append the monzos of the comma basis for V</li><li>[[Saturation|Saturate]] the result to a list of monzos, call that S</li><li>Apply the ith val V[i] (dot product) to each element of S</li><li>Insert V[i].S[j] in front of the elements of S[j] as the first element, obtaining the jth element T[j] of a modified list T</li><li>Hermite reduce the modified list T, take the first row, and remove the first element (which should be a 1.)</li><li>Consider the rest to be a monzo and convert it to a rational number</li><li>This is a corresponding transveral generator to the ith val V[i] of V; it may be reduced to an equivalent generator of minimal [[Tenney_Height|Tenney height]] by multiplying by the commas of V</li></ul> | ||
| Line 396: | Line 396: | ||
=== Wolfram Language implementation === | === Wolfram Language implementation === | ||
{{Databox| | {{Databox|jiT[]| | ||
<syntaxhighlight lang="mathematica"> | <syntaxhighlight lang="mathematica"> | ||
jiTEntry[u_, v_, c_] := Module[{base}, | |||
base = Transpose[columnHermiteDefactor[Join[{u}, Transpose[c]]]]; | base = Transpose[columnHermiteDefactor[Join[{u}, Transpose[c]]]]; | ||
| Line 404: | Line 404: | ||
]; | ]; | ||
jiT[m_] := Module[{c}, | |||
c = nullSpaceBasis[m]; | c = nullSpaceBasis[m]; | ||
Transpose[MapThread[ | Transpose[MapThread[jiTEntry[#1, #1, c]&, {Map[multByLcd,Transpose[PseudoInverse[m]]],m}]] | ||
]; | ]; | ||
jiT[{{1,2,4},{0,-1,-4}}] (* {{1,2},{0,-1},{0,0}} = 2/1 and 4/3 as expected *) | |||
</syntaxhighlight>}} | </syntaxhighlight>}} | ||