The wedge product is associative and distributive, but the key thing

to remember about it is that it is anticommunitive, which means that

u^v = - v^u. This entails that u^u = 0. When we apply this to basis

vectors, we see that if we start with four basis vectors {e2, e3, e5,

e7} and take wedge products, we get six basis vectors for the vector

space of the wedge product, ie {e2^e3, e2^e5, e2^e7, e3^e5, e3^e7,

e5^e7}. Thus 4 choose 1 = four dimensions goes to 4 choose 2 = six

dimensions. If we take a wedge product in this six-dimensional space

with another 4-d vector, or in other words a triple wedge product, we

get a basis {e3^e5^e7, e2^e5^e7, e2^e3^e7, e2^e3^e5} of 4 choose 3 =

four dimensions. If we take a quadruple wedge product, we get a 4

choose 4 = one-demensional space, with basis element {e2^e3^e5^e7};

this can therefore be identified with a scalar, which makes the

quadruple wedge product the determinant. The triple wedge product,

being in effect a thing which takes an interval and sends it to an

integer, can be identified with a val. The triple wedge product of

three 7-limit intervals is the val we get by putting the three

intervals in as rows of a 4x4 matrix and making the top row the four

basis vectors.

This same game can, of course, be played in any number of dimensions,

where we get a Pascal's triangle arrangement to the dimensions. In

the 11-limit, with five dimensions, it goes 5 10 10 5 1 and we get up

to quintuple wedge products. The wedge product of two intervals will

be in a space of dimension n choose 2 = n(n-1)/2, and the length of

the vector in the ordinary norm will be the area of the paralleogram

defined by the two intervals, and the direction will be defined by

the orientation of the paralleogram. In four dimensions, this *isn't*

simply a vector, because a vector is perpendicular to *three*

dimensions, not two. The double wedge product is therefore an

oriented area, the triple wedge product an oriented volume (defined

by three vectors) and so forth--down finally to the determinant.

The coefficients of the double wedge product can be thought of as the

areas of the paralleogram of interval classes defined by taking only

two of the four primes. If there is a common factor in each such

reduction, it spells torsion. We may also see the torsion in

comparing lenghts of wedge products, or their coefficients. We have

64/63^49/48 = [-14, 0, 8, 0, -5, 0] = u

u.u = 3*5*19

16807/15552^256/243 = [70, 0, -40, 0, 25, 0] = v

v = -5 u; and v.v = 3*5^3*19, showing it is 5 times longer.

If someone wants to program this, the following might help:

[u1, u2, u3, u4]^[v1, v2, v3, v4] = [u1*v2-v1*u2, u1*v3-v1*u3,

u1*v4-v1*u4, u2*v3-v3*u2, u2*v4-v2*u4, u3*v4-v3*u4]

In-Reply-To: <9tv600+a9o8@eGroups.com>

Gene wrote:

> four dimensions. If we take a quadruple wedge product, we get a 4

> choose 4 = one-demensional space, with basis element {e2^e3^e5^e7};

> this can therefore be identified with a scalar, which makes the

> quadruple wedge product the determinant.

Okay, if you were to do that in octave-equivalent space, this would be the

Fokker determinant. In octave-equivalent 7-limit space, it's the scalar

triple product, which Fokker would have recognised as being a kind of

volume.

> The triple wedge product,

> being in effect a thing which takes an interval and sends it to an

> integer, can be identified with a val. The triple wedge product of

> three 7-limit intervals is the val we get by putting the three

> intervals in as rows of a 4x4 matrix and making the top row the four

> basis vectors.

That's the same as what I'm getting by taking the left hand column of the

adjoint, with an arbitrary row to make up the numbers. So with octave

specific unison vectors, it describes the related equal temperament. With

octave equivalent vectors it gives you the mapping. In three dimensions,

it's the same as the vector product.

And all this has something to do with wedge products?

Graham

Okay, let's go right back to the beginning. I already have a tutorial

online for matrix algebra. See

<http://x31eq.com/matritut.htm>. If you take the basic

equivalence there, that

5x + 3y + z

is the same as

(5 3 1)(x)

(y)

(z)

you can similarly write any row vector (a b c) as

(a b c)(e1)

(e2)

(e3)

or

a*e1 + b*e2 + c*e3

where * is a normal multiplication and ei simply means the ith element of

the basis. You can then multiply two vectors (a b) and (c d) to get

(a*e1 + b*e2) * (c*e1 + d*e2)

which comes out as

a*c*e1*e1 + a*d*e1*e2 + b*c*e2*e1 + b*d*e2*e2

