pygae / galgebra

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

Getting wrong type of multivector #484

Closed ingodahn closed 6 months ago

ingodahn commented 1 year ago

I am trying to calculate the image of a 3D vector $u=e_1+2e_2+3e_3$ under the rotation with axis vector $e_1+e_2+e_3$. I would expect to get a vector as image but the calculation yields a vector + a tiny multiple of $e_1\wedge e_2\wedge e_3$, perhaps due to rounding errors.

The code is attached gaerror.txt

import sympy
from sympy import symbols
from galgebra.ga import *
from galgebra.printer import latex
from IPython.display import Math
import math
pi=math.pi
e=math.e
sin=math.sin
cos=math.cos
# tell sympy to use our printing by default
sympy.init_printing(latex_printer=latex, use_latex='mathjax')
xyz = (x, y, z) = symbols('x y z', real=True)
o3d = Ga('e_1 e_2 e_3', g=[1, 1, 1], coords=xyz)
e_1, e_2, e_3 = o3d.mv()
I=e_1*e_2*e_3
def normed(x):
    return (1/x.norm())*x
n=normed(e_1+e_2+e_3)
theta=pi/4
i=n*I
def expo(xx,tt):
    return cos(tt/2)+xx*sin(tt/2)
def RR(uu,ii,tt):
    return expo(-ii,tt)*uu*expo(ii,tt)
u=e_1+2*e_2+3*e_3
v=RR(u,i,theta)
v

Edit: Using an updated version of galgebra as described in http://www.faculty.luther.edu/~macdonal/GAlgebraPrimer.pdf and then using the exp() method from galgebra yields exactly the same result.

eric-wieser commented 1 year ago

Your mistake is that you use math.pi which is only an approximation of sympy.pi

ingodahn commented 1 year ago

No.

  1. Using pi=sympy.pi instead of pi=math.pi yields an excess term 2.77555756156289e-17*sqrt(3)*e_1^e_2^e_3 as well
  2. Not using pi at all but using the exp() method from the galgebra module yields the same result (see my edit)

Even if your argument would be true, it would only reinforce the problem that the galgebra module is incompatible with the rest of the world, mainly by overloading fundamental operators like *.

My Use Case: In a jupyter notebook with python-sagemath kernel I would like to use galgebra to calculate some geometric objects and visualize the result using SageMath. But when trying the visualization after using galgebra I get the error that the vector() method is unknown. My current workaround is copying the coefficients calculated by galgebra, ignoring excess terms, manually into anothe galgebra-free notebook.

eric-wieser commented 1 year ago

Can you share the exact code you're using for 2 ?

ingodahn commented 1 year ago

Attached is a version that does not produce excess terms by avoiding any use of math. From my other experiments it seems that excess terms are produced as soon as math is involved, for example by using in this script

pi is essential in the definition of theta but I can avoid the use of math.sin and math.cos).

import math pim=math.cos(math.pi) u=e_1+2*e_2+(3*pim)*e_3

galgebraTest2.txt

import sympy
from sympy import symbols
from galgebra.ga import *
from galgebra.printer import latex
from IPython.display import Math
#import math
#pi=math.pi
pi=sympy.pi
# tell sympy to use our printing by default
sympy.init_printing(latex_printer=latex, use_latex='mathjax')
xyz = (x, y, z) = symbols('x y z', real=True)
o3d = Ga('e_1 e_2 e_3', g=[1, 1, 1], coords=xyz)
e_1, e_2, e_3 = o3d.mv()
print('sympy, pi, e, sin, cos and galgebra loaded')
def normed(x):
    return (1/x.norm())*x
theta=pi/4
I=e_1*e_2*e_3
n=normed(e_1+e_2+e_3)
i=n*I
it=i*(theta/2)
u=e_1+2*e_2+3*e_3
v=((-it).exp())*u*(it.exp())
show(v)
eric-wieser commented 1 year ago

Yes, as soon as you use the math module you are working with floating-point approximations and not symbolic calculations.

Note you can paste code directly into comments here by using ``` around it

Greg1950 commented 1 year ago

In GAlgebra's mv.py module there are various built-in functions. Three of them

proj(B:Mv, A:Mv)

# projects the multivector *A* onto the subspace defined by the blade

B rot(itheta:Mv, A:Mv)

rotates the multivector A through the directed angle defined by the

2-blade itheta refl(B:Mv, A:Mv)

reflects the multivector A through the subspace spanned by the

blade B

were added over a decade ago while Alan Macdonald was writing his textbook Linear and Geometric Algebra. (Many of that textbook 's problems suggest the use of GAlgebra.)

Some coding effort would be saved were you to simply use rot(itheta, A). The answers by other respondents about round-off errors from use of the module math are still relevant.

On Sun, Apr 2, 2023 at 6:14 AM Eric Wieser @.***> wrote:

Yes, as soon as you use the math module you are working with floating-point approximations and not symbolic calculations.

Note you can paste code directly into comments here by using ``` around it

— Reply to this email directly, view it on GitHub https://github.com/pygae/galgebra/issues/484#issuecomment-1493302199, or unsubscribe https://github.com/notifications/unsubscribe-auth/AG2OCIDDDGAIDUQG45QKGSDW7FNPNANCNFSM6AAAAAAVWJCBSE . You are receiving this because you are subscribed to this thread.Message ID: @.***>

eric-wieser commented 1 year ago

Indeed, the function referred to by @Greg1950 can be found in the docs here

eric-wieser commented 1 year ago

The meaning of the hint argument is described in the docs for exp:

https://github.com/pygae/galgebra/blob/3a53b29fb141be1ae47d8df8fc7005c10869cded/galgebra/mv.py#L1093-L1100