back to list

Periodicity blocks/hobbits review

🔗Graham Breed <gbreed@gmail.com>

6/25/2011 4:01:46 AM

Here are some notes I took when I was investigating Carl
and Gene's methods for finding unison vectors that worked
well for finding periodicity blocks or hobbits. I didn't
write up a friendly reply, so maybe somebody else can work
out what I was doing here.

From what I remember, Gene was finding good unison vectors
for the equal temperament (val) according to temperamental
complexity defined for the rank 3 temperament. I couldn't
reproduce Gene's working. Carl was finding simple unison
vectors in full JI space, and whether or not that's how he
did it, he agreed with TLLL-reduction. Carl's method looks
simple and good enough to implement but I didn't get
further than this.

The point about JI space is that, although it's more
complicated than tempered space, you can apply a weighted
LLL to it.

--- In tuning-math@yahoogroups.com, Graham Breed <gbreed@...> wrote:

> > Some time back I introduced dwarf scales, which start from a p-limit val v and define a p-limit JI scale by by choosing for each nonzero
> > value i mod v[1] the smallest positive odd integer n such that v(n) = i mod v[1].

> I take it v[1] is the number of steps to an octave (2:1). What's
> v(n)?

v is an equal temperament val, so v(2) is the number of steps in an octave, which is the same as the first coefficient of the val, v[1].

Carl said down-thread that dwarf scales take the simplest ratio
> that maps to the given number of scale steps. Is that right?

It takes the smallest odd integer which maps to the given number of steps modulo octaves.

> If the commas define the temperament, they must be unison vectors.

If you say so. To me, they are commas.

> The next paragraph's so dense I'm going to have to break it up.
> Nearly every sentence has something I don't understand.
>
> > The standard Euclidean norm on weighted monzos provides a canonical Euclidean metric on interval space.
>
> With Tenney weighting, that'll give the scalar complexity of the
> temperament class defined by the monzo as a unison vector, won't it?

"Scalar complexity" sounds like gibberish to my mind, so I can't easily retain the definition. And no, I am not kidding nor trying to give you a hard time, this is really true of me. Assuming "temperament class" means the same as "temperament", you may be asking if the norm of the monzo for a temperament defined by a single comma is the same as its complexity.
It should be proportional, but I don't know why you think this is important here.

> That looks straightforward. Do we assume Tenney weighting?

Yes, if by that you mean multiplying the prime p coordinate by log2(p).

> > Projecting othogonally from a set of intervals consisting of the commas + 2 in this metric defines a canonical projection map from the p-limit to a lattice of interval classes.
>
> This is your square matrix, is it? Taken from an intermediate
> calculation in the least squares optimization. Is it weighted?

Its an orthogonal projection, which like any projection can be given by an idempotent (P = P^2) square matrix P. I don't know what you mean by the weighting question, but we are working in weighted coordinates, and would need to transform the matrix to get the corresponding matrix in unweighted coordinates, which can be useful. In that case, the matrix is no longer symmetric, since the norm is no longer given by the dot product, but it projects unweighted monzos directly without first needing to weight them.

> Where does +2 come from?

I mean the octave, 2, is added to the list of commas.

> Why interval classes? I thought they were octave equivalent. If so,
> what did you do with the octaves? And what's the norm?

They are octave equivalent only since 2 is added to the commas. The norm (really, seminorm if we are not looking at equivalence classes) is the ordinary dot product norm on the projected monzos.

> > Given a val v tempering out the commas c, we choose the smallest lattice element q (ie, the one nearest the origin) for each i, 0 <= i < v[1] such that v(q) mod v[1] = i.
>
> Element of what lattice? The octave equivalent projection above, with
> the undefined norm? And this v(q) comes up again.

I defined the norm. The lattice is the lattice of projected monzos in the subspace, and the norm is the dot product norm.

> > This assumes q is expressed in terms of rational numbers, but since v tempers out the commas and we plan to temper the result that result is independent of the particular choice of q.
>
> How can it be expressed in terms of rationals if it's a lattice
> element? Lattice elements are expressed in terms of integers.
> Otherwise, what makes it a lattice element?

It's a lattice element since given a q, there is one and only one lattice point associated to it.

--- In tuning-math@yahoogroups.com, "genewardsmith" <genewardsmith@...> wrote:

> All three of us could take a specific small but interesting example, such as constructing an 11-note scale for starling using the starling val <11 18 26 31|, and explaining things as best as possible.

Consider the Hermite normal form mapping/ikon for starling. This gives (tempered) 2, 3, and 5 as generators for the intervals of the temperament. In this subgroup, the <11 18 26 31| val becomes <11 18 26|. A basis for the commas is 16/15 and 3125/2916.

/*
starling = [27, 43, 63, 76; 19, 30, 44, 53; 12, 19, 28, 34]~;
? rowhnf(starling~)

[1 0 0 -1]

[0 1 0 -2]

[0 0 1 3]

? g11 5 = [11,18,26]~;
? basis = [4,-1,-1;-2,-6,5];
? get ratios(basis)
[16/15, 3125/2916]
? basis * g11 5
[0, 0]~
*/

Now form a projection matrix by the following proceedure:

(1) Weight the monzos for 2, 16/15 and 3125/2916 by <1 log2(3) log2(5)|; call these u1, u2, and u3.

/*
? u1 = [1,0,0]
[1, 0, 0]
? u2 = weight intervals(basis)[1,]
[4.000000000000000000000000000, -1.584962500721156181453738944, -2.321928094887362347870319429]
? u3 = weight intervals(basis)[2,]
[-2.000000000000000000000000000, -9.509775004326937088722433663, 11.60964047443681173935159715]
*/

(2) Take the matrix M whose rows are these weighted monzos, and find
Q = M`M, where M` is the pseudoinverse. The projection matrix is now P = I - Q, where I is the identity matrix.
/*

? monzos = [1, 0, 0; 4, -1, -1; -2, -6, 5];
? M = weight intervals(monzos)

[1.000000000000000000000000000 0 0]

[4.000000000000000000000000000 -1.584962500721156181453738944 -2.321928094887362347870319429]

[-2.000000000000000000000000000 -9.509775004326937088722433663 11.60964047443681173935159715]

? pseudo inverse(X) = X~ * matadjoint(X*X~) / matdet(X*X~)
? Mp = pseudo inverse(M)

[0.9999999999999999999999999999 -4.653197630 E-28 -1.183016346 E-28]

[1.032430505844203078890135278 -0.2867862516233897441361486880 -0.05735725032467794882722973816]

[1.017962773628019937947524617 -0.2349144862218507549109672192 0.03915241437030845915182787051]

? M*Mp

[0.9999999999999999999999999999 -4.653197630 E-28 -1.183016346 E-28]

[-5.048709794 E-28 0.9999999999999999999999999974 -1.121760207 E-27]

[4.038967835 E-28 -1.161203252 E-27 1.000000000000000000000000012]

? Q = Mp*M

[0.9999999999999999999999999982 1.862536304 E-27 -2.930004151 E-28]

[2.360271828 E-27 1.000000000000000000000000004 -6.52545741 E-27]

[-7.888609052 E-28 -6.033208204 E-27 1.000000000000000000000000007]

? P = matid(3) - Q

[1.754426653 E-27 -1.862536304 E-27 2.930004151 E-28]

[-2.360271828 E-27 -4.139942031 E-27 6.52545741 E-27]

[7.888609052 E-28 6.033208204 E-27 -6.91673241 E-27]

*/

(3) Project u2 and u3 (u1 projects to zero) by v2 = u2.P, v3 = u3.P.

/* continue with 126/125 (see below)

? u1 = [1,0,0,0]
[1, 0, 0, 0]
? u2 = weight intervals(monzos)[2,]
[4.000000000000000000000000000, -1.584962500721156181453738944, -2.321928094887362347870319429, 0]
? u3 = weight intervals(monzos)[3,]
[1.000000000000000000000000000, 3.169925001442312362907477888, -6.965784284662087043610958289, 2.807354922057604107441969317]

? u1*P
[1.539856487 E-27, -9.83683891 E-28, 9.35760271 E-30, -3.507315730 E-28]
? u2*P
[6.59436940 E-27, -7.75608042 E-27, 6.362952062 E-27, -4.285092438 E-27]
? u3*P
[-1.070580382 E-26, -1.688793426 E-26, 4.412572360 E-26, -1.661025522 E-26]

*/