The music matrices I usually talk about have a basis H, where each entry

is a number. So a normal multiplication really does work

(a b)H * (c d)H

= (a*log(2) + b*log(3)) * (c*log(2) + d*log(3))

= a*c*log(2)*log(2) + a*d*log(2)*log(3)

+ b*c*log(3)*log(2) + b*d*log(3)*log(3)

= a*c*log(2)**2 + (a*d + b*c)*log(2)*log(3) + b*d*log(3)**2

But in general you can't do that, because there isn't a rule for

multiplying elements of a basis. The wedge product is a specific rule

for multipying bases. NOW PAY ATTENTION!

ei^ej = - ej^ei

According to Gene, that's the full definition of a wedge product. So, as

long as you paid attention when I told you you can ignore the rest. You

know what a wedge product is. It follows that

ei^ei = -ei^ei

ei^ei + ei^ei = 0

2*(ei^ei) = 0

ei^ei = 0

So the wedge product of (a b) and (c d) is

(a b)^(c d)

= (a*e1 + b*e2) ^ (c*e1 + d*e2)

= a*c*e1^e1 + a*d*e1^e2 + b*c*e2^e1 + b*d*e2^e2

= a*d*e1^e2 - b*c*e2^e1

= (a*d - b*c)

the same as the determinant

|a b|

|c d|

It gets more complicated in three dimensions

A^B

= (a1*e1 + a2*e2 + a3*e3)^(b1*e1 + b2*e2 + b3*e3)

= a1*b1*e1^e1 + a1*b2*e1^e2 + a1*b3*e1^e3

+ a2*b1*e2^e1 + a2*b2*e2^e2 + a2*b3*e2^e3

+ a3*b1*e3^e1 + a3*b2*e3^e2 + a3*b3*e3^e3

= a1*b2*e1^e2 + a1*b3*e1^e3

- a2*b1*e1^e2 + a2*b3*e2^e3

- a3*b1*e1^e3 - a3*b2*e2^e3

= (a1*b2 - a2*b1)*e1^e2 + (a1*b3 - a3*b1)*e1^e3

+ (a2*b3 - a3*b2)*e2^e3

which is the same as the determinant

|e2^e3 e3^e1 e1^e2|

| a1 a2 a3 |

| b1 b2 b3 |

That's analogous to the cross product of vectors, where AxB is

|x y z|

|a1 a2 a3|

|b1 b2 b3|

and, if A and B are octave-specific 5-limit unison vectors, it happens

that AxB gives the number of steps to each prime consonance. Or, if A and

B are octave-equivalent 7-limit commatic unison vectors, AxB is the

generator mapping.

I can't be bothered to work out the triple wedge product, but you'll find

it's all in terms of e1^e2^e3. So it's something like the determinant

|a1 a2 a3|

|b1 b2 b3|

|c1 c2 c3|

And the right number of wedge products in the right number of dimensions

will always give a determinant.

As determinants and cross products are already useful in dealing with

unison vectors, it shouldn't be such a surprise that wedge products in

general are also useful. I still don't know how they're useful, but Gene

assures us that they are.

What is this "wedge invariant" he keeps using, and how do you go from it

to get a list of unison vectors?

I'm not sure how to implement these things in Python. I could implement

vectors like dictionaries, so

A = {e1:a1, e2:a2, e3:a3}

B = {e1:b1, e2:b2, e3:b3}

then (A^B)[ei^ej] = A[ei]*B[ej] - A[ej]*B[ei]

so the next problem is what data type ei and ej should be. Probably

something like tuples:

A = {(1,):a1, (2,):a2, (3,):a3}

B = {(1,):b1, (2,):b2, (3,):b3}

that makes them look a bit like lists, so instead of A[1]=a1, we have

A[1,]=a1. Then, (A^B)[1, 2] = A[1,]*B[2,] + A[2,]*B[1,].

So this is making some sense, but I still haven't worked out all the

details needed to write the code.

Graham

--- In tuning-math@y..., graham@m... wrote:

> What is this "wedge invariant" he keeps using, and how do you go

from it

> to get a list of unison vectors?

First you order the basis so that a wedge product taken from two ets

or two unison vectors will correspond:

Then you put the wedge product into a standard form, by

(1) Dividing through by the gcd of the coefficients, and

(2) Changing sign if need be, so that the 5-limit comma (or unison)

2^w[6] * 3^(-w[2])*5^w[1] where w is the wedgie, is greater than 1.

If it equals 1, go on to the next invariant comma, which leaves out

5, and if that is 1 also to the one which leaves out 3. See

for the invariant commas. The result of this standardization is the

wedge invariant, or wedgie, which uniquely determins the temperament.

> I'm not sure how to impleme

nt these things in Python.

The above should do for the 7-limit; in general is another matter.

genewardsmith@juno.com (genewardsmith) wrote:

> First you order the basis so that a wedge product taken from two ets

> or two unison vectors will correspond:

>

> /tuning-math/message/1553

I think I've done that. All comes down to bubblesort -- one in the eye

for those who say it's of no practical use!

> Then you put the wedge product into a standard form, by

>

> (1) Dividing through by the gcd of the coefficients, and

Okay, that's easy enough.

> (2) Changing sign if need be, so that the 5-limit comma (or unison)

> 2^w[6] * 3^(-w[2])*5^w[1] where w is the wedgie, is greater than 1.

> If it equals 1, go on to the next invariant comma, which leaves out

> 5, and if that is 1 also to the one which leaves out 3. See

>

> /tuning-math/message/1555

>

> for the invariant commas. The result of this standardization is the

> wedge invariant, or wedgie, which uniquely determins the temperament.

I'll need to study that a bit more.

> > I'm not sure how to impleme

> nt these things in Python.

>

> The above should do for the 7-limit; in general is another matter.

Oh, it needs to be done in general. And it's almost working now. I still

need to get my wedge invariants to look like yours. Also to divide

through by common factors, but I've done that before.

To check:

>>> wedge.wedgeProduct(h12,h22)

{(2, 3): 2, (0, 1): 2, (1, 3): -12, (0, 3): -4, (0, 2): -4, (1, 2): -11}

That's numbering from 0 as the 2-direction, 1 as the 5-direction, etc.

Then for the commas

>>> for i in range(4):

print wedge.interval(

reduce(

wedge.wedgeProduct,

((zeros[:i]+(1,)+zeros[i+1:]), h12, h22)))

[0, -2, -12, 11]

[2, 0, 4, -4]

[12, -4, 0, -2]

[-11, 4, 2, 0]

which looks right. I'll look at it some more tomorrow. I'm still don't

know how to do the generator mapping.

Here's the library code:

def wedgeProduct(a, b):

result = {}

for base1, value1 in makewedgable(a).items():

for base2, value2 in makewedgable(b).items():

value = value1*value2

for element in base1:

if element in base2:

break

else:

base, value = wedgeEquivalent(base1+base2, value)

result[base] = result.get(base, 0)+value

return result

def interval(wedgie):

result = []

bases = wedgie.keys()

for i in range(len(wedgie)):

for base in bases:

if i not in base:

if i%2:

result.append(-wedgie[base])

else:

result.append(wedgie[base])

return result

def wedgeEquivalent(base, value):

workingBase = list(base)

for i in range(len(base)):

for j in range(i,0,-1):

if workingBase[j]<workingBase[j-1]:

workingBase[j-1:j+1] = [

workingBase[j],

workingBase[j-1]]

value = -value

return tuple(workingBase), value

def addWedges(a, b):

x = makewedgable(a)

y = makewedgable(b)

result = {}

for element in x.keys()+y.keys():

result[element]=0

for key in x.keys():

result[key] = result[key] + x[key]

for key in y.keys():

result[key] = result[key] + y[key]

return result

def makewedgable(thing):

if isinstance(thing, type({})):

return thing

else:

result = {}

for i in range(len(thing)):

result[i,]=thing[i]

return result

Update!

The code at <http://x31eq.com/temper.py> has been updated to do

most of the stuff I used to use matrices and Numeric for, but with wedge

products and standard Python 1.5.2. It's passed all the tests I've tried

so far, still some cleaning up to do.

My wedge invariants can't be made unique and invariant in all cases, but

they work most of the time. I could have a method for declaring of two

wedgable objects are equivalent. Also, my invariant is very different to

Gene's.

I still don't get the process for calculating unison vectors with wedge

products, especially in the general case.

One good thing is that the generator mapping (ignoring the period mapping)

which I'm using as my invariant key, is simply the octave-equivalent part

of the wedge product of the commatic unison vectors!

Example:

>>> h31 = temper.PrimeET(31, temper.primes[:4])

>>> h41 = temper.PrimeET(41, temper.primes[:4])

>>> h31^h41

{(2, 3): 15, (0, 4): 15, (1, 4): 3, (1, 2): -25, (0, 3): -2, (2, 4): 59,

(0, 2): -7, (3, 4): 49, (1, 3): -20, (0, 1): 6}

>>> (h31^h41).invariant()

(6, -7, -2, 15, -25, -20, 3, 15, 59, 49)

Gene:

> First you order the basis so that a wedge product taken from two ets

> or two unison vectors will correspond:

>

> /tuning-math/message/1553

I've got mine ordered, but it looks like a different order to yours.

> Then you put the wedge product into a standard form, by

>

> (1) Dividing through by the gcd of the coefficients, and

Okay, done that

> (2) Changing sign if need be, so that the 5-limit comma (or unison)

> 2^w[6] * 3^(-w[2])*5^w[1] where w is the wedgie, is greater than 1.

> If it equals 1, go on to the next invariant comma, which leaves out

> 5, and if that is 1 also to the one which leaves out 3. See

>

> /tuning-math/message/1555

>

> for the invariant commas. The result of this standardization is the

> wedge invariant, or wedgie, which uniquely determins the temperament.

Done something like this.

The problem is with zeroes. As it stands, the 5-limit interval 5:4 is the

same as the 7-limit interval 5:4 as far as the wedge products are

concerned. But some zero elements aren't always present. Either I can

get rid of them, which might mean that different products have the same

invariant, or enumerate the missing bases when I calculate the invariant.

The latter problem is the same as the one I'm trying to solve to get all

combinations of a list of unison vectors.

Another thing would be to ignore the invariants, and add a weak comparison

function.

As to the unison vectors, in the 7-limit I seem to be getting 4 when I

only wanted 2, so how can I be sure they're linearly independent?

Graham

--- In tuning-math@y..., graham@m... wrote:

> The code at <http://x31eq.com/temper.py> has been

updated to do

> most of the stuff I used to use matrices and Numeric for, but with

wedge

> products and standard Python 1.5.2. It's passed all the tests I've

tried

> so far, still some cleaning up to do.

What's the best version of Python for Win98, do you know? In

particular, what is the deal with the "stackless" version?

> My wedge invariants can't be made unique and invariant in all

cases, but

> they work most of the time. I could have a method for declaring of

two

> wedgable objects are equivalent.

You don't need to use my system; you could make the first non-zero

coefficient in the basis ordering you use positive.

Also, my invariant is very different to

> Gene's.

It should differ only in the sign or order of basis elements.

> I still don't get the process for calculating unison vectors with

wedge

> products, especially in the general case.

One way to think of the general case is to get the associated matrix

of what I call "vals", reduce by dividing out by gcds, and solve the

resultant system of linear Diophantine equations, which set each of

the val maps to zero.

> One good thing is that the generator mapping (ignoring the period

mapping)

> which I'm using as my invariant key, is simply the octave-

equivalent part

> of the wedge product of the commatic unison vectors!

Or of the wedge product of two ets.

> I've got mine ordered, but it looks like a different order to yours.

That's not surprising; the order is not determined by the definition

of wedge product, and I chose mine in a way I thought made sense from

the point of view of usability for music theory.

> Done something like this.

>

>

> The problem is with zeroes. As it stands, the 5-limit interval 5:4

is the

> same as the 7-limit interval 5:4 as far as the wedge products are

> concerned.

This has me confused, because it's the same as far as I'm concerned

too, unless you mean its vector representation.

But some zero elements aren't always present. Either I can

> get rid of them, which might mean that different products have the

same

> invariant, or enumerate the missing bases when I calculate the

invariant.

I don't know what is going on here.

> As to the unison vectors, in the 7-limit I seem to be getting 4

when I

> only wanted 2, so how can I be sure they're linearly independent?

They are never linearly independent. Why do they need to be?

--- In tuning-math@y..., graham@m... wrote:

> (6, -7, -2, 15, -25, -20, 3, 15, 59, 49)

> I've got mine ordered, but it looks like a different order to yours.

I don't think I talked about an 11-limit order. I have a program

which orders the above [6,-7,-2,15,20,-25,15,3,59,49] but I'm hardly

fixated on that ordering.

One thing which works well for wedge products of a pair of vectors

but which doesn't work so well for more is the skew-symmetric matrix

form. You take the outer product of the two vectors, and its

transpose, and subtract. It has some redundancy but it's pretty nice;

however for three vectors you get a cubical array and more

redundancy, and so forth.

--- In tuning-math@y..., "genewardsmith" <genewardsmith@j...> wrote:

> --- In tuning-math@y..., graham@m... wrote:

>

> > (6, -7, -2, 15, -25, -20, 3, 15, 59, 49)

>

> > I've got mine ordered, but it looks like a different order to

