Path: blob/master/src/sage/algebras/free_algebra_quotient.py
8818 views
"""1Finite dimensional free algebra quotients23REMARK:45This implementation only works for finite dimensional quotients, since6a list of basis monomials and the multiplication matrices need to be7explicitly provided.89The homogeneous part of a quotient of a free algebra over a field by a10finitely generated homogeneous twosided ideal is available in a11different implementation. See12:mod:`~sage.algebras.letterplace.free_algebra_letterplace` and13:mod:`~sage.rings.quotient_ring`.1415TESTS::1617sage: n = 218sage: A = FreeAlgebra(QQ,n,'x')19sage: F = A.monoid()20sage: i, j = F.gens()21sage: mons = [ F(1), i, j, i*j ]22sage: r = len(mons)23sage: M = MatrixSpace(QQ,r)24sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ]25sage: H2.<i,j> = A.quotient(mons,mats)26sage: H2 == loads(dumps(H2))27True28sage: i == loads(dumps(i))29True30"""3132#*****************************************************************************33# Copyright (C) 2005 David Kohel <[email protected]>34#35# Distributed under the terms of the GNU General Public License (GPL)36#37# This code is distributed in the hope that it will be useful,38# but WITHOUT ANY WARRANTY; without even the implied warranty39# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.40#41# See the GNU General Public License for more details; the full text42# is available at:43#44# http://www.gnu.org/licenses/45#*****************************************************************************4647from sage.modules.free_module import FreeModule48from sage.algebras.algebra import Algebra49from sage.algebras.free_algebra import is_FreeAlgebra50from sage.algebras.free_algebra_quotient_element import FreeAlgebraQuotientElement51from sage.structure.parent_gens import ParentWithGens52from sage.structure.unique_representation import UniqueRepresentation5354class FreeAlgebraQuotient(UniqueRepresentation, Algebra, object):55@staticmethod56def __classcall__(cls, A, mons, mats, names):57"""58Used to support unique representation.5960EXAMPLES::6162sage: H = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0] # indirect doctest63sage: H1 = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]64sage: H is H165True66"""67new_mats = []68for M in mats:69M = M.parent()(M)70M.set_immutable()71new_mats.append(M)72return super(FreeAlgebraQuotient, cls).__classcall__(cls, A, tuple(mons),73tuple(new_mats), tuple(names))7475Element = FreeAlgebraQuotientElement76def __init__(self, A, mons, mats, names):77"""78Returns a quotient algebra defined via the action of a free algebra79A on a (finitely generated) free module. The input for the quotient80algebra is a list of monomials (in the underlying monoid for A)81which form a free basis for the module of A, and a list of82matrices, which give the action of the free generators of A on this83monomial basis.8485EXAMPLES:8687Quaternion algebra defined in terms of three generators::8889sage: n = 390sage: A = FreeAlgebra(QQ,n,'i')91sage: F = A.monoid()92sage: i, j, k = F.gens()93sage: mons = [ F(1), i, j, k ]94sage: M = MatrixSpace(QQ,4)95sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]), M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ]96sage: H3.<i,j,k> = FreeAlgebraQuotient(A,mons,mats)97sage: x = 1 + i + j + k98sage: x991 + i + j + k100sage: x**128101-170141183460469231731687303715884105728 + 170141183460469231731687303715884105728*i + 170141183460469231731687303715884105728*j + 170141183460469231731687303715884105728*k102103Same algebra defined in terms of two generators, with some penalty104on already slow arithmetic.105106::107108sage: n = 2109sage: A = FreeAlgebra(QQ,n,'x')110sage: F = A.monoid()111sage: i, j = F.gens()112sage: mons = [ F(1), i, j, i*j ]113sage: r = len(mons)114sage: M = MatrixSpace(QQ,r)115sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ]116sage: H2.<i,j> = A.quotient(mons,mats)117sage: k = i*j118sage: x = 1 + i + j + k119sage: x1201 + i + j + i*j121sage: x**128122-170141183460469231731687303715884105728 + 170141183460469231731687303715884105728*i + 170141183460469231731687303715884105728*j + 170141183460469231731687303715884105728*i*j123124TEST::125126sage: TestSuite(H2).run()127128"""129if not is_FreeAlgebra(A):130raise TypeError("Argument A must be an algebra.")131R = A.base_ring()132# if not R.is_field(): # TODO: why?133# raise TypeError, "Base ring of argument A must be a field."134n = A.ngens()135assert n == len(mats)136self.__free_algebra = A137self.__ngens = n138self.__dim = len(mons)139self.__module = FreeModule(R,self.__dim)140self.__matrix_action = mats141self.__monomial_basis = mons # elements of free monoid142Algebra.__init__(self, R, names, normalize=True)143144def __eq__(self, right):145"""146Return True if all defining properties of self and right match up.147148EXAMPLES::149150sage: HQ = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]151sage: HZ = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)[0]152sage: HQ == HQ153True154sage: HQ == HZ155False156sage: HZ == QQ157False158"""159return isinstance(right, FreeAlgebraQuotient) and \160self.ngens() == right.ngens() and \161self.rank() == right.rank() and \162self.module() == right.module() and \163self.matrix_action() == right.matrix_action() and \164self.monomial_basis() == right.monomial_basis()165166167def _element_constructor_(self, x):168"""169EXAMPLES::170171sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)172sage: H._element_constructor_(i) is i173True174sage: a = H._element_constructor_(1); a1751176sage: a in H177True178sage: a = H._element_constructor_([1,2,3,4]); a1791 + 2*i + 3*j + 4*k180"""181if isinstance(x, FreeAlgebraQuotientElement) and x.parent() is self:182return x183return self.element_class(self,x)184185def _coerce_map_from_(self,S):186"""187EXAMPLES::188189sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)190sage: H._coerce_map_from_(H)191True192sage: H._coerce_map_from_(QQ)193True194sage: H._coerce_map_from_(GF(7))195False196"""197return S==self or self.__free_algebra.has_coerce_map_from(S)198199def _repr_(self):200"""201EXAMPLES::202203sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)204sage: H._repr_()205"Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field"206"""207R = self.base_ring()208n = self.__ngens209r = self.__module.dimension()210x = self.variable_names()211return "Free algebra quotient on %s generators %s and dimension %s over %s"%(n,x,r,R)212213def gen(self, i):214"""215The i-th generator of the algebra.216217EXAMPLES::218219sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)220sage: H.gen(0)221i222sage: H.gen(2)223k224225An IndexError is raised if an invalid generator is requested::226227sage: H.gen(3)228Traceback (most recent call last):229...230IndexError: Argument i (= 3) must be between 0 and 2.231232Negative indexing into the generators is not supported::233234sage: H.gen(-1)235Traceback (most recent call last):236...237IndexError: Argument i (= -1) must be between 0 and 2.238"""239n = self.__ngens240if i < 0 or not i < n:241raise IndexError("Argument i (= %s) must be between 0 and %s."%(i, n-1))242R = self.base_ring()243F = self.__free_algebra.monoid()244n = self.__ngens245return self.element_class(self,{F.gen(i):R(1)})246247def ngens(self):248"""249The number of generators of the algebra.250251EXAMPLES::252253sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].ngens()2543255"""256return self.__ngens257258def dimension(self):259"""260The rank of the algebra (as a free module).261262EXAMPLES::263264sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].dimension()2654266"""267return self.__dim268269def matrix_action(self):270"""271EXAMPLES::272273sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].matrix_action()274(275[ 0 1 0 0] [ 0 0 1 0] [ 0 0 0 1]276[-1 0 0 0] [ 0 0 0 1] [ 0 0 -1 0]277[ 0 0 0 -1] [-1 0 0 0] [ 0 1 0 0]278[ 0 0 1 0], [ 0 -1 0 0], [-1 0 0 0]279)280"""281return self.__matrix_action282283def monomial_basis(self):284"""285EXAMPLES::286287sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monomial_basis()288(1, i0, i1, i2)289"""290return self.__monomial_basis291292def rank(self):293"""294The rank of the algebra (as a free module).295296EXAMPLES::297298sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].rank()2994300"""301return self.__dim302303def module(self):304"""305The free module of the algebra.306307sage: H = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]; H308Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field309sage: H.module()310Vector space of dimension 4 over Rational Field311"""312return self.__module313314def monoid(self):315"""316The free monoid of generators of the algebra.317318EXAMPLES::319320sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monoid()321Free monoid on 3 generators (i0, i1, i2)322"""323return self.__free_algebra.monoid()324325def monomial_basis(self):326"""327The free monoid of generators of the algebra as elements of a free328monoid.329330EXAMPLES::331332sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monomial_basis()333(1, i0, i1, i2)334"""335return self.__monomial_basis336337def free_algebra(self):338"""339The free algebra generating the algebra.340341EXAMPLES::342343sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].free_algebra()344Free Algebra on 3 generators (i0, i1, i2) over Rational Field345"""346return self.__free_algebra347348349def hamilton_quatalg(R):350"""351Hamilton quaternion algebra over the commutative ring R,352constructed as a free algebra quotient.353354INPUT:355- R -- a commutative ring356357OUTPUT:358- Q -- quaternion algebra359- gens -- generators for Q360361EXAMPLES::362363sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)364sage: H365Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Integer Ring366sage: i^2367-1368sage: i in H369True370371Note that there is another vastly more efficient models for372quaternion algebras in Sage; the one here is mainly for testing373purposes::374375sage: R.<i,j,k> = QuaternionAlgebra(QQ,-1,-1) # much fast than the above376"""377n = 3378from sage.algebras.free_algebra import FreeAlgebra379from sage.matrix.all import MatrixSpace380A = FreeAlgebra(R, n, 'i')381F = A.monoid()382i, j, k = F.gens()383mons = [ F(1), i, j, k ]384M = MatrixSpace(R,4)385mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]), M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]), M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ]386H3 = FreeAlgebraQuotient(A,mons,mats, names=('i','j','k'))387return H3, H3.gens()388389390391