In [1]:
using SymPy
In [2]:
SymPy.sympy.__version__
Out[2]:
In [3]:
using PyCall
In [4]:
const ga = PyCall.PyNULL()
copy!(ga, PyCall.pyimport_conda("galgebra.ga", "galgebra"))
const mv = PyCall.PyNULL()
copy!(mv, PyCall.pyimport_conda("galgebra.mv", "galgebra"))
const printer = PyCall.PyNULL()
copy!(printer, PyCall.pyimport_conda("galgebra.printer", "galgebra"))
ga
Out[4]:
In [5]:
printer.Format()
In [6]:
mutable struct Mv
o::PyCall.PyObject
end
Base.convert(::Type{Mv}, o::PyCall.PyObject) = Mv(o)
pytype_mapping(mv.Mv, Mv)
Out[6]:
In [7]:
macro define_op(type, op, method)
@eval begin
$op(x::$type, y::$type) = x.o.$method(y.o)
end
end
Out[7]:
In [8]:
macro define_lop(type, rtype, op, lmethod)
@eval begin
$op(x::$type, y::$rtype) = x.o.$lmethod(y)
end
end
macro define_rop(type, ltype, op, rmethod)
@eval begin
$op(x::$ltype, y::$type) = y.o.$rmethod(x)
end
end
Out[8]:
In [9]:
import Base: +,-,*,/,^,==
@define_op(Mv, +, __add__)
@define_op(Mv, -, __sub__)
# Geometric product: *
@define_op(Mv, *, __mul__)
@define_op(Mv, /, __div__)
@define_op(Mv, ^, __pow__)
@define_op(Mv, ==, __eq__)
# Wedge product: \wedge
@define_op(Mv, ∧, __xor__)
# Hestene's inner product: \cdot
@define_op(Mv, ⋅, __or__)
# Left contraction: \rfloor
@define_op(Mv, <<, __lt__)
@define_op(Mv, ⊣, __lt__)
# Right contraction: \lfloor
@define_op(Mv, >>, __rt__)
@define_op(Mv, ⊢, __rt__)
Out[9]:
In [10]:
@define_lop(Mv, Sym, +, __add__)
@define_rop(Mv, Sym, +, __radd__)
@define_lop(Mv, Sym, -, __sub__)
@define_rop(Mv, Sym, -, __rsub__)
@define_lop(Mv, Sym, *, __mul__)
@define_rop(Mv, Sym, *, __rmul__)
@define_lop(Mv, Sym, /, __div__)
@define_rop(Mv, Sym, /, __rdiv__)
@define_lop(Mv, Number, +, __add__)
@define_rop(Mv, Number, +, __radd__)
@define_lop(Mv, Number, -, __sub__)
@define_rop(Mv, Number, -, __rsub__)
@define_lop(Mv, Number, *, __mul__)
@define_rop(Mv, Number, *, __rmul__)
@define_lop(Mv, Number, /, __div__)
@define_rop(Mv, Number, /, __rdiv__)
Out[10]:
In [11]:
-(x::Mv) = x.o.__neg__()
Out[11]:
In [12]:
py"""
def vector(ga, components):
bases = ga.mv()
return sum([components[i] * e for i, e in enumerate(bases)])
"""
const vector = py"vector"
Out[12]:
In [13]:
macro define_show(type)
@eval begin
Base.show(io::IO, x::$type) = print(io, pystr(x.o))
Base.show(io::IO, ::MIME"text/plain", x::$type) = print(io, pystr(x.o))
Base.show(io::IO, ::MIME"text/latex", x::$type) = print(io, "\\begin{align*}" * printer.latex(x.o) * "\\end{align*}")
end
end
Out[13]:
In [14]:
@define_show(Mv)
In [15]:
(x, y, z) = xyz = symbols("x,y,z",real=true)
Out[15]:
In [16]:
(o3d, ex, ey, ez) = ga.Ga.build("e_x e_y e_z", g=[1, 1, 1], coords=xyz)
Out[16]:
In [17]:
ex
Out[17]:
In [18]:
ey
Out[18]:
In [19]:
ez
Out[19]:
In [20]:
const V = o3d
Out[20]:
In [21]:
a = V.mv("a", "scalar")
b = V.mv("b", "scalar")
c = V.mv("c", "scalar")
d = V.mv("d", "scalar")
u = V.mv("u", "vector")
v = V.mv("v", "vector")
w = V.mv("w", "vector")
Out[21]:
In [22]:
v + w == w + v
Out[22]:
In [23]:
(u + v) + w == u + (v + w)
Out[23]:
In [24]:
v + Sym(0) == v
Out[24]:
In [25]:
# TODO Why can't == work?
Sym(0) * v - Sym(0)
Out[25]:
In [26]:
Sym(1) * v == v
Out[26]:
In [27]:
a * (b * v) == (a * b) * v
Out[27]:
In [28]:
a * (v + w) == a * v + a * w
Out[28]:
In [29]:
(a + b) * v == a * v + b * v
Out[29]:
In [30]:
uu = vector(V, [1, 2, 3])
vv = vector(V, [4, 5, 6])
ww = vector(V, [5, 6, 7])
Out[30]:
In [31]:
uu + vv
Out[31]:
In [32]:
7 * uu + 2 * ww
Out[32]:
In [33]:
7 * uu - 2 * ww
Out[33]:
In [34]:
3 * uu + 2 * vv + ww
Out[34]:
In [35]:
v + ga.S(-1) * v
Out[35]:
In [36]:
v0 = vector(V, [0, 0, 0])
Out[36]:
In [37]:
a * v0 == v0
Out[37]:
In [38]:
(-a) * v == a * (-v)
Out[38]:
In [39]:
(-a) * v == - a * v
Out[39]:
In [40]:
SymPy.sqrt(2)
Out[40]:
In [41]:
SymPy.sqrt(Sym(2))
Out[41]:
In [42]:
SymPy.Rational(2, 3)
Out[42]:
In [43]:
Sym(SymPy.Rational(2, 3))
Out[43]:
In [44]:
SymPy.sqrt(2) * u + SymPy.Rational(2, 3) * v
Out[44]:
In [45]:
SymPy.sqrt(Sym(2)) * u + Sym(SymPy.Rational(2, 3)) * v
Out[45]:
In [ ]: