Constrained tuning: Difference between revisions
m →Computation: update |
→Simple fast closed-form algorithm: cleanup: unify variable names with the other sections. Fix markup. Also important clarifications on the dimensionalities of these variables. |
||
Line 201: | Line 201: | ||
=== Simple fast closed-form algorithm === | === Simple fast closed-form algorithm === | ||
Another way to compute the CTE and CWE tunings, and the CTWE tuning in general, is to use the pseudoinverse. | Another way to compute the CTE and CWE tunings, and the CTWE tuning in general, is to use the pseudoinverse. | ||
The basic idea is that the set of all pure-octave tuning maps of some temperament will be the intersection of a linear subspace and a shifted hyperplane, and thus will be a shifted subspace. This means that any pure-octave tuning map can be expressed as the sum of some arbitrary "reference" pure-octave tuning map for the temperament, plus some other one also in the temperament whose octave-coordinate is 0. The set of all such tuning maps of the latter category form a linear subspace. | The basic idea is that the set of all pure-octave tuning maps of some temperament will be the intersection of a linear subspace and a shifted hyperplane, and thus will be a shifted subspace. This means that any pure-octave tuning map can be expressed as the sum of some arbitrary "reference" pure-octave tuning map for the temperament, plus some other one also in the temperament whose octave-coordinate is 0. The set of all such tuning maps of the latter category form a linear subspace. | ||
We have the same thing with generator maps, meaning that any pure-octave generator map | We have the same thing with generator maps, meaning that any pure-octave generator map ''G'' can be expressed as: | ||
$$ | $$ G = HB + G_0 $$ | ||
$$ | |||
where | where | ||
* ''G''<sub>0</sub> is any random generator map giving pure octaves; | |||
* ''B'' is an (''r'' - 1)×''r'' matrix whose rows are a basis for the subspace of generator maps with octave coordinate set to 0; | |||
* ''H'' is an (''r'' - 1)-element covector free variable. | |||
Given that, and assuming ''V'' is our mapping matrix, ''X'' our transformation matrix, and ''J'' our just tuning map, we can solve for the best possible ''G'' in closed form: | |||
Given that, and assuming '' | |||
$$ | $$ GV_X \approx J_X $$ | ||
$$ | |||
which becomes | which becomes | ||
$$ | $$ | ||
\left( | \begin{align} | ||
\left( HB + G_x \right) V_X &\approx J_X \\ | |||
H &= \left( J_X - G_0 V_X \right) \cdot \left( BV_X \right)^+ | |||
\end{align} | |||
$$ | $$ | ||
We note that this also works for any | We note that this also works for any transformation matrix, and so we can use this to compute an arbitrary TWE norm very quickly in closed-form. Here is some Python code: | ||
{{Databox|Code| | {{Databox|Code| | ||
Line 265: | Line 260: | ||
# All pure-octave generator maps are just pure_octave_start + something in | # All pure-octave generator maps are just pure_octave_start + something in | ||
# the above row space. Now we have to solve | # the above row space. Now we have to solve | ||
# (h@B + x)@M@W ≈ j@W | # (h @ B + x) @ M @ W ≈ j @ W | ||
# which, solving for h and doing the algebra out gives: | # which, solving for h and doing the algebra out gives: | ||
h = (j - x@M)@W @ pinv(B@M@W) | h = (j - x @ M) @ W @ pinv(B @ M @ W) | ||
g = h@B + x | g = h @ B + x | ||
t = g@M | t = g @ M | ||
return g, t | return g, t | ||