pygae / galgebra

Symbolic Geometric Algebra/Calculus package for SymPy :crystal_ball:
https://galgebra.rtfd.io/
BSD 3-Clause "New" or "Revised" License
223 stars 62 forks source link

Implementing overdot notation #19

Open utensil opened 5 years ago

utensil commented 5 years ago

As brought up by @FreddyBaudine here, @brombe originally described a way to implement the overdot notation in Python as Split Differential Operator which is described in 2.3.4 of GAlgebra: a Geometric Algebra Module for Sympy by Alan Bromborsky .

The overdot notation is used for describing the scope of ∇ which has been used in Geometric Algebra for Physicists by Chris Doran; Anthony Lasenby and many other books and papers. A very brief definition would be

image

( a snapshot taken from hout07.pdf in Course materials of Physical Applications of Geometric Algebra on http://geometry.mrao.cam.ac.uk/home/teaching-resources/ )

This issue does not mean there is a development plan for implementing overdot notation as either Split Differential Operator or other forms but a place to discuss it.

utensil commented 5 years ago

Pros:

Cons:

To summarize, it's highly unlikely for me to pull this off in the near future, the primary goal now is probably to make the original functionalities of galgebra usable for users, fixing bugs, increasing test coverage and improving documentations. But with the potential help from the community, it's possible and I'm glad to assist.

@FreddyBaudine , can you elaborate on the usecase scenario and expected syntax a little bit more?

FreddyBaudine commented 5 years ago

Dear Utensil,

I have taken heed of your ‘pros’ and ‘cons’ above and I could not agree more, especially the bit related to further testing. The Split Differential Operator shall have to wait.

As a case in point, Galgebra, which implements David Hestenes’s inner product, gives the wrong answer when multiplying two numerical scalars – it is OK if the scalar quantities have been declared as such or if the numerical scalars multiply vectors.
The same kind of mishap arises as far as Leo Dorst’s inner products, left and right contractions, are concerned.

For your convenience, I have enclosed in a zip file a little piece of code evincing all that as well as Leo Dorst’s paper, The Inner Products of Geometric Algebra.

Here are some examples computed with Galgebra making use of Python 3.7. image image image

The same types of error occur for the right contraction, please cast an eye on the enclosed code and PDF file.

InnerProducts.zip

Thanks again for your help. Kind regards, Freddy Baudine PS: It seems that I still have a little issue. The PDF file is created without any difficulty except that its creation ends up with !!!!Return to continue!!!!.

Here is the full message image

utensil commented 5 years ago

PS: It seems that I still have a little issue. The PDF file is created without any difficulty except that its creation ends up with !!!!Return to continue!!!!.

This behavior is intentional and you may see https://github.com/pygae/galgebra/issues/15#issuecomment-467683829 for the solution.

I do hope to change this behavior someday.

FreddyBaudine commented 5 years ago

Dear Utensil,

Sorry for the trouble, I should have known better. I totally forgot about this solution of yours. When I enter a valid sequence, e.g., the number 1, as you suggested, and hit the ENTER key everything goes on smoothly to the end. However, proceeding that way, I am left only with my PY and PDF files. All the others, that is, the AUX, LOG and TEX files are erased. It is true that I do not need those files, but is this behaviour according to your design?

Kind regards, Freddy

utensil commented 5 years ago

Yes, it's also by (brombo's) design. These files are considered to be byproduct during generating the pdf. But TeX file could be useful, there should be an option to preserve it.

Sent with GitHawk

utensil commented 5 years ago

Also it's very dangerous to remove files, so I do plan to change these behaviors.

Sent with GitHawk

FreddyBaudine commented 5 years ago

Dear Utensil,

I am coming back to my comment above dated March 2, 2019 relating to inner products.

I have discovered that if you replace raw numerals with declared constant through the member function mv of the algebra Ga, correct results obtains. Thus, in order not to use raw numerals directly, I have modified the enclosed code by adding the following two lines

n5 = st4.mv(5) n11 = st4.mv(11)

Then, replacing the raw numerals 5 and 11 by the constants n5 and n11 respectively where things used to go wrong in the original code, we end up with the correct results.

