DR error measures

From Xenharmonic Reference
Revision as of 06:52, 12 December 2025 by Inthar (talk | contribs) (Fully DR)
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

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):

Say we want the error of a chord 1:f1:f2:...:fn (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.

Rewriting a bit, let D0=0,Di=k=1iδk be the delta signature +δ12 ... +δn written cumulatively. We wish to minimize the following frequency-domain error function by optimizing x:

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

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

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

which can be plugged back into

1=1n(1+Dixfi)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+δ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).

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

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+Difix)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+Difjfi)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+Dilogfjfi)2.