back to list

TUNING digest 591 - 12 tone optimization

🔗Jeff Welty <jwelty@...>

12/22/1995 12:26:28 PM
Jeff said:
>
> The objective function I minimize the sum of squared errors of
> actual interval values minus desired interval values.
>
> errsum = 0 ;
> for n = 0 to 11 {
> v1 = note_cents[n] ;
> w1 = note_weight[n] ;
> for i = 0 to 6 {
> int n2 = n+i+1 ;
> if (n2 < 12) {
> v2 = note_cents[n2] ;
> w2 = note_weight[n2] ;
> } else {
> v2 = note_cents[n2-12]+1200. ;
> w2 = note_weight[n2-12] ;
> }
> err = interval_weight[i]*w1*w2*((v2-v1) - desired_interval[i]) ;
> errsum = errsum + err*err ;
> }
> }
>
>
Manuel Op de Coul said:
> I don't completely understand from the code what it is that is coming
> out of it. You to have to supply weights for 12 notes and then only 7
> intervals are compared. Are you comparing the prime on purpose, or is
> it always 0 cents? Is the resulting scale always symmetrical? The
> error-function seems to be quadratic in the note values, and so far as
> I can tell you need indeed an iterative procedure to find the minimum
> of it. If there wouldn't be product terms of pitch variables then the
> solution could be found algebraically by setting the derivative to
> each of them to zero.
>

First, the easy ones.
1.) The resulting scale is definitely not symmetrical. It is my understanding
that it is impossible to have all perfect intervals in a 12 tone scale
where the intervals are based on frequency ratios. -- the input data
actually asks for the desired interval values in terms of ratios i.e.
a fifth is 3/2 a fourth is 4/3 etc.

2.) the routine is indeed iterative.

Now the harder ones -- thanks for making me think about this Manuel!
You found a bug in the routine. The intent I had was to compare the
actual intervals between all notes only once, but using 7 half steps
forward from each note results in some duplication and an inadvertant
doubling of the weights for intervals 6&7 since each is calculated twice
and added to the error sum! That's what I get for "throwing" this
together. (and that's the value of having other minds examine the
process). The appropriate loop really ought to look *something* like:

for n = 0 to 11 {
for n2 = n+1 to 11 {
int i = n2-n ;
if(i <=6 ) {
v1 = note_cents[n] ;
w1 = note_weight[n] ;
v2 = note_cents[n2] ;
w2 = note_weight[n2] ;
} else {
v1 = note_cents[n2] ;
w1 = note_weight[n2] ;
v2 = note_cents[n2]+1200. ;
w2 = note_weight[n2] ;
i = 12-i ;
}
err = interval_weight[i]*w1*w2*((v2-v1) - desired_interval[i]) ;
errsum = errsum + err*err ;
}
}

New code will come sometime for those who've asked for it with this fix.
Hopefully today.

Jeff Welty


Received: from eartha.mills.edu [144.91.3.20] by vbv40.ezh.nl
with SMTP-OpenVMS via TCP/IP; Sat, 23 Dec 1995 00:00 +0100
Received: from by eartha.mills.edu via SMTP (940816.SGI.8.6.9/930416.SGI)
for id PAA04594; Fri, 22 Dec 1995 15:00:25 -0800
Date: Fri, 22 Dec 1995 15:00:25 -0800
Message-Id:
Errors-To: madole@ella.mills.edu
Reply-To: tuning@eartha.mills.edu
Originator: tuning@eartha.mills.edu
Sender: tuning@eartha.mills.edu