Generator form manipulation: Difference between revisions
Cmloegcmluin (talk | contribs) |
Cmloegcmluin (talk | contribs) |
||
Line 173: | Line 173: | ||
=== Wolfram Language implementation === | === Wolfram Language implementation === | ||
The below code essentially works through the input matrix M two rows at a time, beginning with the first two rows. Each pair of rows is "fixed" so that the second row is less than half of the first row. The same set of changes and potential recursions as described in the table in the previous section is used for each pair of rows. When the sizes of the generators is computed, a weighted Frobenius tuning is used for its computational frugality and reasonableness. | |||
<nowiki> | |||
jip[d_] := Map[Log2, Map[Prime,Range[d]]] | |||
tenneyWeights[m_] := DiagonalMatrix[1/jip[Last[Dimensions[m]]]] | |||
unweightedG[m_] := PseudoInverse[m] | |||
weightedG[m_] := tenneyWeights[m].PseudoInverse[m.tenneyWeights[m]] // N | |||
octaves[vOrVList_]:= N[jip[Length[vOrVList]].vOrVList, 10] | |||
cents[vOrVList_] := N[1200.octaves[vOrVList], 10] | |||
gens[m_] := cents[weightedG[m]] | |||
fixM[m_, i_] := Module[{localM, rp, rg, mGens, p, g, fixedRpRg, fixedM}, | |||
localM = m; | |||
rp = m[[i]]; | |||
rg = m[[i+1]]; | |||
mGens = gens[m]; | |||
p = mGens[[i]]; | |||
g = mGens[[i+1]]; | |||
fixedRpRg = Which[ | |||
g < -p, {rp-2*rg, rg}, | |||
-p <= g < -p/2, {rp-rg, rg}, | |||
-p/2 <= g < 0, {rp, -rg}, | |||
0 <= g <= p/2, {rp, rg}, | |||
p/2 < g <=p, {rp+rg, -rg}, | |||
p < g, {rp+2*rg, -rg} | |||
]; | |||
fixedM = Take[localM, i-1] ~ Join ~ fixedRpRg ~ Join ~ Drop[localM, i+1]; | |||
If[ | |||
g < -p || p < g, | |||
fixM[fixedM, i], | |||
fixedM | |||
] | |||
] | |||
mingen[m_] := Module[{localM, rp, rg, fixedM}, | |||
localM = m; | |||
For[i = 1, i < Length[localM], i++, | |||
localM = fixM[localM, i]; | |||
]; | |||
localM | |||
] | |||
(* examples *) | |||
tester[m_] := Module[{ming}, | |||
ming = mingen[m]; | |||
"in: " <> ToString@m <> " w/ gens: " <> ToString@gens[m] <> "\nout: " <> ToString@ming <> " w/ gens: " <> ToString@gens[ming] | |||
] | |||
tester[{{1, 0, -4}, {0, -1, -4}}] | |||
tester[{{1, 1, 0}, {0, -1, -4}}] | |||
tester[{{1, 2, 4}, {0, 1, 4}}] | |||
tester[{{1, 2, 4}, {0, -1, -4}}] | |||
tester[{{1, 1, 0}, {0, 1, 4}}] | |||
tester[{{1, 0, -4}, {0, 1, 4}}] | |||
tester[{{12, 19, 28}}] | |||
tester[{{1, 2, 3}, {0, 3, 5}}] | |||
tester[{{1, 0, -4, -13}, {0, 1, 4, 10}}] | |||
tester[{{5, 8, 0}, {0, 0, 1}}] | |||
tester[{{2, 0, 11, 12}, {0, 1, -2, -2}}] | |||
tester[{{1, 0, 0, -5}, {0, 1, 0, 2}, {0, 0, 1, 2}}] | |||
tester[{{1, 0, 0, -5, 12}, {0, 1, 0, 2, -1}, {0, 0, 1, 2, -3}}] | |||
tester[{{1, 8, 0}, {0, 11, -4}}] | |||
dimensionality = RandomInteger[{3, 6}]; | |||
rank = RandomInteger[{2, dimensionality}]; | |||
randomM = RandomInteger[{-10, 10}, {rank, dimensionality}] | |||
tester[randomM] | |||
</nowiki> | |||
=== limitations === | === limitations === | ||
Beyond rank-2, the mingen form of a temperament is no longer unique. You can always get smaller and smaller generators. ### I believe there's more to say here, if that's even precisely correct | Beyond rank-2, the mingen form of a temperament is no longer unique. You can always get smaller and smaller generators. ### I believe there's more to say here, if that's even precisely correct |