back to list

TOP-RMS in Scheme

🔗Graham Breed <gbreed@gmail.com>

5/7/2010 11:12:40 PM

Here's the full code for rank 2 TOP-RMS optimization in Scheme. The
standard meantone example is

(generators '(31 49 72 87) '(19 30 44 53) (limit 7))

which should give the "Step Tunings" from

http://x31eq.com/cgi-bin/rt.cgi?ets=31+19&limit=7

; Intervals are measured in terms of 2:1 octaves.
(define prime-numbers '(2 3 5 7 11 13 17 19 23 29 31))
(define (log2 f) (/ (log f) (log 2)))
(define primes (map log2 prime-numbers))

(define (limit n)
(let more-primes ((basis primes) (nums prime-numbers))
(cond
((null? nums) (display "Number is not a registered prime"))
((= (car nums) n) (list (car basis)))
(else (cons (car basis)
(more-primes (cdr basis) (cdr nums)))))))

(define (mean X) (/ (apply + X) (length X)))
(define (square x) (* x x))
(define (weight val basis) (map / val basis))

(define (generators val1 val2 basis)
(let* ((m1 (weight val1 basis))
(m2 (weight val2 basis))
(mm1 (mean m1))
(mm2 (mean m2))
(mm1sq (mean (map square m1)))
(mm2sq (mean (map square m2)))
(mm12 (mean (map * m1 m2)))
(common (/ 1200 (- (* mm1sq mm2sq) (square mm12)))))
(cons (* common (- (* mm1 mm2sq) (* mm2 mm12)))
(* common (- (* mm2 mm1sq) (* mm1 mm12))))))

🔗Carl Lumma <carl@lumma.org>

5/8/2010 4:02:33 AM

Now here's something I can understand! Except, what's
"common"? My scheme doesn't have it, anyway. -C.

Graham wrote:

>Here's the full code for rank 2 TOP-RMS optimization in Scheme. The
>standard meantone example is
>
>(generators '(31 49 72 87) '(19 30 44 53) (limit 7))
>
>which should give the "Step Tunings" from
>
>http://x31eq.com/cgi-bin/rt.cgi?ets=31+19&limit=7
>
>; Intervals are measured in terms of 2:1 octaves.
>(define prime-numbers '(2 3 5 7 11 13 17 19 23 29 31))
>(define (log2 f) (/ (log f) (log 2)))
>(define primes (map log2 prime-numbers))
>
>(define (limit n)
> (let more-primes ((basis primes) (nums prime-numbers))
> (cond
> ((null? nums) (display "Number is not a registered prime"))
> ((= (car nums) n) (list (car basis)))
> (else (cons (car basis)
> (more-primes (cdr basis) (cdr nums)))))))
>
>(define (mean X) (/ (apply + X) (length X)))
>(define (square x) (* x x))
>(define (weight val basis) (map / val basis))
>
>(define (generators val1 val2 basis)
> (let* ((m1 (weight val1 basis))
> (m2 (weight val2 basis))
> (mm1 (mean m1))
> (mm2 (mean m2))
> (mm1sq (mean (map square m1)))
> (mm2sq (mean (map square m2)))
> (mm12 (mean (map * m1 m2)))
> (common (/ 1200 (- (* mm1sq mm2sq) (square mm12)))))
> (cons (* common (- (* mm1 mm2sq) (* mm2 mm12)))
> (* common (- (* mm2 mm1sq) (* mm1 mm12))))))
>
>
>------------------------------------
>
>Yahoo! Groups Links
>
>
>

🔗Graham Breed <gbreed@gmail.com>

5/8/2010 5:04:22 AM

On 8 May 2010 15:02, Carl Lumma <carl@lumma.org> wrote:
> Now here's something I can understand!  Except, what's
> "common"?  My scheme doesn't have it, anyway.  -C.

It's a chunk of calculations you need to do for both generators, and
so can be assigned to a variable (or whatever let* defines) to save
doing them twice.

Graham

🔗Carl Lumma <carl@lumma.org>

5/8/2010 2:49:46 PM

Graham wrote:

>> Now here's something I can understand! Except, what's
>> "common"? My scheme doesn't have it, anyway. -C.
>
>It's a chunk of calculations you need to do for both generators, and
>so can be assigned to a variable (or whatever let* defines) to save
>doing them twice.

Can you give the code for it?

-Carl

🔗Graham Breed <gbreed@gmail.com>

5/8/2010 10:06:21 PM

On 9 May 2010 01:49, Carl Lumma <carl@lumma.org> wrote:
> Graham wrote:
>
>>> Now here's something I can understand!  Except, what's
>>> "common"?  My scheme doesn't have it, anyway.  -C.
>>
>>It's a chunk of calculations you need to do for both generators, and
>>so can be assigned to a variable (or whatever let* defines) to save
>>doing them twice.
>
> Can you give the code for it?

What do you mean? We're talking about the code for it.

Graham

🔗Carl Lumma <carl@lumma.org>

5/8/2010 10:19:57 PM

At 10:06 PM 5/8/2010, you wrote:
>
>On 9 May 2010 01:49, Carl Lumma <carl@lumma.org> wrote:
>> Graham wrote:
>>
>>>> Now here's something I can understand! Except, what's
>>>> "common"? My scheme doesn't have it, anyway. -C.
>>>
>>>It's a chunk of calculations you need to do for both generators, and
>>>so can be assigned to a variable (or whatever let* defines) to save
>>>doing them twice.
>>
>> Can you give the code for it?
>
>What do you mean? We're talking about the code for it.

For "common". If it's a keyword, my scheme doesn't have it.
If it's a custom function, let's see it.

-Carl

🔗Graham Breed <gbreed@gmail.com>

5/8/2010 10:23:34 PM

On 9 May 2010 09:19, Carl Lumma <carl@lumma.org> wrote:

> For "common".  If it's a keyword, my scheme doesn't have it.
> If it's a custom function, let's see it.

It's not a keyword or a function. It's a symbol, or a variable that
doesn't vary. I see the definition right there in my message, give or
take trailing parentheses.:

(common (/ 1200 (- (* mm1sq mm2sq) (square mm12))))

If your Scheme barfs on the it, let's see the error message.

Graham

🔗Carl Lumma <carl@lumma.org>

5/9/2010 1:30:59 AM

Graham wrote:

>> For "common". If it's a keyword, my scheme doesn't have it.
>> If it's a custom function, let's see it.
>
>It's not a keyword or a function. It's a symbol, or a variable that
>doesn't vary. I see the definition right there in my message, give or
>take trailing parentheses.:
>(common (/ 1200 (- (* mm1sq mm2sq) (square mm12))))
>If your Scheme barfs on the it, let's see the error message.

Sorry I missed that. Maybe I'll need eye work next.

Because I have log2 and mean in my libraries, and because I don't
mind writing the formula for the basis in the input each time, I
can use

(define (square x) (* x x))
(define (weight val basis) (map / val basis))

(define generators
(lambda (val1 val2 basis)
(let* ((m1 (weight val1 basis))
(m2 (weight val2 basis))
(mm1 (mean m1))
(mm2 (mean m2))
(mm1sq (mean (map square m1)))
(mm2sq (mean (map square m2)))
(mm12 (mean (map * m1 m2)))
(common (/ 1200 (- (* mm1sq mm2sq) (square mm12)))))
(cons (* common (- (* mm1 mm2sq) (* mm2 mm12)))
(* common (- (* mm2 mm1sq) (* mm1 mm12)))))))

Whereupon

(generators '(31 49 72 87) '(19 30 44 53) (map log2 '(2 3 5 7)))

yields

(33.437588751882345 . 8.667205527055183)

I wanted the tuning of the generator and period but hey, it's
progress. How many notes of the rank 2 temperament give these
step sizes?

-Carl

🔗Graham Breed <gbreed@gmail.com>

5/9/2010 2:52:06 AM

On 9 May 2010 12:30, Carl Lumma <carl@lumma.org> wrote:

> (generators '(31 49 72 87) '(19 30 44 53) (map log2 '(2 3 5 7)))
>
> yields
>
> (33.437588751882345 . 8.667205527055183)
>
> I wanted the tuning of the generator and period but hey, it's
> progress.  How many notes of the rank 2 temperament give these
> step sizes?

Oh, now *you* want the generator and period, do you? This function
happens not to need them. You can feed in the generator/period
mapping and you should get the generator/period tunings out.

What you have are the sizes of the 31-step and 19-step. So you should
get an octave as

(+ (* 31 33.437588751882345) (* 19 8.667205527055183))

and check it against the TOP-RMS stretch.

Graham