yours.

>

> I don't think I talked about an 11-limit order. I have a program

> which orders the above [6,-7,-2,15,20,-25,15,3,59,49] but I'm

hardly

> fixated on that ordering.

Here's the matrix form:

[ 0 6 -7 -2 15]

[-6 0 -25 -20 3]

[ 7 25 0 15 59]

[ 2 20 -15 0 49]

[-15 -3 -59 -49 0]

One nice thing about this form is that the previous prime limits are

included as the principal minors.

Gene wrote:

> What's the best version of Python for Win98, do you know? In

> particular, what is the deal with the "stackless" version?

Usually the latest stable ActiveState release, so long as you don't

quibble with the license.

Stackless is an experimental implementation that has continuations, and

doesn't need the Global Interpreter Lock.

> > My wedge invariants can't be made unique and invariant in all

> cases, but

> > they work most of the time. I could have a method for declaring of

> two

> > wedgable objects are equivalent.

>

> You don't need to use my system; you could make the first non-zero

> coefficient in the basis ordering you use positive.

Yes, that's what I do.

> Also, my invariant is very different to

> > Gene's.

>

> It should differ only in the sign or order of basis elements.

Looks like it, except for the zeros.

> > I still don't get the process for calculating unison vectors with

> wedge

> > products, especially in the general case.

>

> One way to think of the general case is to get the associated matrix

> of what I call "vals", reduce by dividing out by gcds, and solve the

> resultant system of linear Diophantine equations, which set each of

> the val maps to zero.

Is your matrix of vals my mapping by steps? [(41, 31), (65, 49), (95,

72), (115, 87), (142, 107)] for Miracle. If so, I'm with you until you

get to the Diophantine equations. I think it's solving systems of linear

Diophantine equations that I need to know how to do.

> > One good thing is that the generator mapping (ignoring the period

> mapping)

> > which I'm using as my invariant key, is simply the octave-

> equivalent part

> > of the wedge product of the commatic unison vectors!

>

> Or of the wedge product of two ets.

Ah, no, not quite. This works:

>>> wedgie = reduce(temper.wedgeProduct,

map(temper.WedgableRatio,

[(225,224),(385,384),(243,242)]))

>>> wedgie.octaveEquivalent().flatten()

(0, -6, 7, 2, -15)

but with the wedge of the temperaments

>>> (h31^h41).octaveEquivalent().flatten()

(-25, -20, 3, 15, 59, 49)

so what I have to do is

>>> (h31^h41).complement().octaveEquivalent().flatten()

(0, -6, 7, 2, -15)

The complement() method is something like a transpose. Would that be a

better name for it? Anyway, my invariant usually works so that wedge

products related in this way compare the same, but not always.

> > I've got mine ordered, but it looks like a different order to yours.

>

> That's not surprising; the order is not determined by the definition

> of wedge product, and I chose mine in a way I thought made sense from

> the point of view of usability for music theory.

Oh, well, mine's numerical order.

> > The problem is with zeroes. As it stands, the 5-limit interval 5:4

> is the

> > same as the 7-limit interval 5:4 as far as the wedge products are

> > concerned.

>

> This has me confused, because it's the same as far as I'm concerned

> too, unless you mean its vector representation.

Yes, for matrices you need to have consistent dimensions, but you can get

away without them for wedge products. At least the way I've implemented

them.

> But some zero elements aren't always present. Either I can

> > get rid of them, which might mean that different products have the

> same

> > invariant, or enumerate the missing bases when I calculate the

> invariant.

>

> I don't know what is going on here.

Take the multiple-29 wedgie:

>>> h29 = temper.PrimeET(29,temper.primes[:5])

>>> h58 = temper.PrimeET(58,temper.primes[:5])

>>> (h29^h58).invariant()

(0, 29, 29, 29, 29, 46, 46, 46, 46, -14, -33, -40, -19, -26, -7)

Note it starts with a zero, which corresponds to the (0,1) element. But,

if you build it up from the right set of unison vectors,

>>> wedgie = reduce(temper.wedgeProduct, (

(46, -29),

(-14, 0, -29, 29),

(33, 0, 29, 0, -29),

(7, 0, 0, 0, 29, -29)))

>>> wedgie.simplify()

>>> wedgie.complement()

{(0, 5): 29, (0, 4): 29, (1, 4): 46, (1, 5): 46, (1, 2): 46, (1, 3): 46,

(2, 5): -40, (2, 4): -33, (2, 3): -14, (3, 4): -19, (3, 5): -26, (0, 2):

29, (4, 5): -7, (0, 3): 29}

