Error measures for DR chords: Difference between revisions

Inthar (talk | contribs)
Inthar (talk | contribs)
Fully DR, rooted linear: Correct analytical solution for x
 
(6 intermediate revisions by the same user not shown)
Line 11: Line 11:
with root real-valued harmonic ''x''. Let <math>D_0 = 0, D_i = \sum_{k=1}^i \delta_k</math> be the delta signature {{nowrap|+δ<sub>1</sub> +δ<sub>2</sub> ... +δ<sub>''n''</sub>}} written cumulatively.
with root real-valued harmonic ''x''. Let <math>D_0 = 0, D_i = \sum_{k=1}^i \delta_k</math> be the delta signature {{nowrap|+δ<sub>1</sub> +δ<sub>2</sub> ... +δ<sub>''n''</sub>}} written cumulatively.


We want to measure the error ''without having to fix any dyad'' (as one might naively fix a dyad and measure errors in the other deltas in relation to the fixed dyad). To do this we solve a least-squares error problem: use a root-sum-square error function and optimize ''x'' (and any free deltas) to minimize that function.
We want to measure the error ''without having to fix any dyad in the target chord'' (as one might naively fix a dyad and measure errors in the other deltas in relation to the fixed dyad). To do this we solve a least-squares optimization problem: use a root-sum-square objective function and optimize ''x'' (and any free deltas) to minimize that function.


== Domain and error model ==
== Domain and error model ==
Line 21: Line 21:
** ''All-steps'': Only intervals between adjacent notes are compared.
** ''All-steps'': Only intervals between adjacent notes are compared.


We arrive at the following general formula: Let <math>[n] = \{0, 1, 2, ..., n\},</math> let <math>I \subseteq {[n] \choose 2}</math> be the error model, and let <math>f_D</math> represent the domain function (identity for linear, or <math>\log</math>). Then the error function to be minimized by optimizing <math>x</math> and any free deltas is:
We arrive at the following general formula: Let <math>[n] = \{0, 1, 2, ..., n\},</math> let <math>I \subseteq {[n] \choose 2}</math> be the error model, and let <math>f_D</math> represent the domain function (identity for linear, or <math>\log</math>). Then the objective function (measuring the error) to be minimized by optimizing <math>x</math> and any free deltas is:


<math>
<math>
Line 28: Line 28:


{| class="wikitable"
{| class="wikitable"
|+ style="font-size: 105%;" | Error function for various modes and error models
|+ style="font-size: 105%;" | Objective function for various modes and error models
|-
|-
! Domain
! Domain
! Error model
! Error model
! Error function
! Objective function
|-
|-
! rowspan="3" | Linear
! rowspan="3" | Linear
Line 64: Line 64:
Setting the derivative to 0 gives us the closed-form solution
Setting the derivative to 0 gives us the closed-form solution


<math>x = \frac{\sum_{i=1}^n D_i }{-n + \sum_{i=1}^n r_i},</math>
<math>x = \frac{\sum_{i=1}^n D_i^2 }{\sum_{i=1}^n D_i(r_i-1)},</math>


which can be plugged back into
which can be plugged back into


<math>\sqrt{\sum_{1=1}^n \Bigg( 1 + \frac{D_i}{x} - r_i \Bigg)^2 }</math>
<math>\sqrt{\sum_{i=1}^n \Bigg( 1 + \frac{D_i}{x} - r_i \Bigg)^2 }</math>


to obtain the least-squares linear error.
to obtain the least-squares linear error.
Line 157: Line 157:


BFGS-B is a quasi-Newton optimization method (based on BFGS) particularly suited for this problem:
BFGS-B is a quasi-Newton optimization method (based on BFGS) particularly suited for this problem:
* The error function is smooth, allowing use of gradients
* The objective function is smooth, allowing use of gradients
* Fast convergence, requiring at worst 20 iterations for accuracy
* Fast convergence, requiring at worst 20 iterations for accuracy
* Naturally deals with the {{nowrap|''x'' &gt; 0}} constraint using a log barrier and minimizing the transformed function using the unconstrained BFGS method
* Naturally deals with the {{nowrap|''x'' &gt; 0}} constraint using a log barrier and minimizing the transformed function using the unconstrained BFGS method
* Acceptable memory usage given a realistic number of parameters for practical DR chords (up to 3 interior free delta segments, thus 4 parameters).
* Acceptable memory usage given a realistic number of parameters for practical DR chords (up to 3 interior free delta segments, thus 4 parameters).


It is a ''quasi-Newton method'' because it uses an approximation of the Hessian (matrix of mixed second partial derivatives) of the error function at each step.
It is a ''quasi-Newton method'' because it uses an approximation of the Hessian (matrix of mixed second partial derivatives) of the objective function at each step.


In the Python implementation below, <code>x</code> represents the vector <math>(x_1, x_2, ..., x_n),</math> <code>x0</code> is the initial guess for the solution, and <code>f</code> is the error function.
In the Python implementation below, <code>x</code> represents the vector <math>(x_1, x_2, ..., x_n),</math> <code>x0</code> is the initial guess for the solution, and <code>f</code> is the objective function.


<syntaxhighlight lang="python">
<syntaxhighlight lang="python">
Line 415: Line 415:


== External links ==
== External links ==
* [http://inthar-raven.github.io/delta/ Inthar's DR chord explorer (includes least-squares error calculation in both domains and multiple error models)]
* [http://turbofishcrow.github.io/delta/ Inthar's DR chord explorer (includes least-squares error calculation in both domains and multiple error models)]


[[Category:Math]]
[[Category:Math]]