(4) v2 and v3 span a subspace of R^4, the 4-dimensional real Euclidean space with dot product norm, and define a lattice on this subspace. Find the Minkowski basis for this subspace, which consists of the projections of 16/15 and 15625/15552.

/*

Mapping that includes 11:

starling11 = [11, 18, 26, 31; 27, 43, 63, 76; 12, 19, 28, 34]~;

Definition of the subspace:

? subtransform = [0,1,0; 0,0,1]~

[0 0]

[1 0]

[0 1]

Find shortest vectors in the mapping lattice:

? maplll(starling11*subtransform)

[-4 1]

[9 -2]

M = weight mapping(starling11);
? qfminim(subtransform~*M~*M*subtransform, 20, 10, 2)[3]

[-4 -8 -12 -16]

[9 18 27 36]

This isn't right. Equal temperaments:

? (starling11*subtransform*qfminim(subtransform~*M~*M*subtransform, 30, 20, 2)[3])[1,]
[0, 0, 0, 0, 0]

Orthogonal complement:

? orthog(X, y) = X - X * y~*y * X / (y*X*y~)
? (starling11*subtransform*qfminim(subtransform~*orthog(M~*M, [1,0,0])*subtransform, 0.06, 10, 2)[3])[1,]
[-3, -18]

Makes more sense but still not right.

Try Cangwu badness:

? (starling11*subtransform*qfminim(subtransform~*starling11~*Cangwu metric(7, 1/12e2)*starling11*subtransform, 0.005, 10, 2)[3])[1,]
[12, 27]
? (starling11*subtransform*qfminim(subtransform~*starling11~*Cangwu metric(7, 1/12e2)*starling11*subtransform, 0.006, 10, 2)[3])[1,]
[12, 27, 15]
? (starling11*subtransform*qfminim(subtransform~*starling11~*Cangwu metric(7)*starling11*subtransform, 0.006, 10, 2)[3])[1,]
[12, 27, 39, 15]
? (starling11*subtransform*qfminim(subtransform~*starling11~*Cangwu metric(7,0.0085)*starling11*subtransform, 0.1, 5, 2)[3])[1,]
[3, 6, 12, 15, 9]

Looks like Gene's 3&15. But 12 is still linearly independent and better.

Orthogonal Cangwu badness works:

? (starling11*subtransform*qfminim(subtransform~*orthog(starling11~*Cangwu metric(7, 0.0085)*starling11, [1,0,0])*subtransform, 0.008, 10, 2)[3])[1,]
[-3, -15]

Find shortest vectors in the interval sublattice:

Ki = icmet(starling11);
? qfminim(subtransform~ *Ki* subtransform, 10, 10, 2)[3]

[2 -3]

[1 -2]

These are Carl's unison vectors (below).

? qfminim(subtransform~ *Ki* subtransform, 13, 10, 2)[3]

[2 -3 -1]

[1 -2 -1]

[1,1] is what Gene uses. So the reduced basis is [1,1;2,1] giving unison vectors of [0,1,1;0,2,1].

Confirm they match Gene's:

? genevec = [4,-1,-1,0;-6,-5,6,0];

? get ratios(genevec)
[16/15, 15625/15552]
? genevec*starling11

[0 2 1]

[0 1 1]

[3,2] -> [0,3,2] is Carl's:

Simplest UVs of 11 note val:
? uv11 = matkerint((starling11*[1;0;0])~)~;
? get ratios(uvlll(uv11) * uv11)
[15/16, 49/45, 189/200]
? uvlll(uv11) * uv11 * starling11

[0 -2 -1]

[0 3 2]

[0 -2 -1]

? carlvec = [4,-1,-1,0;-2,-6,5,0;0,-2,-1,2];
? get ratios(carlvec)
[16/15, 3125/2916, 49/45]
? carlvec*starling11

[0 2 1]

[0 3 2]

[0 3 2]

Carl got 49/45 from the TM-reduced kernel of the 11-equal mapping.
Gene replaced it with 3125/2916.

Gene is looking for unison vectors orthogonal to 2:1, not the 11-equal mapping.

Carl's block definers:

? matdet([11,27,12;0,2,1;0,3,2])
11
? matadjoint([2,1;3,2])

[2 -1]

[-3 2]

? carlmap = starling11*[1,0,0;0,2,-1;0,-3,2]

[11 18 -3]

[18 29 -5]

[26 42 -7]

[31 50 -8]

? carlvec*carlmap

[0 1 0]

[0 0 1]

[0 0 1]

? matadjoint([11,27,12;0,2,1;0,3,2])

[1 -18 3]

[0 22 -11]

[0 -33 22]

Gene's:

? matdet([11,27,12;0,2,1;0,1,1])
11
? matadjoint([2,1;1,1])

[1 -1]

[-1 2]

? genemap = starling11 * [1,0,0;0,1,-1;0,-1,2]

[11 15 -3]

[18 24 -5]

[26 35 -7]

[31 42 -8]

? genevec*genemap

[0 1 0]

[0 0 1]

? matadjoint([11,27,12;0,2,1;0,1,1])

[1 -15 3]

[0 11 -11]

[0 -11 22]

*/

