def test_mixed_algebras(self): coords = x, y, z = symbols('x y z', real=True) ga1, ex1, ey1, ez1 = Ga.build('e1*x|y|z', g=[1, 1, 1], coords=coords) ga2, ex2, ey2, ez2 = Ga.build('e2*x|y|z', g=[1, 1, 1], coords=coords) assert ga1 != ga2 v1 = ga1.mv('v', 'vector', f=True) v2 = ga2.mv('v', 'vector', f=True) with pytest.raises(ValueError): ga1.grad * v2 with pytest.raises(ValueError): v1 * ga2.rgrad with pytest.raises(ValueError): ga1.grad * ga2.grad
def derivatives_in_spherical_coordinates(): #Print_Function() coords = (r, th, phi) = symbols('r theta phi', real=True) (sp3d, er, eth, ephi) = Ga.build('e_r e_theta e_phi', g=[1, r**2, r**2 * sin(th)**2], coords=coords) grad = sp3d.grad f = sp3d.mv('f', 'scalar', f=True) A = sp3d.mv('A', 'vector', f=True) B = sp3d.mv('B', 'bivector', f=True) print('#Derivatives in Spherical Coordinates') print('f =', f) print('A =', A) print('B =', B) print('grad*f =', grad * f) print('grad|A =', grad | A) print('grad\\times A = -I*(grad^A) =', -sp3d.i * (grad ^ A)) print('%\\nabla^{2}f =', grad | (grad * f)) print('grad^B =', grad ^ B) """ print '( \\nabla\\W\\nabla )\\bm{e}_{r} =',((grad^grad)*er).trigsimp() print '( \\nabla\\W\\nabla )\\bm{e}_{\\theta} =',((grad^grad)*eth).trigsimp() print '( \\nabla\\W\\nabla )\\bm{e}_{\\phi} =',((grad^grad)*ephi).trigsimp() """ return
def derivatives_in_elliptic_cylindrical_coordinates(): #Print_Function() a = symbols('a', real=True) coords = (u, v, z) = symbols('u v z', real=True) (elip3d, er, eth, ephi) = Ga.build('e_u e_v e_z', X=[a * cosh(u) * cos(v), a * sinh(u) * sin(v), z], coords=coords, norm=True) grad = elip3d.grad f = elip3d.mv('f', 'scalar', f=True) A = elip3d.mv('A', 'vector', f=True) B = elip3d.mv('B', 'bivector', f=True) print('#Derivatives in Elliptic Cylindrical Coordinates') print('f =', f) print('A =', A) print('B =', B) print('grad*f =', grad * f) print('grad|A =', grad | A) print('-I*(grad^A) =', -elip3d.i * (grad ^ A)) print('grad^B =', grad ^ B) return
def derivatives_in_paraboloidal_coordinates(): #Print_Function() coords = (u, v, phi) = symbols('u v phi', real=True) (par3d, er, eth, ephi) = Ga.build( 'e_u e_v e_phi', X=[u * v * cos(phi), u * v * sin(phi), (u**2 - v**2) / 2], coords=coords, norm=True) grad = par3d.grad f = par3d.mv('f', 'scalar', f=True) A = par3d.mv('A', 'vector', f=True) B = par3d.mv('B', 'bivector', f=True) print('#Derivatives in Paraboloidal Coordinates') print('f =', f) print('A =', A) print('B =', B) print('grad*f =', grad * f) print('grad|A =', grad | A) (-par3d.i * (grad ^ A)).Fmt(3, 'grad\\times A = -I*(grad^A)') print('grad^B =', grad ^ B) return
def derivatives_in_toroidal_coordinates(): Print_Function() a = symbols('a', real=True) coords = (u, v, phi) = symbols('u v phi', real=True) (t3d, eu, ev, ephi) = Ga.build('e_u e_v e_phi', X=[ a * sinh(v) * cos(phi) / (cosh(v) - cos(u)), a * sinh(v) * sin(phi) / (cosh(v) - cos(u)), a * sin(u) / (cosh(v) - cos(u)) ], coords=coords, norm=True) grad = t3d.grad f = t3d.mv('f', 'scalar', f=True) A = t3d.mv('A', 'vector', f=True) B = t3d.mv('B', 'bivector', f=True) print('f =', f) print('A =', A) print('B =', B) print('grad*f =', grad * f) print('grad|A =', grad | A) print('-I*(grad^A) =', -t3d.i * (grad ^ A)) print('grad^B =', grad ^ B) return
def derivatives_in_bipolar_coordinates(): Print_Function() a = symbols('a', real=True) coords = (u, v, z) = symbols('u v z', real=True) (bp3d, eu, ev, ez) = Ga.build('e_u e_v e_z', X=[ a * sinh(v) / (cosh(v) - cos(u)), a * sin(u) / (cosh(v) - cos(u)), z ], coords=coords, norm=True) grad = bp3d.grad f = bp3d.mv('f', 'scalar', f=True) A = bp3d.mv('A', 'vector', f=True) B = bp3d.mv('B', 'bivector', f=True) print('f =', f) print('A =', A) print('B =', B) print('grad*f =', grad * f) print('grad|A =', grad | A) print('-I*(grad^A) =', -bp3d.i * (grad ^ A)) print('grad^B =', grad ^ B) return
def derivatives_in_oblate_spheroidal_coordinates(): Print_Function() a = symbols('a', real=True) coords = (xi, eta, phi) = symbols('xi eta phi', real=True) (os3d, er, eth, ephi) = Ga.build('e_xi e_eta e_phi', X=[ a * cosh(xi) * cos(eta) * cos(phi), a * cosh(xi) * cos(eta) * sin(phi), a * sinh(xi) * sin(eta) ], coords=coords, norm=True) grad = os3d.grad f = os3d.mv('f', 'scalar', f=True) A = os3d.mv('A', 'vector', f=True) B = os3d.mv('B', 'bivector', f=True) print('f =', f) print('A =', A) print('B =', B) print('grad*f =', grad * f) print('grad|A =', grad | A) print('-I*(grad^A) =', -os3d.i * (grad ^ A)) print('grad^B =', grad ^ B) return
def derivatives_in_prolate_spheroidal_coordinates(): #Print_Function() a = symbols('a', real=True) coords = (xi, eta, phi) = symbols('xi eta phi', real=True) (ps3d, er, eth, ephi) = Ga.build('e_xi e_eta e_phi', X=[ a * sinh(xi) * sin(eta) * cos(phi), a * sinh(xi) * sin(eta) * sin(phi), a * cosh(xi) * cos(eta) ], coords=coords, norm=True) grad = ps3d.grad f = ps3d.mv('f', 'scalar', f=True) A = ps3d.mv('A', 'vector', f=True) B = ps3d.mv('B', 'bivector', f=True) print('#Derivatives in Prolate Spheroidal Coordinates') print('f =', f) print('A =', A) print('B =', B) print('grad*f =', grad * f) print('grad|A =', grad | A) (-ps3d.i * (grad ^ A)).Fmt(3, '-I*(grad^A)') (grad ^ B).Fmt(3, 'grad^B') return
def main(): Eprint() X = (x, y, z) = symbols('x y z', real=True) (o3d, ex, ey, ez) = Ga.build('e_x e_y e_z', g=[1, 1, 1], coords=(x, y, z)) A = x * (ey ^ ez) + y * (ez ^ ex) + z * (ex ^ ey) print('A =', A) print('grad^A =', (o3d.grad ^ A).simplify()) print() f = o3d.mv(1 / sqrt(x**2 + y**2 + z**2)) print('f =', f) print('grad*f =', (o3d.grad * f).simplify()) print() B = f * A print('B =', B) print() Curl_B = o3d.grad ^ B print('grad^B =', Curl_B.simplify()) return
def test_from_str(self): coords = symbols('x y', real=True) g, e1, e2 = Ga.build('e*1|2', coords=coords, g=[1, 1]) a1 = g.mv('a1', 'vector') a2 = g.mv('a2', 'vector') a1x, a1y = a1.get_coefs(1) a2x, a2y = a2.get_coefs(1) # one-d T = Mlt('T', g, nargs=1) v = T(a1) # Two new symbols created Tx, Ty = sorted(v.free_symbols - {a1x, a1y}, key=lambda x: x.sort_key()) assert v == ( Tx * a1x + Ty * a1y ) # two-d T = Mlt('T', g, nargs=2) v = T(a1, a2) # four new symbols created Txx, Txy, Tyx, Tyy = sorted(v.free_symbols - {a1x, a1y, a2x, a2y}, key=lambda x: x.sort_key()) assert v == ( Txx * a1x * a2x + Txy * a1x * a2y + Tyx * a1y * a2x + Tyy * a1y * a2y )
def Dirac_Equation_in_Geom_Calculus(): Print_Function() coords = symbols('t x y z', real=True) (st4d, g0, g1, g2, g3) = Ga.build('gamma*t|x|y|z', g=[1, -1, -1, -1], coords=coords) I = st4d.i (m, e) = symbols('m e') psi = st4d.mv('psi', 'spinor', f=True) A = st4d.mv('A', 'vector', f=True) sig_z = g3 * g0 print('\\text{4-Vector Potential\\;\\;}\\bm{A} =', A) print('\\text{8-component real spinor\\;\\;}\\bm{\\psi} =', psi) dirac_eq = (st4d.grad * psi) * I * sig_z - e * A * psi - m * psi * g0 dirac_eq = dirac_eq.simplify() print( dirac_eq.Fmt( 3, r'%\text{Dirac Equation\;\;}\nabla \bm{\psi} I \sigma_{z}-e\bm{A}\bm{\psi}-m\bm{\psi}\gamma_{t} = 0' )) return
def test_associativity_and_distributivity(self): coords = x, y, z = symbols('x y z', real=True) ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords) v = ga.mv('v', 'vector', f=True) laplacian = ga.grad * ga.grad rlaplacian = ga.rgrad * ga.rgrad # check addition distributes assert (laplacian + ga.grad) * v == laplacian * v + ga.grad * v != 0 assert (laplacian + 1234567) * v == laplacian * v + 1234567 * v != 0 assert (1234 * ex + ga.grad) * v == 1234 * ex * v + ga.grad * v != 0 # check subtraction distributes assert (laplacian - ga.grad) * v == laplacian * v - ga.grad * v != 0 assert (laplacian - 1234567) * v == laplacian * v - 1234567 * v != 0 assert (1234 * ex - ga.grad) * v == 1234 * ex * v - ga.grad * v != 0 # check unary subtraction distributes assert (-ga.grad) * v == -(ga.grad * v) != 0 # check division is associative assert v * (ga.rgrad / 2) == (v * ga.rgrad) / 2 != 0 # check multiplication is associative assert (ex * ga.grad) * v == ex * (ga.grad * v) != 0 assert (20 * ga.grad) * v == 20 * (ga.grad * v) != 0 assert v * (ga.rgrad * ex) == (v * ga.rgrad) * ex != 0 assert v * (ga.rgrad * 20) == (v * ga.rgrad) * 20 != 0 assert (laplacian * ga.grad) * v == laplacian * (ga.grad * v) != 0 # check wedge is associative assert (ex ^ ga.grad) ^ v == ex ^ (ga.grad ^ v) != 0 assert (20 ^ ga.grad) ^ v == 20 ^ (ga.grad ^ v) != 0 assert v ^ (ga.rgrad ^ ex) == (v ^ ga.rgrad) ^ ex != 0 assert v ^ (ga.rgrad ^ 20) == (v ^ ga.rgrad) ^ 20 != 0
def Maxwells_Equations_in_Geom_Calculus(): Print_Function() X = symbols('t x y z', real=True) (st4d, g0, g1, g2, g3) = Ga.build('gamma*t|x|y|z', g=[1, -1, -1, -1], coords=X) I = st4d.i B = st4d.mv('B', 'vector', f=True) E = st4d.mv('E', 'vector', f=True) B.set_coef(1, 0, 0) E.set_coef(1, 0, 0) B *= g0 E *= g0 J = st4d.mv('J', 'vector', f=True) F = E + I * B print(r'\text{Pseudo Scalar\;\;}I =', I) print('\\text{Magnetic Field Bi-Vector\\;\\;} B = \\bm{B\\gamma_{t}} =', B) print('\\text{Electric Field Bi-Vector\\;\\;} E = \\bm{E\\gamma_{t}} =', E) print('\\text{Electromagnetic Field Bi-Vector\\;\\;} F = E+IB =', F) print('%\\text{Four Current Density\\;\\;} J =', J) gradF = st4d.grad * F print('#Geom Derivative of Electomagnetic Field Bi-Vector') gradF.Fmt(3, 'grad*F') print('#Maxwell Equations') print('grad*F = J') print('#Div $E$ and Curl $H$ Equations') print((gradF.get_grade(1) - J).Fmt(3, '%\\grade{\\nabla F}_{1} -J = 0')) print('#Curl $E$ and Div $B$ equations') print((gradF.get_grade(3)).Fmt(3, '%\\grade{\\nabla F}_{3} = 0')) return
def test_blade_coefs(self): """ Various tests on several multivectors. """ (_g3d, e_1, e_2, e_3) = Ga.build('e*1|2|3') m0 = 2 * e_1 + e_2 - e_3 + 3 * (e_1 ^ e_3) + (e_1 ^ e_3) + (e_2 ^ (3 * e_3)) self.assertTrue(m0.blade_coefs([e_1]) == [2]) self.assertTrue(m0.blade_coefs([e_2]) == [1]) self.assertTrue(m0.blade_coefs([e_1, e_2]) == [2, 1]) self.assertTrue(m0.blade_coefs([e_1 ^ e_3]) == [4]) self.assertTrue(m0.blade_coefs([e_1 ^ e_3, e_2 ^ e_3]) == [4, 3]) self.assertTrue(m0.blade_coefs([e_2 ^ e_3, e_1 ^ e_3]) == [3, 4]) self.assertTrue(m0.blade_coefs([e_1, e_2 ^ e_3]) == [2, 3]) a = Symbol('a') b = Symbol('b') m1 = a * e_1 + e_2 - e_3 + b * (e_1 ^ e_2) self.assertTrue(m1.blade_coefs([e_1]) == [a]) self.assertTrue(m1.blade_coefs([e_2]) == [1]) self.assertTrue(m1.blade_coefs([e_3]) == [-1]) self.assertTrue(m1.blade_coefs([e_1 ^ e_2]) == [b]) self.assertTrue(m1.blade_coefs([e_2 ^ e_3]) == [0]) self.assertTrue(m1.blade_coefs([e_1 ^ e_3]) == [0]) self.assertTrue(m1.blade_coefs([e_1 ^ e_2 ^ e_3]) == [0]) # Invalid parameters self.assertRaises(ValueError, lambda: m1.blade_coefs([e_1 + e_2])) self.assertRaises(ValueError, lambda: m1.blade_coefs([e_2 ^ e_1])) self.assertRaises(ValueError, lambda: m1.blade_coefs([e_1, e_2 ^ e_1])) self.assertRaises(ValueError, lambda: m1.blade_coefs([a * e_1])) self.assertRaises(ValueError, lambda: m1.blade_coefs([3 * e_3]))
def test_make_grad(self): ga, e_1, e_2, e_3 = Ga.build('e*1|2|3', g=[1, 1, 1], coords=symbols('x y z')) r = ga.mv(ga.coord_vec) assert ga.make_grad(r) == ga.grad assert ga.make_grad(r, cmpflg=True) == ga.rgrad x = ga.mv('x', 'vector') B = ga.mv('B', 'bivector') dx = ga.make_grad(x) dB = ga.make_grad(B) # GA4P, eq. (6.29) for a in [ga.mv(1), e_1, e_1 ^ e_2]: r = a.i_grade assert dx * (x ^ a) == (ga.n - r) * a assert dx * (x * a) == ga.n * a # derivable via the product rule assert dx * (x * x) == 2 * x assert dx * (x * x * x) == (2 * x) * x + (x * x) * ga.n assert dB * (B * B) == 2 * B assert dB * (B * B * B) == (2 * B) * B + (B * B) * ga.n # an arbitrary chained expression to check we do not crash assert dB * dx * (B * x) == -3 assert dx * dB * (x * B) == -3 assert dx * dB * (B * x) == 9 assert dB * dx * (x * B) == 9
def main(): Print_Function() (a, b, c) = abc = symbols('a,b,c',real=True) (o3d, ea, eb, ec) = Ga.build('e_a e_b e_c', g=[1, 1, 1], coords=abc) grad = o3d.grad x = symbols('x',real=True) A = o3d.lt([[x*a*c**2,x**2*a*b*c,x**2*a**3*b**5],\ [x**3*a**2*b*c,x**4*a*b**2*c**5,5*x**4*a*b**2*c],\ [x**4*a*b**2*c**4,4*x**4*a*b**2*c**2,4*x**4*a**5*b**2*c]]) print('A =',A) v = a*ea+b*eb+c*ec print('v =',v) f = v|A(v) print(r'%f = v\cdot \f{A}{v} =',f) (grad * f).Fmt(3,r'%\nabla f') Av = A(v) print(r'%\f{A}{v} =', Av) (grad * Av).Fmt(3,r'%\nabla \f{A}{v}') return
def test_misc(self): """ Other miscellaneous tests """ coords = x, y, z = symbols('x y z', real=True) ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords) v = ga.mv('v', 'vector', f=True) laplacian = ga.grad * ga.grad rlaplacian = ga.rgrad * ga.rgrad # laplacian is a scalar operator, so applying it from either side # is the same assert laplacian * v == v * rlaplacian assert laplacian.is_scalar() assert not ga.grad.is_scalar() # test comparison assert ga.grad == ga.grad assert not (ga.grad != ga.grad) assert ga.grad != laplacian assert not (ga.grad == laplacian) assert ga.grad != object() assert not (ga.grad == object()) # inconsistent cmpflg, not clear which side the operator goes on with pytest.raises(ValueError): ga.grad + ga.rgrad with pytest.raises(ValueError): ga.grad * ga.rgrad
def basic_multivector_operations_3D(): Print_Function() (g3d,ex,ey,ez) = Ga.build('e*x|y|z') print('g_{ij} =',g3d.g) A = g3d.mv('A','mv') print(A.Fmt(1,'A')) print(A.Fmt(2,'A')) print(A.Fmt(3,'A')) print(A.even().Fmt(1,'%A_{+}')) print(A.odd().Fmt(1,'%A_{-}')) X = g3d.mv('X','vector') Y = g3d.mv('Y','vector') print(X.Fmt(1,'X')) print(Y.Fmt(1,'Y')) print((X*Y).Fmt(2,'X*Y')) print((X^Y).Fmt(2,'X^Y')) print((X|Y).Fmt(2,'X|Y')) return
def test_constructor_errors(self): ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1]) # list lengths must match with pytest.raises(ValueError, match='same length'): Dop([ex], [], ga=ga) # the two conventions can't be mixed mixed_args = [ (ex, Pdop({})), (Sdop([]), ex), ] with pytest.raises(TypeError, match='pairs'): Dop(mixed_args, ga=ga) # ga must be non-none with pytest.raises(ValueError, match='must not be None'): Dop([], ga=None) # too few arguments with pytest.raises(TypeError, match='0 were given'): Dop(ga=ga) # too many arguments with pytest.raises(TypeError, match='3 were given'): Dop(1, 2, 3, ga=ga)
def test_rep_switching(self): # this ga has a non-diagonal metric _g3d, e_1, e_2, e_3 = Ga.build('e*1|2|3') m0 = 2 * e_1 + e_2 - e_3 + 3 * (e_1 ^ e_3) + (e_1 ^ e_3) + (e_2 ^ (3 * e_3)) m1 = ( -4 * (e_1 | e_3) - 3 * (e_2 | e_3)) + 2 * e_1 + e_2 - e_3 + 4 * e_1 * e_3 + 3 * e_2 * e_3 # m1 was chosen to make this true self.assertEqual(m0, m1) # all objects start off in blade rep self.assertTrue(m0.is_blade_rep) # convert to base rep m0_base = m0.base_rep() self.assertTrue(m0.is_blade_rep) # original should not change self.assertFalse(m0_base.is_blade_rep) self.assertEqual(m0, m0_base) # convert back m0_base_blade = m0_base.blade_rep() self.assertFalse(m0_base.is_blade_rep) # original should not change self.assertTrue(m0_base_blade.is_blade_rep) self.assertEqual(m0, m0_base_blade)
def Lorentz_Tranformation_in_Geog_Algebra(): Print_Function() (alpha, beta, gamma) = symbols('alpha beta gamma') (x, t, xp, tp) = symbols("x t x' t'", real=True) (st2d, g0, g1) = Ga.build('gamma*t|x', g=[1, -1]) from sympy import sinh, cosh R = cosh(alpha / 2) + sinh(alpha / 2) * (g0 ^ g1) X = t * g0 + x * g1 Xp = tp * g0 + xp * g1 print('R =', R) print( r"#%t\bm{\gamma_{t}}+x\bm{\gamma_{x}} = t'\bm{\gamma'_{t}}+x'\bm{\gamma'_{x}} = R\lp t'\bm{\gamma_{t}}+x'\bm{\gamma_{x}}\rp R^{\dagger}" ) Xpp = R * Xp * R.rev() Xpp = Xpp.collect() Xpp = Xpp.trigsimp() print(r"%t\bm{\gamma_{t}}+x\bm{\gamma_{x}} =", Xpp) Xpp = Xpp.subs({sinh(alpha): gamma * beta, cosh(alpha): gamma}) print(r'%\f{\sinh}{\alpha} = \gamma\beta') print(r'%\f{\cosh}{\alpha} = \gamma') print(r"%t\bm{\gamma_{t}}+x\bm{\gamma_{x}} =", Xpp.collect()) return
def test_arithmetic(self): ga, e_1, e_2, e_3 = Ga.build('e*1|2|3', g=[1, 1, 1]) one = ga.mv(sympy.S.One) # test that scalars are promoted to Mvs correctly assert e_1 + 1 == e_1 + one assert 1 + e_1 == one + e_1 assert e_1 - 1 == e_1 - one assert 1 - e_1 == one - e_1
def test_single_basis(self): # dual numbers g, delta = Ga.build('delta,', g=[0]) assert delta * delta == 0 # which work for automatic differentiation x = Symbol('x') xd = x + delta f = lambda x: x**3 + 2 * x * 2 + 1 assert f(xd) == f(x) + f(x).diff(x) * delta
def test_hashable(self): ga, e_1, e_2, e_3 = Ga.build('e*1|2|3') d = {} d[e_1] = 1 d[e_2] = 2 assert d[e_1 + 0] == 1 d[10] = 3 # note: not a multivector key! assert d[e_1 * 0 + 10] == 3
def test_contraction(self, make_one): ga, e_1, e_2 = Ga.build('e*1|2', g=[1, 1]) e12 = e_1 ^ e_2 one = make_one(ga) assert (one < e12) == e12 assert (e12 > one) == e12 assert (e12 < one) == 0 assert (one > e12) == 0
def test_sympify(self): ga, e_1, e_2, e_3 = Ga.build('e*1|2|3', g=[1, 1, 1]) # Letting this succeed silently and not return an Mv instance would be # dangerous. with pytest.raises(sympy.SympifyError): sympy.sympify(e_1) # this is fine sympy.sympify(e_1.obj)
def test_components(self): coords = x, y, z = symbols('x y z', real=True) ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords) components = ga.grad.components() assert components == ( ex * (ex | ga.grad), ey * (ey | ga.grad), ez * (ez | ga.grad), )
def test_subs(self): ga, e_1, e_2, e_3 = Ga.build('e*1|2|3', g=[1, 1, 1]) B = ga.mv('B', 'bivector') B_inv = B.inv() B_mag = Symbol('|B|') # both of the sympy subs syntaxes work: assert (-B / B_mag**2).subs(B_mag, abs(B)) == B_inv assert (-B / B_mag**2).subs({B_mag: abs(B)}) == B_inv
def General_Lorentz_Tranformation(): Print_Function() (alpha, beta, gamma) = symbols('alpha beta gamma') (x, y, z, t) = symbols("x y z t", real=True) (st4d, g0, g1, g2, g3) = Ga.build('gamma*t|x|y|z', g=[1, -1, -1, -1]) B = (x * g1 + y * g2 + z * g3) ^ (t * g0) print(B) print(B.exp(hint='+')) print(B.exp(hint='-'))
def test_empty_dop(self): """ Test that dop with zero terms is equivalent to multiplying by zero """ coords = x, y, z = symbols('x y z', real=True) ga, ex, ey, ez = Ga.build('e*x|y|z', g=[1, 1, 1], coords=coords) v = ga.mv('v', 'vector', f=True) make_zero = ga.dop([]) assert make_zero * v == 0 assert make_zero * make_zero * v == 0 assert (make_zero + make_zero) * v == 0 assert (-make_zero) * v == 0
def test_is_base(self): """ Various tests on several multivectors. """ (_g3d, e_1, e_2, e_3) = Ga.build('e*1|2|3') self.assertTrue((e_1).is_base()) self.assertTrue((e_2).is_base()) self.assertTrue((e_3).is_base()) self.assertTrue((e_1 ^ e_2).is_base()) self.assertTrue((e_2 ^ e_3).is_base()) self.assertTrue((e_1 ^ e_3).is_base()) self.assertTrue((e_1 ^ e_2 ^ e_3).is_base()) self.assertFalse((2*e_1).is_base()) self.assertFalse((e_1 + e_2).is_base()) self.assertFalse((e_3 * 4).is_base()) self.assertFalse(((3 * e_1) ^ e_2).is_base()) self.assertFalse((2 * (e_2 ^ e_3)).is_base()) self.assertFalse((e_3 ^ e_1).is_base()) self.assertFalse((e_2 ^ e_1 ^ e_3).is_base())