X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_algebra.py;h=5d96a53f402f4f3343cc396049b4311d13fa3ba1;hb=8059516ad9df112ac18c740af7d6f856639d4b8d;hp=ad4e2c7832f961b4893814551657a7a823ac083d;hpb=3940dadefa5ede86fd81917ace7d145e4d3f0da9;p=sage.d.git diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index ad4e2c7..5d96a53 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -460,9 +460,7 @@ class FiniteDimensionalEJA(CombinatorialFreeModule): this algebra was constructed with ``check_axioms=False`` and passed an invalid multiplication table. """ - return all( self.product_on_basis(i,j) == self.product_on_basis(i,j) - for i in range(self.dimension()) - for j in range(self.dimension()) ) + return all( x*y == y*x for x in self.gens() for y in self.gens() ) def _is_jordanian(self): r""" @@ -931,7 +929,7 @@ class FiniteDimensionalEJA(CombinatorialFreeModule): # And to each subsequent row, prepend an entry that belongs to # the left-side "header column." - M += [ [self.gens()[i]] + [ self.product_on_basis(i,j) + M += [ [self.gens()[i]] + [ self.gens()[i]*self.gens()[j] for j in range(n) ] for i in range(n) ] @@ -3117,6 +3115,33 @@ class CartesianProductEJA(CombinatorialFreeModule_CartesianProduct, sage: CP2.is_associative() False + Cartesian products of Cartesian products work:: + + sage: J1 = JordanSpinEJA(1) + sage: J2 = JordanSpinEJA(1) + sage: J3 = JordanSpinEJA(1) + sage: J = cartesian_product([J1,cartesian_product([J2,J3])]) + sage: J.multiplication_table() + +--------------++---------+--------------+--------------+ + | * || e(0, 0) | e(1, (0, 0)) | e(1, (1, 0)) | + +==============++=========+==============+==============+ + | e(0, 0) || e(0, 0) | 0 | 0 | + +--------------++---------+--------------+--------------+ + | e(1, (0, 0)) || 0 | e(1, (0, 0)) | 0 | + +--------------++---------+--------------+--------------+ + | e(1, (1, 0)) || 0 | 0 | e(1, (1, 0)) | + +--------------++---------+--------------+--------------+ + sage: HadamardEJA(3).multiplication_table() + +----++----+----+----+ + | * || e0 | e1 | e2 | + +====++====+====+====+ + | e0 || e0 | 0 | 0 | + +----++----+----+----+ + | e1 || 0 | e1 | 0 | + +----++----+----+----+ + | e2 || 0 | 0 | e2 | + +----++----+----+----+ + TESTS: All factors must share the same base field:: @@ -3198,6 +3223,88 @@ class CartesianProductEJA(CombinatorialFreeModule_CartesianProduct, self.one.set_cache(self._cartesian_product_of_elements(ones)) self.rank.set_cache(sum(J.rank() for J in algebras)) + def _monomial_to_generator(self, mon): + r""" + Convert a monomial index into a generator index. + + This is needed in product algebras because the multiplication + table is in terms of the generator indices. + + SETUP:: + + sage: from mjo.eja.eja_algebra import random_eja + + TESTS:: + + sage: J1 = random_eja(field=QQ, orthonormalize=False) + sage: J2 = random_eja(field=QQ, orthonormalize=False) + sage: J = cartesian_product([J1,J2]) + sage: all( J.monomial(m) + ....: == + ....: J.gens()[J._monomial_to_generator(m)] + ....: for m in J.basis().keys() ) + True + + """ + # This works recursively so that we can handle Cartesian + # products of Cartesian products. + try: + # monomial is an ordered pair + factor = mon[0] + except TypeError: # 'int' object is not subscriptable + # base case where the monomials are integers + return mon + + idx_in_factor = self._monomial_to_generator(mon[1]) + + offset = sum( f.dimension() + for f in self.cartesian_factors()[:factor] ) + return offset + idx_in_factor + + def product_on_basis(self, i, j): + r""" + Return the product of the monomials indexed by ``i`` and ``j``. + + This overrides the superclass method because here, both ``i`` + and ``j`` will be ordered pairs. + + SETUP:: + + sage: from mjo.eja.eja_algebra import (HadamardEJA, + ....: JordanSpinEJA, + ....: QuaternionHermitianEJA, + ....: RealSymmetricEJA,) + + EXAMPLES:: + + sage: J1 = JordanSpinEJA(2, field=QQ) + sage: J2 = RealSymmetricEJA(2, field=QQ, orthonormalize=False) + sage: J3 = HadamardEJA(1, field=QQ) + sage: K1 = cartesian_product([J1,J2]) + sage: K2 = cartesian_product([K1,J3]) + sage: list(K2.basis()) + [e(0, (0, 0)), e(0, (0, 1)), e(0, (1, 0)), e(0, (1, 1)), + e(0, (1, 2)), e(1, 0)] + sage: g = K2.gens() + sage: (g[0] + 2*g[3]) * (g[1] - 4*g[2]) + e(0, (0, 1)) - 4*e(0, (1, 1)) + + TESTS:: + + sage: J1 = RealSymmetricEJA(1,field=QQ) + sage: J2 = QuaternionHermitianEJA(1,field=QQ) + sage: J = cartesian_product([J1,J2]) + sage: x = sum(J.gens()) + sage: x == J.one() + True + sage: x*x == x + True + + """ + l = self._monomial_to_generator(i) + m = self._monomial_to_generator(j) + return FiniteDimensionalEJA.product_on_basis(self, l, m) + def matrix_space(self): r""" Return the space that our matrix basis lives in as a Cartesian @@ -3449,3 +3556,16 @@ class RationalBasisCartesianProductEJA(CartesianProductEJA, RationalBasisEJA.CartesianProduct = RationalBasisCartesianProductEJA random_eja = ConcreteEJA.random_instance + +# def random_eja(*args, **kwargs): +# J1 = ConcreteEJA.random_instance(*args, **kwargs) + +# # This might make Cartesian products appear roughly as often as +# # any other ConcreteEJA. +# if ZZ.random_element(len(ConcreteEJA.__subclasses__()) + 1) == 0: +# # Use random_eja() again so we can get more than two factors. +# J2 = random_eja(*args, **kwargs) +# J = cartesian_product([J1,J2]) +# return J +# else: +# return J1