You will observe that it not necessary to do this at every place where the above numerals are used, which is somewhat paradoxical.

Alan Bromborsky explains, in the footnote of Section 3.2 of his book, Instantiating a Multivector, that Ga.mv is used systematically in order to ensure that the instantiated multivector is associated with the correct algebra. However, numerals, by default, belong to any algebra whatsoever. I imagine that declaring constants as I did must somehow raise a flag to keep track of their status, leading in the end to the correct results. It seems to me that we should be able to enter numbers without the above stratagem.

What are your thoughts on all this?

Kind regards, FB InnerProductsTrial.zip

utensil commented 5 years ago

Dear @FreddyBaudine , sorry for the delay, I was working on #9 this week and will be working on issues related to #15, #18, #19 next week.

FreddyBaudine commented 5 years ago

Dear Utensil,

You don’t have to be sorry after the superb job you have done with the documentation.

Alas, it is while I was perusing it, more specifically the bit related to submanifolds, that I discovered that you had added a LateX output that I am totally unable to reproduce. To be more precise, I am referring to the program written on page 56 of Galgebra: a Geometric Algebra Module for Sympy (April 13, 2016). It is explicitly stated there that the output of this program is that given on the following page, that is, on page 57.

However, when you run the program, the output relating to the one-dimensional manifold is not that given in the listing. To wit, the basis vectors are not normalised and the metric tensor, possibly as a consequence of the foregoing is wrong. It looks as if the output, as far as one-dimensional submanifolds are concerned is utterly insensitive to the norm being set to true.

I have written two versions of the program both evincing the same mishaps. In the light of these results, I decided to verify systematically all the results given by galgebra. The calculations in question were performed through using the Physics package of Maple for second-dimensional submanifolds. As for the one-dimensional submanifolds, I had to do the reckoning by hand for the Physics package has been designed to work with space dimension greater than one. All the details are enclosed in the zip file.

Look forward to having your views on all this.

Kind regards, Freddy submanifolds.zip

ghost commented 4 years ago

