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 ===
{{Todo|inline=1|cleanup|comment=Unify variable names with the other sections. }}
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 <math>g</math> can be expressed as:
We have the same thing with generator maps, meaning that any pure-octave generator map ''G'' can be expressed as:


$$
$$ G = HB + G_0 $$
g = hB + x
$$


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.


* ''x'' is any random generator map giving pure octaves
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:
* ''B'' is a matrix whose rows are a basis for the subspace of generator maps with octave coordinate set to 0
* ''h'' is a free variable.
 
Given that, and assuming ''M'' is our mapping matrix, ''W'' our weighting matrix, and ''j'' our JIP, we can solve for the best possible ''g'' in closed form:


$$
$$ GV_X \approx J_X $$
gMW ≈ jW
$$


which becomes
which becomes


$$
$$
\left(hB + x\right)MW ≈ jW \\
\begin{align}
h = \left(j - xM\right)W \cdot \left(BMW\right)^\dagger
\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 weighting matrix, and so we can use this to compute an arbitrary TWE norm very quickly in closed-form. Here is some Python code:
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