Constrained tuning: Difference between revisions

Improve notation: getting rid of A and B, only V and M now. Code bugfix
Line 6: Line 6:


== Definition ==
== Definition ==
Given a temperament [[mapping]] A and the [[JIP]] J<sub>0</sub>, we specify a weight W, a skew X, and a ''p''-norm. Suppose the tuning is constrained by the eigenmonzo list B<sub>C</sub>. The goal is to find the generator list G by
Given a temperament [[mapping]] V and the [[JIP]] J, we specify a weight and a skew, represented by transformation matrices W and X, respectively, and a ''p''-norm. Suppose the tuning is constrained by the eigenmonzo list M<sub>C</sub>. The goal is to find the generator list G by


Minimize
Minimize


<math>\displaystyle \lVert GV - J \rVert_p </math>
<math>\displaystyle \lVert GV_{WX} - J_{WX} \rVert_p </math>


subject to
subject to


<math>\displaystyle (GA - J_0)B_{\rm C} = O </math>
<math>\displaystyle (GV - J)M_{\rm C} = O </math>


where V is the weight-skewed mapping and J the weight-skewed JIP, found by
where (·)<sub>WX</sub> denotes the weight-skew transformation, found by


<math>\displaystyle
<math>\displaystyle
\begin{align}
\begin{align}
V &= AWX \\
V_{WX} &= VWX \\
J &= J_0 WX
J_{WX} &= JWX
\end{align}
\end{align}
</math>
</math>


The problem is feasible if
The problem is feasible if
# rank (B<sub>C</sub>) ≤ rank (A), and
# rank (M<sub>C</sub>) ≤ rank (V), and
# The subspaces of B<sub>C</sub> and N (A) are [[Wikipedia:linear independence|linearly independent]].
# The subspaces of M<sub>C</sub> and N (V) are [[Wikipedia:linear independence|linearly independent]].


== Computation ==
== Computation ==
Line 34: Line 34:
{{Databox| Code |
{{Databox| Code |
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
# © 2020-2022 Flora Canou | Version 0.22.0
# © 2020-2022 Flora Canou | Version 0.22.1
# This work is licensed under the GNU General Public License version 3.
# This work is licensed under the GNU General Public License version 3.


Line 55: Line 55:
     return main, subgroup
     return main, subgroup


def get_weight (subgroup, wtype = "tenney"):
def get_weight (subgroup, wtype = "tenney", wamount = 1):
     if wtype == "tenney":
     if wtype == "tenney":
         return np.diag (1/np.log2 (subgroup))
         weight_vec = np.reciprocal (np.log2 (np.array (subgroup, dtype = float)))
    elif wtype == "wilson" or wtype == "benedetti":
        weight_vec = np.reciprocal (np.array (subgroup, dtype = float))
    elif wtype == "equilateral":
        weight_vec = np.ones (len (subgroup))
     elif wtype == "frobenius":
     elif wtype == "frobenius":
         return np.eye (len (subgroup))
         warnings.warn ("\"frobenius\" is deprecated. Use \"equilateral\" instead. ")
    elif wtype == "benedetti":
         weight_vec = np.ones (len (subgroup))
         return np.diag (1/np.array (subgroup))
     else:
     else:
         warnings.warn ("weighter type not supported, using default (\"tenney\")")
         warnings.warn ("weighter type not supported, using default (\"tenney\")")
         return get_weight (subgroup, wtype = "tenney")
         return get_weight (subgroup, wtype = "tenney", wamount = wamount)
    return np.diag (weight_vec**wamount)


def get_skew (subgroup, skew = 0, order = 2):
def get_skew (subgroup, skew = 0, order = 2):
Line 157: Line 161:
=
=
\begin{bmatrix}
\begin{bmatrix}
VV^{\mathsf T} & AB \\
V_{WX} V_{WX}^{\mathsf T} & VM \\
(AB)^{\mathsf T} & O
(VM)^{\mathsf T} & O
\end{bmatrix}^{-1}
\end{bmatrix}^{-1}


\begin{bmatrix}
\begin{bmatrix}
VJ^{\mathsf T}\\
V_{WX} J_{WX}^{\mathsf T}\\
(J_0 B)^{\mathsf T}
(JM)^{\mathsf T}
\end{bmatrix}
\end{bmatrix}
</math>
</math>
Line 196: Line 200:
The step size ''g'' can be found by
The step size ''g'' can be found by


<math>\displaystyle g = 1/\operatorname {mean} (V)</math>
<math>\displaystyle g = 1/\operatorname {mean} (V_{WX})</math>


The edo number ''n'' can be found by
The edo number ''n'' can be found by


<math>\displaystyle n = 1/g = \operatorname {mean} (V)</math>
<math>\displaystyle n = 1/g = \operatorname {mean} (V_{WX})</math>


Unlike TE or TOP, the optimal edo number space in TOC is linear with respect to A. That is, if A = ''α''A<sub>1</sub> + ''β''A<sub>2</sub>, then
Unlike TE or TOP, the optimal edo number space in TOC is linear with respect to V. That is, if V = ''α''V<sub>1</sub> + ''β''V<sub>2</sub>, then


<math>\displaystyle
<math>\displaystyle
\begin{align}
\begin{align}
n &= \operatorname {mean} (AW) \\
n &= \operatorname {mean} (VWX) \\
&= \operatorname {mean} ((\alpha A_1 + \beta A_2)W) \\
&= \operatorname {mean} ((\alpha V_1 + \beta V_2)WX) \\
&= \operatorname {mean} (\alpha A_1 W) + \operatorname {mean} (\beta A_2 W) \\
&= \operatorname {mean} (\alpha V_1 WX) + \operatorname {mean} (\beta V_2 WX) \\
&= \alpha n_1 + \beta n_2
&= \alpha n_1 + \beta n_2
\end{align}
\end{align}
</math>
</math>


As a result, the [[Relative interval error #Linearity|relative error space]] is also linear with respect to A.  
As a result, the [[Relative interval error #Linearity|relative error space]] is also linear with respect to V.  


For example, the relative errors of 12ettoc5 (12et in 5-limit TOC) is
For example, the relative errors of 12ettoc5 (12et in 5-limit TOC) is