Error measures for DR chords: Difference between revisions

Inthar (talk | contribs)
Inthar (talk | contribs)
No edit summary
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'' (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 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">