DR error measures: Difference between revisions

From Xenharmonic Reference
No edit summary
Line 6: Line 6:


=== Fully DR ===
=== Fully DR ===
The idea motivating rooted 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):
We wish to minimize the following frequency-domain error function by optimizing ''x'':
 
Say we want the error of a chord 1:''r''<sub>1</sub>:''r''<sub>2</sub>:...:''r''<sub>''n''</sub> (in increasing order), with ''n'' &gt; 1, in the linear domain as an approximation to a fully delta-rational chord with signature +δ<sub>1</sub> +δ<sub>2</sub> ... +δ<sub>''n''</sub>, i.e. a chord
 
<math>x : x + \delta_1 : \cdots : x + \sum_{l=1}^n \delta_l.</math>
 
Rewriting a bit, let <math>D_0 = 0, D_i = \sum_{k=1}^i \delta_k</math> be the delta signature +δ<sub>1</sub> +δ<sub>2</sub> ... +δ<sub>''n''</sub> written cumulatively. We wish to minimize the following frequency-domain error function by optimizing ''x'':


<math>
<math>

Revision as of 06:58, 12 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.

This article will describe several least-squares error measures for delta-rational chords. They have 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 them with a grain of salt.

Rooted linear error

Rooted linear error (here linear means "in frequency space, not pitch space") measures error by optimizing how well cumulative intervals from the root real-valued harmonic match the target chord's DR signature.

Fully DR

We wish to minimize the following frequency-domain error function by optimizing x:

i=1n(x+Dixri)2=i=1n(1+Dixri)2.

Setting the derivative to 0 gives us the closed-form solution

x=i=1nDin+i=1nri,

which can be plugged back into

1=1n(1+Dixri)2

to obtain the least-squares linear error.

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+δ1xr1)2+(x+δ1+yxr2)2+(x+δ1+y+δ3xr3)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)
r1 = sympy.Symbol("r_1", real=True)
r2 = sympy.Symbol("r_2", real=True)
r3 = sympy.Symbol("r_3", real=True)
err_squared = ((x + d1) / x - r1) ** 2 + ((x + d1 + y) / x - r2) ** 2 + ((x + d1 + y + d3) / x - r3) ** 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δ12r1+δ12r2+δ12r3δ1δ3r1+δ1δ3r2δ1δ3r3+δ1δ3+δ32r2δ32)2δ1r12δ1δ3r2+δ3r3r2+r32, 2δ12r1+δ12r2+δ12r3δ1δ3r1+δ1δ3r2δ1δ3r3+δ1δ3+δ32r2δ322δ1r12δ1δ3r2+δ3r3).

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.

Todo: The L-BFGS-B algorithm is suited for five-variable (base real-valued harmonic + four free deltas; a realistic upper bound on real-world use cases of partial DR) optimization problems with bounds, so let's talk about that

<hj>Here be dragons. No one really wants to do this, right</hj>

Rooted logarithmic error

This error measure also measures errors of rooted intervals, but measures the error in logarithmic interval distance and thus arguably has a more musically intuitive meaning.

Fully DR

The error function to be minimized, with units in nepers (logarithmic unit for frequency ratio of e), is

i=1n(logx+Dirix)2.

(To scale to cents, multiply by 1200/log 2.)

All-interval linear error

Measure all pairwise intervals, linearly

Fully DR

0i<jn(x+Djx+Dirjri)2.

All-interval logarithmic error

This error measure measures errors of all intervals, not just rooted ones.

Fully DR

The error function to be minimized, with units in nepers, is

0i<jn(logx+Djx+Dilogrjri)2.