galgebra icon indicating copy to clipboard operation
galgebra copied to clipboard

Investigate whether the left and right contraction overloads are safe

Open eric-wieser opened this issue 4 years ago • 18 comments

galgebra uses a < b to mean left_contract(a, b). I'm worried that this doesn't work properly:

Quoting the python docs about the comparison ops:

There are no swapped-argument versions of these methods (to be used when the left argument does not support the operation but the right argument does); rather, lt()` and gt() are each other’s reflection

If the operands are of different types, and right operand’s type is a direct or indirect subclass of the left operand’s type, the reflected method of the right operand has priority, otherwise the left operand’s method has priority.

What this means is that obj < mv and mv > obj are indistinguishable if obj does not take part in the comparison.

From dorst, the rule for converting a left to right contraction is:

image

So by identity, left_contract(obj, mv) == right_contract(mv.rev(), obj.rev()).rev()

However, the python rules allow the rewrite left_contract(obj, mv) == right_contract(mv, obj).

Can we guarantee this is always true?

eric-wieser avatar Nov 19 '19 16:11 eric-wieser

Grassmann.jl has < and > for contractions and <<, >> for the symmetrization (e.g. ab+ba) and anti-symmetrization (commutator ab-ba)

In my paper you can find the formula I use for converting between left and right contraction: it is simply that a<b == b>a so the left contraction is computed by switching arguments of the right contraction.

chakravala avatar Nov 19 '19 20:11 chakravala

it is simply that a<b == b>a

That directly contradicts the screenshot I took above from GA4CS, you need to apply grade reversion too

eric-wieser avatar Nov 19 '19 20:11 eric-wieser

My definitions are based on the discussion I had previously with @orbots https://github.com/chakravala/Grassmann.jl/issues/27

On Tue, Nov 19, 2019, 3:38 PM Eric Wieser [email protected] wrote:

it is simply that a<b == b>a

That directly contradicts the screenshot I took above from GA4CS

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/pygae/galgebra/issues/54?email_source=notifications&email_token=AEMFOECWUKQKV6H7Y2ML5LLQURFDTA5CNFSM4JPGDAR2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEPVP6Y#issuecomment-555702267, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEMFOEAMLASCXBHDXUM3CCTQURFDTANCNFSM4JPGDARQ .

chakravala avatar Nov 19 '19 22:11 chakravala

@chakravala, I assume then that your_lc == ga4cs_lc, but your_rc(a, b) == ga4cs_rc(a.rev(), b.rev()).rev()?

Or do neither of them align?

@enkimute, it might be worth putting a comparison of contraction definitions among your comparison cheat sheets.

eric-wieser avatar Nov 19 '19 22:11 eric-wieser

@eric-wieser What do you mean by if obj does not take part in the comparison?

It seems that such a rewrite won't kick in unless not both < and > are defined(for corresponding types)and it's not the case in GAlgebra. So it seems to be fine pratically, am I missing something?

utensil avatar Nov 19 '19 23:11 utensil

@eric-wieser well, what happened is I originally had the same GA4CS definition as you

Then @orbots came along and opened https://github.com/chakravala/Grassmann.jl/issues/27 to discuss this definition

We settled on the definition I have now. So, I don't really know what's better or correct.

I mainly rely on the right contraction, not the left contraction.

Would be good if we can get to the bottom of this.

chakravala avatar Nov 20 '19 02:11 chakravala

The issue I opened was simply that the left contraction should be the b-a grade element of the geometric product A<B == <AB>_(b-a). I didn't specify the relationship between lc and rc. I don't think the relation a<b == b>a holds in general. From the definition in the Dorst paper I referenced it doesn't. @chakravala are you still using the hodge star to define contractions? That might be the source of the problem. I think if you want to define some "inner products" ( are contractions inner products? ) with the hodge star you should give them different names from the GA ones.

Orbots avatar Nov 20 '19 18:11 Orbots

Alright, well the original definition I used is the original Grassmann definition as discussed by John Browne in his book, which comes out as

complementhodge(a) ∨ b

which, it turns out, should be equivalent to the definition used by Dorst (but simpler in my opinion)

so, I will be switching back to the original definition for left complement, somehow I got confused when you opened that issue and I changed it, I'll go back to what I had originally

the change is now implemented in this commit https://github.com/chakravala/AbstractTensors.jl/commit/6a0542e005dcd2f90286bc74f6973742e0ca48f8

chakravala avatar Nov 22 '19 16:11 chakravala

julia> ⋆(1v1) ∨ (1v1 ∧ 1v2)
-1v₂

Not what Dorst's left complement would give you. I didn't see a complementhodge method in my version of Grassmann.jl

AFAICT you can choose your own operator, but left and right contractions have well established definitions in geometric algebra.

From the John Browne reference (didn't read too far ) there was an inner product with an entirely different symbol which appears to be the right contraction.

https://www.researchgate.net/publication/2842332_The_Inner_Products_of_Geometric_Algebra

Screen Shot 2019-11-22 at 10 52 52 AM

one more source I found from a quick google:

Theorem 16. Let Ar and Bs be nonzero blades where r, s ≥ 1.
(a) Ar ⌋ Bs = 0 iff Ar contains a nonzero vector orthogonal to Bs .
(b) If r < s then Ar ⌋ Bs, if nonzero, is an s − r-blade representing the orthogonal complement of Ar in Bs.
` ``

