back to list

Wedge products

🔗genewardsmith@juno.com

11/26/2001 8:49:04 PM

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]

🔗graham@microtonal.co.uk

11/27/2001 9:11:00 AM

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

🔗graham@microtonal.co.uk

12/6/2001 11:03:00 AM

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

🔗genewardsmith <genewardsmith@juno.com>

12/6/2001 4:01:24 PM

--- 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:

/tuning-math/message/1553

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

/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'm not sure how to impleme
nt these things in Python.

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

🔗graham@microtonal.co.uk

12/7/2001 1:14:00 PM

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

🔗graham@microtonal.co.uk

12/8/2001 1:32:00 PM

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

🔗genewardsmith <genewardsmith@juno.com>

12/8/2001 1:55:49 PM

--- 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?

🔗genewardsmith <genewardsmith@juno.com>

12/8/2001 11:40:08 PM

--- 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.

🔗genewardsmith <genewardsmith@juno.com>

12/9/2001 12:26:50 AM

--- 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.

🔗graham@microtonal.co.uk

12/9/2001 8:02:00 AM

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

🔗genewardsmith <genewardsmith@juno.com>

12/9/2001 3:26:16 PM

--- 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.

🔗graham@microtonal.co.uk

12/10/2001 5:06:00 AM

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

🔗genewardsmith <genewardsmith@juno.com>

12/10/2001 12:40:43 PM

--- 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.

🔗graham@microtonal.co.uk

12/11/2001 4:55:00 AM

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