DR error measures: Difference between revisions

From Xenharmonic Reference
No edit summary
No edit summary
Line 19: Line 19:
to obtain the least-squares linear error.
to obtain the least-squares linear error.


== Partially DR (one free delta) ==
 
== Partially DR (arbitrary) ==
=== Partially DR (one free variable) ===
Suppose we wish to approximate a target delta signature of the form <math>+\delta_1 +? +\delta_3</math> with the chord <math>1:f_1:f_2:f_3</math> (where the +? is free to vary). By a derivation similar to the above, the least-squares problem is
 
<math>
\displaystyle {\underset{x,y}{\text{minimize}} \sqrt{\bigg(\frac{x + \delta_1}{x} - f_1 \bigg)^2 + \bigg(\frac{x+\delta_1 + y}{x} - f_2 \bigg)^2 + \bigg(\frac{x+\delta_1 + y + \delta_3}{x} - f_3 \bigg)^2 }},
</math>
 
where ''y'' represents the free delta +?.
 
We can set the partial derivatives with respect to ''x'' and ''y'' of the inner expression equal to zero (since the derivative of sqrt() is never 0) and use SymPy to solve the system:
 
<syntaxhighlight lang="py">
import sympy
x = sympy.Symbol("x", real=True)
y = sympy.Symbol("y", real=True)
d1 = sympy.Symbol("\\delta_{1}", real=True)
d2 = sympy.Symbol("\\delta_{2}", real=True)
d3 = sympy.Symbol("\\delta_{3}", real=True)
f1 = sympy.Symbol("f_1", real=True)
f2 = sympy.Symbol("f_2", real=True)
f3 = sympy.Symbol("f_3", real=True)
err_squared = ((x + d1) / x - f1) ** 2 + ((x + d1 + y) / x - f2) ** 2 + ((x + d1 + y + d3) / x - f3) ** 2
err_squared.expand()
err_squared_x = sympy.diff(err_squared, x)
err_squared_y = sympy.diff(err_squared, y)
sympy.nonlinsolve([err_squared_x, err_squared_y], [x, y])
</syntaxhighlight>
 
The unique solution with x > 0 is
<math>
(x, y) = \displaystyle { \left( \frac{2 \delta_{1} + \delta_{3} + \frac{2 \left(- 2 \delta_{1}^{2} f_{1} + \delta_{1}^{2} f_{2} + \delta_{1}^{2} f_{3} - \delta_{1} \delta_{3} f_{1} + \delta_{1} \delta_{3} f_{2} - \delta_{1} \delta_{3} f_{3} + \delta_{1} \delta_{3} + \delta_{3}^{2} f_{2} - \delta_{3}^{2}\right)}{2 \delta_{1} f_{1} - 2 \delta_{1} - \delta_{3} f_{2} + \delta_{3} f_{3}}}{f_{2} + f_{3} - 2}, \  \frac{- 2 \delta_{1}^{2} f_{1} + \delta_{1}^{2} f_{2} + \delta_{1}^{2} f_{3} - \delta_{1} \delta_{3} f_{1} + \delta_{1} \delta_{3} f_{2} - \delta_{1} \delta_{3} f_{3} + \delta_{1} \delta_{3} + \delta_{3}^{2} f_{2} - \delta_{3}^{2}}{2 \delta_{1} f_{1} - 2 \delta_{1} - \delta_{3} f_{2} + \delta_{3} f_{3}}\right).}
</math>
 
=== Partially DR (arbitrary) ===
We similarly include a free variable to be optimized for every additional +?, after coalescing strings of consecutive +?'s and omitting the middle notes, and after trimming leading and trailing +?'s. If two variables are related to each other but not to the integer deltas in the signatures, they have a common variable.
 
== External links ==
== External links ==
* [https://inthar-raven.github.io/delta/ Inthar's DR chord explorer (includes least-squares linear error calculation)]
* [https://inthar-raven.github.io/delta/ Inthar's DR chord explorer (includes least-squares linear error calculation)]
[[Category:Atypical ratios]]
[[Category:Atypical ratios]]

Revision as of 02:59, 11 December 2025

This is a technical or mathematical page. While the subject may be of some relevance to music, the page treats the subject in technical language.

Least-squares linear error (here linear means "in frequency space, not pitch space") is a proposed error measure for approximations to delta-rational chords. It has the advantage of not fixing a particular interval in the chord when constructing the chord of best fit. However, like any other numerical measure of concordance or error, you should take it with a grain of salt.

Fully DR

The idea motivating least-squares linear error on a chord as an approximation to a given delta signature is the following (for simplicity, let’s talk about the fully DR case first):

Say we want the error of a chord 1:r1:r2:...:rn (in increasing order), with n > 1, in the linear domain as an approximation to a fully delta-rational chord with signature +δ12 ... +δn, i.e. a chord

x:x+δ1::x+l=1nδl.

Minimizing the least-squares frequency-domain error by varying x gives you the closed-form solution

x=i=1nDin+i=1nfi,

which you plug back into

1=1n(1+Dixfi)2

to obtain the least-squares linear error.


Partially DR (one free variable)

Suppose we wish to approximate a target delta signature of the form +δ1+?+δ3 with the chord 1:f1:f2:f3 (where the +? is free to vary). By a derivation similar to the above, the least-squares problem is

minimizex,y(x+δ1xf1)2+(x+δ1+yxf2)2+(x+δ1+y+δ3xf3)2,

where y represents the free delta +?.

We can set the partial derivatives with respect to x and y of the inner expression equal to zero (since the derivative of sqrt() is never 0) and use SymPy to solve the system:

import sympy
x = sympy.Symbol("x", real=True)
y = sympy.Symbol("y", real=True)
d1 = sympy.Symbol("\\delta_{1}", real=True)
d2 = sympy.Symbol("\\delta_{2}", real=True)
d3 = sympy.Symbol("\\delta_{3}", real=True)
f1 = sympy.Symbol("f_1", real=True)
f2 = sympy.Symbol("f_2", real=True)
f3 = sympy.Symbol("f_3", real=True)
err_squared = ((x + d1) / x - f1) ** 2 + ((x + d1 + y) / x - f2) ** 2 + ((x + d1 + y + d3) / x - f3) ** 2
err_squared.expand()
err_squared_x = sympy.diff(err_squared, x)
err_squared_y = sympy.diff(err_squared, y)
sympy.nonlinsolve([err_squared_x, err_squared_y], [x, y])

The unique solution with x > 0 is (x,y)=(2δ1+δ3+2(2δ12f1+δ12f2+δ12f3δ1δ3f1+δ1δ3f2δ1δ3f3+δ1δ3+δ32f2δ32)2δ1f12δ1δ3f2+δ3f3f2+f32, 2δ12f1+δ12f2+δ12f3δ1δ3f1+δ1δ3f2δ1δ3f3+δ1δ3+δ32f2δ322δ1f12δ1δ3f2+δ3f3).

Partially DR (arbitrary)

We similarly include a free variable to be optimized for every additional +?, after coalescing strings of consecutive +?'s and omitting the middle notes, and after trimming leading and trailing +?'s. If two variables are related to each other but not to the integer deltas in the signatures, they have a common variable.