Douglas Blumeyer's RTT How-To: Difference between revisions

Cmloegcmluin (talk | contribs)
use \log
Cmloegcmluin (talk | contribs)
update re: canonical form
Line 610: Line 610:
And ta-da! You’ve found a mapping from a comma-basis, and it is {{ket|{{map|19 30 44}}}}. In other words, for this temperament, you have converted a basis for its null-space to a row-basis for its mapping row-space. Feel free to try this with any other combination of two commas tempered out by this mapping-row.
And ta-da! You’ve found a mapping from a comma-basis, and it is {{ket|{{map|19 30 44}}}}. In other words, for this temperament, you have converted a basis for its null-space to a row-basis for its mapping row-space. Feel free to try this with any other combination of two commas tempered out by this mapping-row.


So why the anti-transpose sandwich? What we (and everyone) want in a canonical mapping is to have a triangle of zeros in the bottom left corner. What we want in a comma-basis is also to have a triangle of zeros in the bottom left corner. But the comma-basis is on the other side of duality from the mapping, so it must be transposed before we can apply our nullSpaceBasis[] function to it, because that function is designed for mappings. But when we transpose the comma-basis we end up with the triangle of zeros in the top right. If we take the null-space of that and then transpose it back again, we don't get our canonical form of the mapping, we get a mapping with a triangle of zeros in the top right. The way to fix this is to anti-transpose instead of transpose, before and after taking the null-space. Because when you anti-transpose the comma-basis, you still turn columns into rows, but this time the triangle of zeros stays on the bottom left.
So why the anti-transpose sandwich? What we (and everyone) want in a mapping is to have a triangle of zeros in the bottom left corner. What we want in a comma-basis is also to have a triangle of zeros in the bottom left corner. But the comma-basis is on the other side of duality from the mapping, so it must be transposed before we can apply our nullSpaceBasis[] function to it, because that function is designed for mappings. But when we transpose the comma-basis we end up with the triangle of zeros in the top right. If we take the null-space of that and then transpose it back again, we don't get a nice form of the mapping, we get a mapping with a triangle of zeros in the top right. The way to fix this is to anti-transpose instead of transpose, before and after taking the null-space. Because when you anti-transpose the comma-basis, you still turn columns into rows, but this time the triangle of zeros stays on the bottom left.


Here's the Wolfram Language implementation:
Here's the Wolfram Language implementation:
Line 1,079: Line 1,079:
</math>
</math>


The latter is sometimes called the “musician’s form” of the temperament, because it’s easy to reason about from a musical perspective. But it turns out there’s not a particularly clean function for consistently getting to it, or even defining it.
In this form, as we observed, the period is an octave and the generator is a fifth, which is a popular and convenient way to think about meantone. But there are other good forms this mapping-row-basis could be put into.


Another form you might want the mapping-row-basis in is the type Graham Breed's temperament finder puts them in, where all values in a mapping-row-basis row may be negative, but this is in the service of the generator being positive, and less than half the size of the period. For example, for meantone, we'd want the fourth instead of the fifth, and we can see that
For example, you might want the form that Graham Breed's temperament finder puts them in, where all values in a mapping-row-basis row may be negative, but this is in the service of the generator being positive, and less than half the size of the period. For example, for meantone, we'd want the fourth instead of the fifth, and we can see that


<math>
<math>
Line 1,090: Line 1,090:
</math>
</math>


maps the fourth (4/3, {{vector|2 -1 0 }}) to {{vector|0 1}}.
maps the fourth (4/3, {{vector|2 -1 0 }}) to {{vector|0 1}}. That form is called [[mingen]] form.  


It’s often the case that a temperament’s nullity is greater than 1 or its rank is greater than 1, and therefore we have an infinitude of equivalent ways of expressing the comma-basis or the mapping-row-basis. This can be problematic, if we want to efficiently communicate about and catalog temperaments. It’s good to have a standardized form in these cases. The approach RTT takes here is to get these matrices into '''“canonical” form'''. In plain words, this just means: we have a function which takes in a matrix and spits out a matrix of the same shape, and no matter which matrix we input from a set of matrices which we consider all to be equivalent to each other, it will spit out the same result. This output is what we call the “canonical” matrix, and it can therefore uniquely identify a temperament.
But there are still more forms! One very important form is called '''[[canonical form]]'''.
 