(5) If you take all 11 Fokker blocks for these commas, you find the transversal for the hobbit scale is one of them. But you don't need to worry about that; instead take just one such Fokker block, and for each scale step z, project z and find which of the nine choices z+-v2+-v3 is closest to the origin. Nine should be enough, but 25 would not unduly strain computing resources. The corresponding 5-limit interval is in the transversal for the hobbit.

Step five involves the problem of finding a lattice point closest to a given point, which in theory is NP-hard. In spite of your no doubt fervently held belief that P does not equal NP, we don't actually have a hard problem, since in rank three we are looking at a planar lattice, and we can't stack up very many commas without running over the boundries for a scale step.

By the way, the counterexample I thought I had to the claim that all hobbits come from a Minkowski basis in terms of the projection metric was a mistake, so I suppose I'd better see if I can think of a proof.
--- In tuning-math@yahoogroups.com, "genewardsmith" <genewardsmith@...> wrote:

> (5) If you take all 11 Fokker blocks for these commas, you find the transversal for the hobbit scale is one of them. But you don't need to worry about that; instead take just one such Fokker block, and for each scale step z, project z and find which of the nine choices z+-v2+-v3 is closest to the origin. Nine should be enough, but 25 would not unduly strain computing resources. The corresponding 5-limit interval is in the transversal for the hobbit.

I was assuming we'd switched basis to 16/15 15625/15552 for v2 and v3; if we don't, we'd better go with the 25.

/*
? factor(15625/15552)

[2 -6]

[3 -5]

[5 6]

? monzos = [1,0,0;4,-1,-1;-6,-5,6]

[1 0 0]

[4 -1 -1]

[-6 -5 6]

? get ratios(monzos)
[2, 16/15, 15625/15552]
? M = weight intervals(monzos)

[1.000000000000000000000000000 0 0]

[4.000000000000000000000000000 -1.584962500721156181453738944 -2.321928094887362347870319429]

[-6.000000000000000000000000000 -7.924812503605780907268694720 13.93156856932417408722191658]

? Mp = pseudo inverse(M)

[0.9999999999999999999999999997 -8.35998218 E-28 -2.523768207 E-27]

[1.032430505844203078890135278 -0.3441435019480676929633784244 -0.05735725032467794882722974046]

[1.017962773628019937947524617 -0.1957620718515422957591393503 0.03915241437030845915182787519]

? M*Mp

[0.9999999999999999999999999997 -8.35998218 E-28 -2.523768207 E-27]

[-1.009741958 E-27 0.9999999999999999999999999960 -1.798602864 E-26]

[-2.221432309 E-27 -1.923558431 E-26 1.000000000000000000000000111]

? Q = Mp*M;
? P = matid(3) - Q

[-1.148581478 E-26 -2.132541567 E-26 3.321892208 E-26]

[-2.338183723 E-26 -1.958899400 E-26 4.268684131 E-26]

[3.532203590 E-26 4.074939893 E-26 -7.58063775 E-26]

*/

--- In tuning-math@yahoogroups.com, "genewardsmith" <genewardsmith@...> wrote:

> Now form a projection matrix by the following proceedure:
>
> (1) Weight the monzos for 2, 16/15 and 3125/2916 by <1 log2(3) log2(5)|; call these u1, u2, and u3.

Sorry, I mean weight the monzos for 2 and 126/125! The matrix M has rows which are the weighted monzos for 2 and 126/125.