The (0,1) element isn't there. That means it's also missing from the

invariant

>>> wedgie.invariant()

(29, 29, 29, 29, 46, 46, 46, 46, -14, -33, -40, -19, -26, -7)

If I could enumerate over all pairs, I could fix that. But that still

leave the general problem of all combinations of N items taken from a set.

I'd prefer to get rid of zero elements altogether.

> > As to the unison vectors, in the 7-limit I seem to be getting 4

> when I

> > only wanted 2, so how can I be sure they're linearly independent?

>

> They are never linearly independent. Why do they need to be?

I need a pair of unison vectors to define a 7-limit linear temperament.

Right? Some pairs have torsion as well:

>>> for i in range(4):

for j in range(3):

print temper.wedgeProduct(vectors[i],

vectors[j]).torsion(),

0 2 12 2 0 4 12 4 0 11 4 2

The aim is to get a pair without torsion. And then generalize the process

for any number of dimensions.

Graham

--- In tuning-math@y..., graham@m... wrote:

> Is your matrix of vals my mapping by steps? [(41, 31), (65, 49),

(95,

> 72), (115, 87), (142, 107)] for Miracle. If so, I'm with you until

you

> get to the Diophantine equations. I think it's solving systems of

linear

> Diophantine equations that I need to know how to do.

No, but if you have an easy way to get your two vals, and if they

produce the correct wedgie, then they will work also.

> >>> wedgie = reduce(temper.wedgeProduct,

> map(temper.WedgableRatio,

> [(225,224),(385,384),(243,242)]))

I get 225/224^385/384^243^242 = h31^h41 =

[6,-7,-2,15,-25,-20,3,15,59,49] in the ordering I'm using now; this

has the correct number of dimensions, ten. If you want to mess around