<blockquote><img src="https://c5.rgstatic.net/m/426351313275430/images/favicon/favicon.ico" width="48" align="right"><div><img src="https://c5.rgstatic.net/m/42134677640462/images/favicon/favicon-16x16.png" height="14"> ResearchGate</div><div><strong><a href="https://www.researchgate.net/publication/2842332_The_Inner_Products_of_Geometric_Algebra">ResearchGate</a></strong></div><div>ResearchGate is a network dedicated to science and research. Connect, collaborate and discover scientific publications, jobs and conferences. All for free.</div></blockquote>

Orbots avatar Nov 22 '19 18:11 Orbots

Not what Dorst's left complement would give you.

Actually, it is the same result as Dorst's left complement, check with some examples below:

dorst(a,b) = ~((~b)⋅(~a))
grassmann(a,b) = (⋆a)∨b
compare(a,b) = dorst(a,b),grassmann(a,b)

now check with the compare method:

julia> compare(v1,v12)
(-1v₂, -1v₂)

The result of Grassmann is indeed the same as what @eric-wieser posted above.

I didn't see a complementhodge method in my version of Grassmann.jl

Sorry, it is Grassmann.complementrighthodge not complementhodge.

From the John Browne reference (didn't read too far ) there was an inner product with an entirely different symbol which appears to be the right contraction.

That's correct, he has the right contraction as default, as do I, but he also has the left contraction too, which turns out to be the same as Dorst's definition also, just written in a different way.

chakravala avatar Nov 22 '19 19:11 chakravala

I can see that your code is self consistent. However the math says that the left contraction of a grade 1 blade with a grade 2 blade is the grade 2-1 = 1 grade element of the geometric product between the two. So the answer should be 1v2 not -1v2.

Better to check your definitions against another lib. Here's what ganja.js says: https://enkimute.github.io/ganja.js/examples/coffeeshop.html#OGRllEcPi

Orbots avatar Nov 22 '19 20:11 Orbots

Better to check your definitions against another lib. Here's what ganja.js says:

it looks to me more like ganja.js is not using the correct left contraction definition, instead it is using a definition which has been mis-named as the left contraction, but is actually the right contraction with its arguments swapped:

this is why I use the right contraction... because that gives you the inner product! the left contraction is another strange beast, which should not be the default (study John Browne)

also, it looks like ganja.js does not return the correct value for the right contraction (>>) either.. the result it returns for the "left contraction" is actually what the right contraction swapped should be

the definition @orbots and @enki seems to want is the following:

right(a,b) =  a ∨ complementrighthodge(b)
right_swapped(a,b) = right(b,a)

which is what I changed it to for him in https://github.com/chakravala/Grassmann.jl/issues/27 that is the right contraction, but with arguments swapped. but the left contraction is

left(a,b) = complementrighthodge(a) ∨ b

so @enki is also using the right contraction with arguments swapped, as @orbots does

you seem to be confused, you are not actually using the left contraction then.

chakravala avatar Nov 22 '19 20:11 chakravala

I haven't read the John Browne book, looks interesting though. I'll add it to my stack.

@chakravala it seems your definition of contraction in Grassmann.jl is different from the one used in Geometric Algebra. Nothing wrong with that and I don't want to get into a discussion about which one is "right".

This particular issue we are discussing here is for a Geometric Algebra library, galgebra.

The current Geometric Algebra definition of contractions should be used here, not the Grassmann Algebra/Grassmann.jl/John Browne's definition. Unless the contributers to galgebra decide otherwise.

Orbots avatar Nov 22 '19 21:11 Orbots

At this point I suggest we continue this conversation at the Grassman.jl repository.

The intent of this issue was to flag a potentially dangerous use of python operator overload semantics, not to question the operators of geometric Algebra.

eric-wieser avatar Nov 22 '19 22:11 eric-wieser

This is nice to be fixed and it's a good discussion, but as an issue, we could close it now as it tracks no action.

utensil avatar Jun 02 '20 13:06 utensil

Reopening because I have an answer - they're not safe, we need to change them:

>>> from galgebra.ga import Ga
>>> from sympy import S
>>> g, e1, e2, e3 = Ga.build('e1 e2 e3', g=[1, 1, 1])
>>> one = g.mv(S.One)
>>> e12 = e1 ^ e2

# with sympy scalars (incorrect)
>>> [S.One < e12, S.One > e12, e12 < S.One, e12 > S.One]
[0, e1^e2, e1^e2, 0]

# with Mv instances (correct)
>>> [one < e12, one > e12, e12 < one, e12 > one]
[e1^e2, 0, 0, e1^e2]

Either that, or we have a new bug

eric-wieser avatar Jun 02 '20 14:06 eric-wieser

Turns out that bug is not relevant. However, our current design means that we cannot cooperatively dispatch the contraction methods, unlike all the other multiplication methods that can return NotImplemented:

https://github.com/pygae/galgebra/blob/48822e7c530fd68bc5b3b407bd4391c3a82b96dc/galgebra/mv.py#L831-L834

https://github.com/pygae/galgebra/blob/48822e7c530fd68bc5b3b407bd4391c3a82b96dc/galgebra/mv.py#L851-L854

eric-wieser avatar Jun 02 '20 14:06 eric-wieser

I see, that's why you said "#54 causes no visible issues, but does cause internal headaches and incompatibility with clifford". So this issue itself could be closed again?

utensil avatar Jun 03 '20 02:06 utensil