It’s often the case that a temperament’s nullity is greater than 1 or its rank is greater than 1, and therefore we have an infinitude of equivalent ways of expressing the comma-basis or the mapping-row-basis. This can be problematic, if we want to efficiently communicate about and catalog temperaments. It’s good to have a standardized form in these cases. The approach RTT takes here is to get these matrices into canonical form. In plain words, this just means: we have a function which takes in a matrix and spits out a matrix of the same shape, and no matter which matrix we input from a set of matrices which we consider all to be equivalent to each other, it will spit out the same result. This output is thereby “canonical”, and it can therefore uniquely identify a temperament.


To be clear, canonical form isn’t necessary to avoid ambiguity: you will never find a comma-basis that could represent more than one temperament.
To be clear, canonical form isn’t necessary to avoid ambiguity: you will never find a comma-basis that could represent more than one temperament.
I've seen many specialized matrix forms used in RTT for problems like this, such as "[[IRREF|integer canonical form]]", [https://en.wikipedia.org/wiki/Hermite_normal_form Hermite Normal Form], and maybe others. What we will be using here is a form I’ve developed recently in collaboration with Dave Keenan that we’re calling [[TBD canonical form]].<ref>Historically, Hermite Normal Form was used as if it gave a unique identifier for each temperament, when in fact it did not. It failed to remove possibly-hidden common factors in the columns of comma-bases and rows of mapping-row-bases, leading to situations which were named "[[torsion]]" and "[[contorsion]]", respectively. Hermite Canonical Form goes too far; it reduces the matrix's diagonals to all 1's or 0's, which loses important information for temperaments with non-octave periods. Integer canonical form removes such common factors without compromising non-octave periods, therefore truly giving a unique identifier, and also eliminating the need to deal with enfactored mappings or comma-bases.</ref>.


For example, the canonical form of meantone is:
For example, the canonical form of meantone is:
Line 1,107: Line 1,107:
</math>
</math>


If you take the integer canonical form of {{ket|{{map|5 8 12}} {{map|7 11 16}}}}, that’s what you get. It’s also what you get if you take the integer canonical form of {{ket|{{map|12 19 28}} {{map|19 30 44}}}}, etc. That’s the power of canonicalization.
So if you take the canonical form of {{ket|{{map|5 8 12}} {{map|7 11 16}}}}, that’s what you get. It’s also what you get if you take the canonical form of {{ket|{{map|12 19 28}} {{map|19 30 44}}}}, or any equivalent other mapping-row-basis. That’s the power of canonicalization.
 
To find the integer canonical form, we can combine the two processes we already know how to do: null-space for getting from a mapping-row-basis to a comma-basis, and anti-null-space to get from a comma-basis to a mapping-row-basis. Basically, to achieve canonical form of one type of basis, we convert it into the other type of basis, then back, and voilà: canonicalization.


{| class="wikitable"
Canonical form can be done by hand, but it's a bit involved, because it requires first [[defactoring]] and then putting into [[Hermite Normal Form]]. I've demonstrated how to do these processes at the links provided.
!input
!output
|-
|<code>antiTranspose[m_] := Transpose[Reverse[m,{1,2}]]</code>


 
Canonicalization used to be achieved in RTT through the use of the "wedgie", an object that involves more advanced math. So while you may see "wedgies" around on the wiki and elsewhere, don't worry — you don't need to worry about them in order to do RTT. If you want to learn more anyway, I've gathered up everything I figured out about those here: [[VEA]].
<code>multByLcd[row_] := Apply[LCM,Denominator[row]]*row</code>
 
<code>canonicalForm[m_] := Map[multByLcd,RowReduce[m]]</code>
 
<code>columnCanonicalForm[m_] := antiTranspose[canonicalForm[antiTranspose[m]]]</code>
 
 
<code>canonicalForm[{{5,8,12},{7,11,16}}]</code>
 
<code>columnCanonicalForm[{{-4,-10},{4,-1},{-1,5}}]</code>
|{{1,0,-4},{0,1,4}}
{{-44,-30},{0,19},{19,0}}
|}


== other topics (TBD) ==
== other topics (TBD) ==