with wedging equivalence classes (but what's the point?) then they

should come out in six dimensions. The equivalence class wedgies are

just subsets of the full wedgie, but they don't correspond any more,

and don't get rid of torsion, and so don't seem very useful.

> >>> wedgie.octaveEquivalent().flatten()

> (0, -6, 7, 2, -15)

>

> but with the wedge of the temperaments

>

> >>> (h31^h41).octaveEquivalent().flatten()

> (-25, -20, 3, 15, 59, 49)

Both of these are only part of the correct wedgie, so naturally they

are not in correspondence.

> Yes, for matrices you need to have consistent dimensions, but you

can get

> away without them for wedge products. At least the way I've

implemented

> them.

That may be your problem. You could do this by assuming infinite

dimensions, and ignoring things after the dimension becomes larger

than your inputs, where all coefficients become zero, but the normal

way is to stick with a certain number of dimensions.

>

> > But some zero elements aren't always present. Either I can

> > > get rid of them, which might mean that different products have

the

> > same

> > > invariant, or enumerate the missing bases when I calculate the

> > invariant.

You'd certainly can't ignore a basis element with a coefficient of

zero unless it is beyond the range of dimensions you are working in.

> Take the multiple-29 wedgie:

>

> >>> h29 = temper.PrimeET(29,temper.primes[:5])

> >>> h58 = temper.PrimeET(58,temper.primes[:5])

> >>> (h29^h58).invariant()

> (0, 29, 29, 29, 29, 46, 46, 46, 46, -14, -33, -40, -19, -26, -7)

There are fifteen of these, so presumably it is 13-limit, but you

don't say. For a 13-limit wedgie of these two, I get your result, so

that seems to be what it is.

> >>> wedgie.invariant()

> (29, 29, 29, 29, 46, 46, 46, 46, -14, -33, -40, -19, -26, -7)

This has dimension 14, which is wrong, and there is your missing zero.

> If I could enumerate over all pairs, I could fix that. But that

still

> leave the general problem of all combinations of N items taken from

a set.

> I'd prefer to get rid of zero elements altogether.

For programming purposes? I think the program should follow the math,

and not vice-versa; otherwise you are asking for trouble.

> Right? Some pairs have torsion as well:

My algorithm gets rid of the torsion, that's really the point of it

all.

In-Reply-To: <9v0ruo+hdll@eGroups.com>

Me:

> > Is your matrix of vals my mapping by steps? [(41, 31), (65, 49),

> (95,

> > 72), (115, 87), (142, 107)] for Miracle. If so, I'm with you until

> you

> > get to the Diophantine equations. I think it's solving systems of

> linear

> > Diophantine equations that I need to know how to do.

Gene:

> No, but if you have an easy way to get your two vals, and if they

> produce the correct wedgie, then they will work also.

Yes, I can get the wedgie no problem. It's going from that to the

simplest set of unison vectors that's the problem. It now looks like it's

systems of Diophantine equations I need to look at, and wedge products are

incidental.

> > >>> wedgie = reduce(temper.wedgeProduct,

> > map(temper.WedgableRatio,

> > [(225,224),(385,384),(243,242)]))

>

> I get 225/224^385/384^243^242 = h31^h41 =

> [6,-7,-2,15,-25,-20,3,15,59,49] in the ordering I'm using now; this

> has the correct number of dimensions, ten. If you want to mess around

> with wedging equivalence classes (but what's the point?) then they

> should come out in six dimensions. The equivalence class wedgies are

> just subsets of the full wedgie, but they don't correspond any more,

> and don't get rid of torsion, and so don't seem very useful.

What? The octave-equivalent part of the unison-vector wedgie is the

mapping by generators. It uniquely defines the temperament, and is the

most important thing we're trying to find. The other equivalence class

wedgies give us an ET mapping, if sometimes a silly one. These are the

two pieces of information we need to construct the temperament. So they

look like the most useful things the wedgie gives us.

> > >>> wedgie.octaveEquivalent().flatten()

> > (0, -6, 7, 2, -15)

> >

> > but with the wedge of the temperaments

> >

> > >>> (h31^h41).octaveEquivalent().flatten()

> > (-25, -20, 3, 15, 59, 49)

>

> Both of these are only part of the correct wedgie, so naturally they

> are not in correspondence.

Yes, but in the bit you cut off

Me:

> > One good thing is that the generator mapping (ignoring the period

> mapping)

> > which I'm using as my invariant key, is simply the octave-

> equivalent part

> > of the wedge product of the commatic unison vectors!

Gene:

> Or of the wedge product of two ets.

So it isn't the octave-equivalent part of the wedge product of the two ETs

at all. But you've been ignoring this distinction. Do you get it to work

in the 5-limit?

> > Yes, for matrices you need to have consistent dimensions, but you

> can get

> > away without them for wedge products. At least the way I've

> implemented

> > them.

>

> That may be your problem. You could do this by assuming infinite

> dimensions, and ignoring things after the dimension becomes larger

> than your inputs, where all coefficients become zero, but the normal

> way is to stick with a certain number of dimensions.

Yes, but then 5:4 can't be both a 5-limit and 7-limit interval at the same

time. I'm okay until we get to the flattening, which doesn't seem to be

important.

> > > But some zero elements aren't always present. Either I can

> > > > get rid of them, which might mean that different products have

> the

> > > same

> > > > invariant, or enumerate the missing bases when I calculate the

> > > invariant.

>

> You'd certainly can't ignore a basis element with a coefficient of

> zero unless it is beyond the range of dimensions you are working in.

But before you said the definition of wedge products was

ei^ej = -ej^ei

nothing about keeping zero elements. And it doesn't make any difference

so far. (May sometimes make the complements wrong.)

> > Take the multiple-29 wedgie:

> >

> > >>> h29 = temper.PrimeET(29,temper.primes[:5])

> > >>> h58 = temper.PrimeET(58,temper.primes[:5])

> > >>> (h29^h58).invariant()

> > (0, 29, 29, 29, 29, 46, 46, 46, 46, -14, -33, -40, -19, -26, -7)

>

> There are fifteen of these, so presumably it is 13-limit, but you

> don't say. For a 13-limit wedgie of these two, I get your result, so

> that seems to be what it is.

I do say.

> > >>> h29 = temper.PrimeET(29,temper.primes[:5])

^

5 octave-equivalent dimensions, so 13-limit.

> > >>> wedgie.invariant()

> > (29, 29, 29, 29, 46, 46, 46, 46, -14, -33, -40, -19, -26, -7)

>

> This has dimension 14, which is wrong, and there is your missing zero.

I know there's a missing zero. I was showing you why it went missing.

> > If I could enumerate over all pairs, I could fix that. But that

> still

> > leave the general problem of all combinations of N items taken from

> a set.

> > I'd prefer to get rid of zero elements altogether.

>

> For programming purposes? I think the program should follow the math,

> and not vice-versa; otherwise you are asking for trouble.

Either way, the program's following the math you originally gave.

> > Right? Some pairs have torsion as well:

>

> My algorithm gets rid of the torsion, that's really the point of it

> all.

That's the thing with isolve?

Graham

--- In tuning-math@y..., graham@m... wrote:

> In-Reply-To: <9v0ruo+hdll@e...>

> So it isn't the octave-equivalent part of the wedge product of the

two ETs

> at all. But you've been ignoring this distinction. Do you get it

to work

> in the 5-limit?

The 5-limit wedge product of two ets is the corresponding comma, and

of two commas the corresponding et. We've been doing this all along;

you can consider it to be a cross-product, or a matrix determinant.

The wedgie of a 5-limit linear temperament would reduce the cross-

product until it was not a power (getting rid of any torsion) and

standardize it to be greater than one.

> > You'd certainly can't ignore a basis element with a coefficient

of

> > zero unless it is beyond the range of dimensions you are working

in.

>

> But before you said the definition of wedge products was

>

> ei^ej = -ej^ei

>

> nothing about keeping zero elements.

That's the defintion, but it's an element in a vector space. You

can't wish way a basis element ei^ej simply because it has a

coefficient of zero, that isn't the way linear algebra works. A zero

vector is not the same as the number zero.

> > > If I could enumerate over all pairs, I could fix that. But

that

> > still

> > > leave the general problem of all combinations of N items taken

from

> > a set.

> > > I'd prefer to get rid of zero elements altogether.

Why not simply order a list of size n choose m, and if one entry has

the value zero, so be it? A function which goes from combinations of

the first n integers, takrn m at a time, to unique integers in the

range from 1 to n choose m might help.

In-Reply-To: <9v36kb+mvhf@eGroups.com>

gene wrote:

> The 5-limit wedge product of two ets is the corresponding comma, and

> of two commas the corresponding et. We've been doing this all along;

> you can consider it to be a cross-product, or a matrix determinant.

> The wedgie of a 5-limit linear temperament would reduce the cross-

> product until it was not a power (getting rid of any torsion) and

> standardize it to be greater than one.

The thing about the 5-limit is that the complements can have the same

dimensions. Here's where the problem arises:

>>> comma = temper.WedgableRatio(81,80)

>>> comma.octaveEquivalent()

{(2,): -1, (1,): 4}

>>> comma.octaveEquivalent().complement()

{(2,): 4, (1,): 1}

That shows the octave equivalent part of the syntonic comma is not the

meantone mapping. You need to take the complement. But in your system,

which ignores this distinction, how to you know that the vector as it

stands isn't right? You don't get any clues from the dimensions, because

they're the same. Do you have an algorithm that would give (0 4 1) as the

invariant of (-4 4 -1) wedged with (1 0 0)? I don't, so I explicitly take

the complement in the code.

Me:

> > But before you said the definition of wedge products was

> >

> > ei^ej = -ej^ei

> >

> > nothing about keeping zero elements.

Gene:

> That's the defintion, but it's an element in a vector space. You

> can't wish way a basis element ei^ej simply because it has a

> coefficient of zero, that isn't the way linear algebra works. A zero

> vector is not the same as the number zero.

So how about ei^ei, can I wish that away?

Seriously, until we get to complements and listifying, it doesn't make any

difference of those dimensions go. At least, not the way I wrote the code

it doesn't. I can always listify the generator and ET mappings. The only

problem would be if a temperament-defining wedgie didn't depend on a

particular prime interval, in which case I don't think it would define an

n-limit temperament.

> > > > If I could enumerate over all pairs, I could fix that. But

> that

> > > still

> > > > leave the general problem of all combinations of N items taken

> from

> > > a set.

> > > > I'd prefer to get rid of zero elements altogether.

>

> Why not simply order a list of size n choose m, and if one entry has

> the value zero, so be it? A function which goes from combinations of

> the first n integers, takrn m at a time, to unique integers in the

> range from 1 to n choose m might help.

Yes, it's getting the combinations of the first n integers that's the

problem. But I'm sure I can solve it if I sit down and think about it.

To make you happy, I'll do that.

>>> def combinations(number, input):

... if number==1:

... return [[x] for x in input]

... output = []

... for i in range(len(input)-number+1):

... for element in combinations(number-1, input[i+1:]):

... output.append([input[i]]+element)

... return output

(Hopefully the indentation will be okay on that, at least in View Source)

Inexistent entries are already the same as entries with the value zero in

that w[1,2] will be zero if w doesn't have an element (1,2). For example

>>> comma[0,]

-4

>>> comma[1,]

4

>>> comma[2,]

-1

>>> comma[3,]

0

So the 5-limit comma I used above is already a 7-limit interval. What I'd

like to change is for w[1,2]=0 to remove the element (1,2) instead of

assigning zero to it.

Graham