I have an implementation of the overdot. The question is whether it makes sense? Assume you have product of multivector differential operators and multivectors. An example would be D.odot()*A^B.odot() where D is a multivector differential operator and A and B a multivector functions of coordinates. The member function odot() sets a flag, dot_flg, on each object. Then the multiplicative operations, *, and ^ (I don't know if it makes sense to also include |) are modified so that D mulitiplies A, that is to say a dotted term times a undotted term, any derivative operation are not evaluated. That is D.odot()*A results in a differential operator and not a multivector. The resulting product D.odot()*A have it's dot_flg set to True. This behavior is continued until the dotted differential operator multiplies a dotted multivector. Then the derivatives are applied and the result is a multivector.

The main problem that I see is checking the original expression to see where there are only two dotted terms one being a differential operator and one being a multivector. Also making sure that the dotted differential operator applies to the multivector. That is if the differential operator operates to the right is the multivector to it's right and vice versa. All how should more than one differential operator in the expression be interpreted or if that even makes sense.

Comments and suggestions are welcome.

ghost commented 4 years ago

I forgot one thing with regard to the overdot. You must use parenthesis to define the order of the operations in the original expression. This is especially important if you have both * and ^ operations.

utensil commented 4 years ago

Yeah, after Freddy Baudine brought this up, I've been struggling with the design of this overdot notation from time to time.

In my design, Instead of just add a flag to the original type, calling odot on an object will return a placeholder, symbolically recording the operations afterwards as the context, and once it meets another overdot that's compatible with the first overdot, it emits an ordinary GA expression. IMHO this design will solve part of the "make sense" problem and it works better for me, one who's less familiar with the internal of GAlgebra and didn't want to change it significantly and even mess it up just to implement the overdot, also it seems to be less coupled in the sense of object-oriented abstraction.

Sent with GitHawk

eric-wieser commented 4 years ago

I wonder if this is worthwhile at all. If you have some expression like

\grad_x (F(X) {\overdot G}(x) H(x))

then can you not just write it:

\left.\grad_y (F(x) G(y) H(x))\right|_{y=x}

Or in python notation:

(grad(y) * (F * G.subs(x, y) * H)).subs(y, x)

I suppose this is difficult because we have no mechanism to substitute whole multivectors at once.

utensil commented 4 years ago

Overdot in math smells insufficient notational support for truly representing the underlying semantics (Just check out Structure and Interpretation of Classical Mechanics and Functional Differential Geometry for the criticism on mathematical notations ). But @eric-wieser 's proposal is even less clear in conveying the semantics so aesthetically I disagree with the proposal. The proper notation in this case should be attached to the grad so the grad can be manipulated freely, the \right| things makes the manipulation a bit more awkward, this awkwardness would be more clear if we try to formalize it in a theorem prover like coq, agda or lean.

P.S. Overdot is an important part of @abrombo 's work in his new branch, although the implementation could be less coupled.

eric-wieser commented 4 years ago

P.S. Overdot is an important part of @abrombo 's work in his new branch, although the implementation could be less coupled.

From what I've seen of the branch, the only bit implemented is a.odot() setting a flag - nothing looks at that flag at the moment.

I've bumped this to the next release, since we're no closer than we were last release.

abrombo commented 4 years ago

On 5/29/20 8:37 AM, Eric Wieser wrote:

P.S. Overdot is an important part of @abrombo
<https://github.com/abrombo> 's work in his new branch, although
the implementation could be less coupled.

From what I've seen of the branch, the only bit implemented is |a.odot()| setting a flag - nothing looks at that flag at the moment.

I've bumped this to the next release, since we're no closer than we were last release.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pygae/galgebra/issues/19#issuecomment-635949007, or unsubscribe https://github.com/notifications/unsubscribe-auth/AN3TFRGZDALPP7VTMJNJINTRT6T7JANCNFSM4G3JH5XQ.

The saga of overdot is as follows. /odot()/ sets a flag on either a /dop/ or an /mv /object.  If there is an operation between a dotted /dop/ and an undotted /mv/ all differentiation is deferred the result being another /dop/. If both the /dop/ and the /mv/ are dotted the differentiation is performed and the result is an /mv/.  The code for doing this was in the overloaded /dop/ operators. I got this working when using sympy 1.2.  It stopped working for any later versions of sympy generating an error in sympy.  The sympy people looked at my code and traced the error and said they could not understand what happened and that was the end of it for then.

eric-wieser commented 4 years ago

The sympy people looked at my code and traced the error

Do you still have a copy of that code anywhere? All I can see is c4ec67804afb18dd3d15903aa1143726544df9a3, which has only the odot() method and nothing else.

eric-wieser commented 4 years ago

I found the mailing list thread at https://groups.google.com/forum/#!searchin/sympy/brombo%7Csort:date/sympy/x9nD3huSRBU/YQfj0XOiAgAJ, and pushed the code to https://github.com/pygae/galgebra/tree/recovered-history/galgebra3.tar.gz

Google Groups
Google Groups allows you to create and participate in online forums and email-based groups with a rich experience for community conversations.
GitHub
pygae/galgebra
Symbolic Geometric Algebra/Calculus package for SymPy :crystal_ball: - pygae/galgebra
utensil commented 4 years ago

Seems to be the implementation I imagined it......before the latest discussion on Slack.

utensil commented 1 year ago

This is an old issue and I almost forgot what I said above, but I've just come across something similar that might shed some light on the design of this, so I add the notes here:

There's an operation in QFT called Wick contraction, what it does is not relevant here, but the notation and its LaTeX implementation might be inspiring.

The notation and LaTeX syntax looks like:

image

Check out https://jpellis.me/projects/simpler-wick/ (there's a PDF documentation in it) and https://tex.stackexchange.com/questions/460657/how-do-i-do-wick-contraction-with-dirac-bracket for further info.

The core ideas that I get from it are:

  1. overdot notation is confusing about the pairing(not visually indicating there's a relation between two over-dotted symbols), and can't support more than one pair;
  2. Wick contraction solves problem 1;
  3. The LaTeX implementation of simpler-wick makes it clear that it should be a two phase thing("label" and "pair") and derive the info and inject them during the pairing phase (although the label should not be limited to numerical like in simpler-wick), also the second labling of the same label can trigger the pairing and injecting.

These might seem obvious in retrospect, but it's good to have some reference.