Constrained tuning: Difference between revisions

Definition: make it match the optimization page
Line 30: Line 30:


== Computation ==
== Computation ==
As a standard optimization problem, numerous algorithms exist to solve it, such as [[Wikipedia: Sequential quadratic programming|sequential quadratic programming]], to name one. [[Flora Canou]]'s [https://github.com/FloraCanou/temperament_evaluator/blob/bbe4d6b86f099117263824574ef408ffe3c92e95/te_optimizer_legacy.py tuning optimizer] is such an implementation in [https://www.python.org Python]. Note: it depends on [https://scipy.org/ Scipy].  
As a standard optimization problem, numerous algorithms exist to solve it, such as [[Wikipedia: Sequential quadratic programming|sequential quadratic programming]], to name one. [[Flora Canou]]'s [https://github.com/FloraCanou/temperament_evaluator/blob/3c56c06fabba86f71606c3b6eec64cef3179240c/te_optimizer_legacy.py tuning optimizer] is such an implementation in [https://www.python.org Python]. Note: it depends on [https://scipy.org/ Scipy].  


{{Databox| Code |
{{Databox| Code |
<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
# © 2020-2022 Flora Canou | Version 0.21.3
# © 2020-2022 Flora Canou | Version 0.22.0
# 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 69: Line 69:
     if skew == 0:
     if skew == 0:
         return np.eye (len (subgroup))
         return np.eye (len (subgroup))
    elif skew == np.inf:
        return np.eye (len (subgroup)) - np.ones ((len (subgroup), len (subgroup)))/len(subgroup)
     elif order == 2:
     elif order == 2:
         r = skew/(len (subgroup)*skew**2 + 1)
         r = skew/(len (subgroup)*skew**2 + 1)
         return np.append (np.eye (len (subgroup)) - skew*r*np.ones ((len (subgroup), len (subgroup))),
         return np.append (
            np.eye (len (subgroup)) - skew*r*np.ones ((len (subgroup), len (subgroup))),
             r*np.ones ((len (subgroup), 1)), axis = 1)
             r*np.ones ((len (subgroup), 1)), axis = 1)
     else:
     else:
         raise NotImplementedError ("Weil skew only works with Euclidean norm as of now.")
         raise NotImplementedError ("Weil skew only works with Euclidean norm as of now.")


def weightskewed (main, subgroup, wtype = "tenney", skew = 0, order = 2):
def weightskewed (main, subgroup, wtype = "tenney", wamount = 1, skew = 0, order = 2):
     return main @ get_weight (subgroup, wtype) @ get_skew (subgroup, skew, order)
     return main @ get_weight (subgroup, wtype, wamount) @ get_skew (subgroup, skew, order)


def error (gen, map, jip, order):
def error (gen, map, jip, order):
     return linalg.norm (gen @ map - jip, ord = order)
     return linalg.norm (gen @ map - jip, ord = order)


def optimizer_main (map, subgroup = None, wtype = "tenney", skew = 0, order = 2,
def optimizer_main (map, subgroup = None, wtype = "tenney", wamount = 1, skew = 0, order = 2,
         cons_monzo_list = None, des_monzo = None, show = True):
         cons_monzo_list = None, des_monzo = None, show = True):
     map, subgroup = get_subgroup (np.array (map), subgroup)
     map, subgroup = get_subgroup (np.array (map), subgroup)


     jip = np.log2 (subgroup)*SCALAR
     jip = np.log2 (subgroup)*SCALAR
     map_wx = weightskewed (map, subgroup, wtype, skew, order)
     map_wx = weightskewed (map, subgroup, wtype, wamount, skew, order)
     jip_wx = weightskewed (jip, subgroup, wtype, skew, order)
     jip_wx = weightskewed (jip, subgroup, wtype, wamount, skew, order)
     if order == 2 and cons_monzo_list is None: #te with no constraints, simply use lstsq for better performance
     if order == 2 and cons_monzo_list is None: #te with no constraints, simply use lstsq for better performance
         res = linalg.lstsq (map_w.T, jip_wx)
         res = linalg.lstsq (map_wx.T, jip_wx)
         gen = res[0]
         gen = res[0]
         print ("L2 tuning without constraints, solved using lstsq. ")
         print ("L2 tuning without constraints, solved using lstsq. ")
Line 164: Line 167:
</math>
</math>


which is almost an analytical solution. Notice we introduced the vector of lagrange multipliers Λ, with length equal to the number of constraints. The lagrange multipliers have no concrete meaning for the resulting tuning, so they can be discarded.  
which is almost an analytical solution. Notice we introduced the vector of lagrange multipliers Λ, with length equal to the number of constraints. The lagrange multipliers have no concrete meaning for the resulting tuning, so they can be discarded.


== CTE tuning vs CTWE tuning ==
== CTE tuning vs CTWE tuning ==