back to list

Unison vectors with Pari/GP

🔗Graham Breed <gbreed@gmail.com>

10/27/2010 12:12:14 AM

What I did last night is get a Tenney-weighted LLL reduction working
with Pari/GP. Maybe we can call this TLLL reduction.

Here's the code:

/* LLL reduction of a mapping, with Tenney weighting */
maplll(mapping) = qflll(weight mapping(mapping))

/* LLL reduction of a unison vector matrix, with Tenney weighting */
uvlll(uvs) = qflll(weight intervals(uvs)~)~

/* Tenney weight a mapping */
weight mapping(cols)={
local(size);
size=matsize(cols);
matrix(size[1],size[2],i,j,cols[i,j]/log(prime(i))*log(2))
}

/* Tenney weight a matrix of intervals */
weight intervals(rows)={
local(size);
size=matsize(rows);
matrix(size[1],size[2],i,j,rows[i,j]*log(prime(j))/log(2))
}

My functions echo the original qflll except that uvlll works by row
instead of by column because that's how I happen to hold my unison
vectors. The example I have is, I'm afraid, the 17-limit 46 note one.

Here's the code for finding the unison vectors for the 46-equal mapping:

uv46 = matkerint([46, 73, 107, 129, 159, 170, 188;0,0,0,0,0,0,0])~

The TLL-reduced basis is:

lll46 = uvlll(uv46)*uv46

As ratios, they happen to be:

91/90, 153/154, 136/135, 196/195, 594/595, 121/120

One of them's bigger than the previous reduced set. That must be
because LLL isn't strictly about finding the shortest vectors.

To work out these intervals in terms of the 46&31&72 Portent basis:

portent = [46, 73, 107, 129, 159, 170, 188;31, 49, 72, 87, 107, 115,
127;72, 114, 167, 202, 249, 266, 294]~

lll46*portent*portent[1,]~

The result is

103, -72, 103, 72, -31, 72

I'm not sure what to do with that because it gives three distinct
chromatic unison vector in Portent. The periodicity block must be
tunable in Portent. You could calculate it as a redundant
46&103&72&31 I suppose.

Because this method uses LLL reduction, it may actually be an
efficient way of finding an optimal basis in mapping-space with
minimal scalar badness. That assumes my guess about simple badness
being dual to complexity is true. Minimizing scalar badness directly
may be more difficult because, although it's defined by a quadratic
form, it isn't the "Euclidean" type that LLL works with.

Note: if you want a basis in Portent with minimal scalar complexity, you can do

portent * maplll(portent)

Graham