/*

? factor(126/125)

[2 1]

[3 2]

[5 -3]

[7 1]

? monzos = [1,0,0,0;4,-1,-1,0;1,2,-3,1];
? get ratios(monzos)
[2, 16/15, 126/125]
? M = weight intervals(monzos)

[1.000000000000000000000000000 0 0 0]

[4.000000000000000000000000000 -1.584962500721156181453738944 -2.321928094887362347870319429 0]

[1.000000000000000000000000000 3.169925001442312362907477888 -6.965784284662087043610958289 2.807354922057604107441969317]

? Mp = pseudo inverse(M)

[0.9999999999999999999999999998 -3.707692210 E-28 1.249331070 E-28]

[1.297010414729281449203816095 -0.3508973750862449556218754685 0.1065790856156983732836857806]

[0.8373588888865278630897888805 -0.1911518362106499953681258644 -0.07275154404392788161728542350]

[0.2569805628700864811485074050 -0.07808207388092430656903012342 0.05534773265361074512761308937]

? M*Mp

[0.9999999999999999999999999998 -3.707692210 E-28 1.249331070 E-28]

[-7.573064690 E-28 0.9999999999999999999999999982 1.527234712 E-27]

[-7.57306469 E-29 1.214845794 E-27 1.000000000000000000000000006]

? Q = Mp*M

[0.9999999999999999999999999985 9.83683891 E-28 -9.35760271 E-30 3.507315730 E-28]

[1.457814953 E-27 0.8940068892372473303163575160 0.07235155397949413003235751600 0.2992053205916296218042221140]

[-8.07793567 E-28 0.07235155397949413003235751659 0.9506123810729101665391023779 -0.2042394052590115104309951386]

[7.115525366 E-28 0.2992053205916296218042221139 -0.2042394052590115104309951388 0.1553807296898425031445401115]

? P = matid(3) - Q
*** impossible addition t_MAT + t_MAT.
? P = matid(4) - Q

[1.539856487 E-27 -9.83683891 E-28 9.35760271 E-30 -3.507315730 E-28]

[-1.457814953 E-27 0.1059931107627526696836424840 -0.07235155397949413003235751600 -0.2992053205916296218042221140]

[8.07793567 E-28 -0.07235155397949413003235751659 0.04938761892708983346089762206 0.2042394052590115104309951386]

[-7.115525366 E-28 -0.2992053205916296218042221139 0.2042394052590115104309951388 0.8446192703101574968554598885]

*/

Both <11 17 25 30| and <11 18 26 31| support starling, but the second one seems preferable in terms of tuning.

*
* response
*

>>> starling = regular.Temperament(regular.limit7, 27, 19, 12)
>>> regutils.nameThatMapping(starling.melody)
('Starling', 0)
>>> regutils.nameThatMapping(starling.melody+[[11,18,26,31]])
('Starling', 0)
>>> regutils.nameThatMapping(starling.melody+[[11,17,25,30]])
('Starling', 0)
>>> h11 = [11,17,25,30]
>>> g11 = [11,18,26,31]
>>> regutils.nameThatMapping(starling.melody+[h11])
('Starling', 0)
>>> regutils.nameThatMapping(starling.melody+[g11])
('Starling', 0)
>>> regutils.lattice_reduction(starling.melody + [g11])
[[1, 0, 0, -1], [0, 1, 0, -2], [0, 0, 1, 3], [0, 0, 0, 0]]
>>> regutils.lattice_reduction(starling.melody + [h11])
[[1, 0, 0, -1], [0, 1, 0, -2], [0, 0, 1, 3], [0, 0, 0, 0]]
>>> regutils.lattice_reduction(starling.melody[1:] + [h11])
[[1, 0, 0, -1], [0, 1, 0, -2], [0, 0, 1, 3]]
>>> regutils.lattice_reduction(starling.melody[1:] + [g11])
[[1, 0, 0, -1], [0, 1, 0, -2], [0, 0, 2, 6]]
>>> regutils.lattice_reduction(starling.melody[:-1] + [g11])
[[1, 0, 0, -1], [0, 1, 1, 1], [0, 0, 2, 6]]
>>> regutils.lattice_reduction(starling.melody[:1] + starling.melody[-1:] + [g11])
[[1, 0, 0, -1], [0, 1, 0, -2], [0, 0, 1, 3]]
>>> regutils.lattice_reduction(starling.melody)
[[1, 0, 0, -1], [0, 1, 0, -2], [0, 0, 1, 3]]
>>> starlingene = [g11] + starling.melody[:1] + starling.melody[-1:]
>>> sgene = regular.RegularTemperament(regular.limit7, starlingene)
>>> sgene
Starling
>>> print sgene
Starling

mapping by steps:
[<11, 18, 26, 31],
<27, 43, 63, 76],
<12, 19, 28, 34]>

step tunings:
<-29.704, 74.314, -39.995] cents

reduced mapping:
[<1, 0, 0, -1],
<0, 1, 0, -2],
<0, 0, 1, 3]>

tuning map:
[1199.795, 1900.927, 2789.622, 3367.214> cents

scalar complexity: 0.099
RMS weighted error: 0.840 cents/octave
max weighted error: 1.425 cents/octave

>>> ' '.join(['%.3f'%x for x in sgene.tunedBlock()])
'113.248 192.177 345.420 424.349 577.593 656.522 809.765 888.694 1041.937 1120.866 1199.795'
>>> set([int(interval*1000+0.5) for interval in regular.intervals(sgene.tunedBlock())])
set([113248, 78929, 153243])
>>> regular.fokkerBlock(11,27,12)
[(1, 3, 2), (2, 5, 3), (3, 8, 4), (4, 10, 5), (5, 13, 6), (6, 15, 7), (7, 18, 8), (8, 20, 9), (9, 23, 10), (10, 25, 11), (11, 27, 12)]

--- In tuning-math@yahoogroups.com, Graham Breed <gbreed@...> wrote:
>
> On 26 October 2010 23:07, genewardsmith <genewardsmith@...> wrote:
>
> > Hobbits are constructed using notes of minimal complexity relative to the temperament and under the assumption we are constructing scales with octave repetition. How do you define "minimal complexity"?
>
> There's no obvious way of measuring the complexity of intervals in a
> higher-rank temperament.

Whether or not it's obvious, Euclidean distance on the subspace the TOP-RMS projection projects orthogonally onto is precisely a way of measuring complexity for higher-rank temperaments. In fact, it even works for rank one, where it gives something proportional to the count of scale steps. What's less obvious is whether it's legitimate to get rid of octaves by adding 2 to the commas, but it seems to work, so I think my characterization is accurate.

*
* response
*

inverse(x) = matadjoint(x)/matdet(x)

M = weight mapping(mapping) /* vals as columns */
scalar complexity = sqrt(matdet(M~*M)/matsize(M)[1])
P = M * inverse(M~*M) * M~
{
M = weight intervals(uvs)
P = M~ * inverse(M*M~) * M
}
complexity = interval*P*interval~
Tenney weighting(mapping) = {
size = matsize(mapping)[1];
matrix(size, size, i, j, (i==j) * log(2) / log(prime(i)))
}
W = Tenney weighting(mapping)
P = W*mapping*inverse(mapping~*W*W*mapping)*mapping~*W
JI: P = I
for intervals in temperament:
K = inverse(mapping~*W*W*mapping)
comp(interval) = interval*K*interval~
tempcomp(interval) = interval*mapping*K*mapping~*interval~

example session:

? mean5 = [31,12;49,19;72,28];
? K = inverse(mean5~*W*W*mean5);
? comp(interval) = interval*K*interval~
? comp([31,12])
0.74019667948570838578038457092870693813812152114868
? tempcomp(interval) = interval*mean5*K*mean5~*interval~
? tempcomp([1,0,0])
0.74019667948570838578038457092870693813812152114868
? tempcomp([-1,1,0])
0.30746088901595324088268807370952846463394272923835
? tempcomp([2,-1,0])
1.2227439000359748292943830509315280776811108650325
? tempcomp([-2,0,1])
9.2808515944725910182950307134136245859679426695721
? tempcomp([1,-1,1])
2.7671480011435791679441926633857561817054845631452
? sqrt(tempcomp([-2,0,1])/4)
1.5232245069647966225810330927703830323631327757665
? tempcomp([-3,2,0])
2.3202128986181477545737576783534061464919856673930
? qfminim(K, 3.0, 20, 2)[3]

[18 36 54 31 49 13 67 -5 85 80 62]

[7 14 21 12 19 5 26 -2 33 31 24]

? mystery = [29, 46, 67, 81, 100, 107; 58, 92, 135, 163, 201, 215]~;
? qfminim(inverse(weight mapping(mystery)~ * weight mapping(mystery)), 0.01, 20, 2)[3]

[1 2 3 4]

[2 4 6 8]

alternative:

redmap = mapping * maplll(mapping) /* maybe Hermite or something */
G = redmap~ * W*W * redmap
comp(interval) = interval*G*interval~ /* vector in temperament */
Gt = redmap~ * W /* transforms to a lattice with Euclidean norm */
comp(interval) = interval*Gt*Gt~*interval~
K = redmap * redmap~ * W*W * redmap * redmap~
Kt = redmap * redmap~ * W
tempcomp(interval) = interval*Kt*Kt~*interval~ /* vector in ratio space */
X = maplll(mapping) /* unimodular transformation */
Gt = X~ * mapping~ * W
Kt = mapping * X*X~ * mapping~ * W

example session:

? mean5 = [31,12;49,19;72,28];
? W = Tenney weighting(mean5);
? X = maplll(mean5) /* each row is a generator/period ratio */

[7 -12]

[-18 31]

? inverse(X) /* rows define generators */

[31 12]

[18 7]

? bezout(31,12)
[-5, 13, 1]
? 12-5
7
? 31-13
18
? redmap = mean5*X

[1 0]

[1 1]

[0 4]

? [1,0,0]*redmap
[1, 0]
? [-1,1,0]*redmap
[0, 1]
? [-2,0,1]*redmap
[-2, 4]
? W = Tenney weighting(mean5)

[1.0000000000000000000000000000000000000000000000000 0 0]

[0 0.63092975357145743709952711434276085429958564013188 0]

[0 0 0.43067655807339305067010656876396563206979193207976]

? Kt = redmap * redmap~ * W

[1.0000000000000000000000000000000000000000000000000 0.63092975357145743709952711434276085429958564013188 0]

[1.0000000000000000000000000000000000000000000000000 1.2618595071429148741990542286855217085991712802638 1.7227062322935722026804262750558625282791677283190]

[0 2.5237190142858297483981084573710434171983425605275 6.8908249291742888107217051002234501131166709132762]

? tempcomp(interval) = interval*Kt*Kt~*interval~
? tempcomp([1,0,0])
1.3980723539417400086049989597545217146411588729548
? tempcomp([-1,1,0])
3.3657891167248551588902584948517200500413502223106
? tempcomp([0,1,0])
5.5600061785500751847052553741152851939648268411752
? tempcomp([2,-1,0])
3.9677167627831151502852595350971983354001913493558
? tempcomp([-2,0,1])
53.075757620296802438984148400573260224967697081512
? tempcomp([1,1,-1])
31.107523218989776361172334775629306733242881017157
? sqrt(tempcomp([-2,0,1])/4)
3.6426555430172368426362816254074846406837109449425
? tempcomp([4,-1,-1])
84.785208485344838791551484216448045243569419225714
? tempcomp([-3,2,0])
13.268939405074200609746037100143315056241924270378
? tempcomp([1,-2,1])
13.2689394050
? qfminim(X*X~ * mean5~ * W*W * mean5 * X*X~, 20, 20, 2)[3]

[31 62 93 18 49 -13 80 -44 111 -75 5 36 -26 67]

[12 24 36 7 19 -5 31 -17 43 -29 2 14 -10 26]

? qflllgram(mean5~*W*W*mean5)==X
1

Graham

🔗Carl Lumma <carl@lumma.org>

6/25/2011 11:22:51 AM

Hi Graham,

>From what I remember, Gene was finding good unison vectors
>for the equal temperament (val) according to temperamental
>complexity defined for the rank 3 temperament. I couldn't
>reproduce Gene's working. Carl was finding simple unison
>vectors in full JI space, and whether or not that's how he
>did it, he agreed with TLLL-reduction. Carl's method looks
>simple and good enough to implement but I didn't get
>further than this.

Thanks for digging this up. I don't have time to study it
now, but I can say two things:

* IIRC, Gene produced the scale with the lowest mean variety.

* My method is described at
/tuning-math/message/18305

-Carl