Path: blob/master/sage/algebras/free_algebra_quotient.py
4146 views
"""1Free algebra quotients23TESTS::45sage: n = 26sage: A = FreeAlgebra(QQ,n,'x')7sage: F = A.monoid()8sage: i, j = F.gens()9sage: mons = [ F(1), i, j, i*j ]10sage: r = len(mons)11sage: M = MatrixSpace(QQ,r)12sage: 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]) ]13sage: H2.<i,j> = A.quotient(mons,mats)14sage: H2 == loads(dumps(H2))15True16sage: i == loads(dumps(i))17True18"""1920#*****************************************************************************21# Copyright (C) 2005 David Kohel <[email protected]>22#23# Distributed under the terms of the GNU General Public License (GPL)24#25# This code is distributed in the hope that it will be useful,26# but WITHOUT ANY WARRANTY; without even the implied warranty27# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.28#29# See the GNU General Public License for more details; the full text30# is available at:31#32# http://www.gnu.org/licenses/33#*****************************************************************************3435from sage.modules.free_module import FreeModule36from sage.algebras.algebra import Algebra37from sage.algebras.free_algebra import is_FreeAlgebra38from sage.algebras.free_algebra_quotient_element import FreeAlgebraQuotientElement39from sage.structure.parent_gens import ParentWithGens40from sage.structure.unique_representation import UniqueRepresentation4142class FreeAlgebraQuotient(UniqueRepresentation, Algebra, object):43@staticmethod44def __classcall__(cls, A, mons, mats, names):45"""46Used to support unique representation.4748EXAMPLES::4950sage: H = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0] # indirect doctest51sage: H1 = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]52sage: H is H153True54"""55new_mats = []56for M in mats:57M = M.parent()(M)58M.set_immutable()59new_mats.append(M)60return super(FreeAlgebraQuotient, cls).__classcall__(cls, A, tuple(mons),61tuple(new_mats), tuple(names))6263Element = FreeAlgebraQuotientElement64def __init__(self, A, mons, mats, names):65"""66Returns a quotient algebra defined via the action of a free algebra67A on a (finitely generated) free module. The input for the quotient68algebra is a list of monomials (in the underlying monoid for A)69which form a free basis for the module of A, and a list of70matrices, which give the action of the free generators of A on this71monomial basis.7273EXAMPLES:7475Quaternion algebra defined in terms of three generators::7677sage: n = 378sage: A = FreeAlgebra(QQ,n,'i')79sage: F = A.monoid()80sage: i, j, k = F.gens()81sage: mons = [ F(1), i, j, k ]82sage: M = MatrixSpace(QQ,4)83sage: 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]) ]84sage: H3.<i,j,k> = FreeAlgebraQuotient(A,mons,mats)85sage: x = 1 + i + j + k86sage: x871 + i + j + k88sage: x**12889-170141183460469231731687303715884105728 + 170141183460469231731687303715884105728*i + 170141183460469231731687303715884105728*j + 170141183460469231731687303715884105728*k9091Same algebra defined in terms of two generators, with some penalty92on already slow arithmetic.9394::9596sage: n = 297sage: A = FreeAlgebra(QQ,n,'x')98sage: F = A.monoid()99sage: i, j = F.gens()100sage: mons = [ F(1), i, j, i*j ]101sage: r = len(mons)102sage: M = MatrixSpace(QQ,r)103sage: 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]) ]104sage: H2.<i,j> = A.quotient(mons,mats)105sage: k = i*j106sage: x = 1 + i + j + k107sage: x1081 + i + j + i*j109sage: x**128110-170141183460469231731687303715884105728 + 170141183460469231731687303715884105728*i + 170141183460469231731687303715884105728*j + 170141183460469231731687303715884105728*i*j111112TEST::113114sage: TestSuite(H2).run()115116"""117if not is_FreeAlgebra(A):118raise TypeError("Argument A must be an algebra.")119R = A.base_ring()120# if not R.is_field(): # TODO: why?121# raise TypeError, "Base ring of argument A must be a field."122n = A.ngens()123assert n == len(mats)124self.__free_algebra = A125self.__ngens = n126self.__dim = len(mons)127self.__module = FreeModule(R,self.__dim)128self.__matrix_action = mats129self.__monomial_basis = mons # elements of free monoid130Algebra.__init__(self, R, names, normalize=True)131132def __eq__(self, right):133"""134Return True if all defining properties of self and right match up.135136EXAMPLES::137138sage: HQ = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]139sage: HZ = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)[0]140sage: HQ == HQ141True142sage: HQ == HZ143False144sage: HZ == QQ145False146"""147return isinstance(right, FreeAlgebraQuotient) and \148self.ngens() == right.ngens() and \149self.rank() == right.rank() and \150self.module() == right.module() and \151self.matrix_action() == right.matrix_action() and \152self.monomial_basis() == right.monomial_basis()153154155def _element_constructor_(self, x):156"""157EXAMPLES::158159sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)160sage: H._element_constructor_(i) is i161True162sage: a = H._element_constructor_(1); a1631164sage: a in H165True166sage: a = H._element_constructor_([1,2,3,4]); a1671 + 2*i + 3*j + 4*k168"""169if isinstance(x, FreeAlgebraQuotientElement) and x.parent() is self:170return x171return self.element_class(self,x)172173def _coerce_map_from_(self,S):174"""175EXAMPLES::176177sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)178sage: H._coerce_map_from_(H)179True180sage: H._coerce_map_from_(QQ)181True182sage: H._coerce_map_from_(GF(7))183False184"""185return S==self or self.__free_algebra.has_coerce_map_from(S)186187def _repr_(self):188"""189EXAMPLES::190191sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)192sage: H._repr_()193"Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field"194"""195R = self.base_ring()196n = self.__ngens197r = self.__module.dimension()198x = self.variable_names()199return "Free algebra quotient on %s generators %s and dimension %s over %s"%(n,x,r,R)200201def gen(self, i):202"""203The i-th generator of the algebra.204205EXAMPLES::206207sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)208sage: H.gen(0)209i210sage: H.gen(2)211k212213An IndexError is raised if an invalid generator is requested::214215sage: H.gen(3)216Traceback (most recent call last):217...218IndexError: Argument i (= 3) must be between 0 and 2.219220Negative indexing into the generators is not supported::221222sage: H.gen(-1)223Traceback (most recent call last):224...225IndexError: Argument i (= -1) must be between 0 and 2.226"""227n = self.__ngens228if i < 0 or not i < n:229raise IndexError("Argument i (= %s) must be between 0 and %s."%(i, n-1))230R = self.base_ring()231F = self.__free_algebra.monoid()232n = self.__ngens233return self.element_class(self,{F.gen(i):R(1)})234235def ngens(self):236"""237The number of generators of the algebra.238239EXAMPLES::240241sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].ngens()2423243"""244return self.__ngens245246def dimension(self):247"""248The rank of the algebra (as a free module).249250EXAMPLES::251252sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].dimension()2534254"""255return self.__dim256257def matrix_action(self):258"""259EXAMPLES::260261sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].matrix_action()262(263[ 0 1 0 0] [ 0 0 1 0] [ 0 0 0 1]264[-1 0 0 0] [ 0 0 0 1] [ 0 0 -1 0]265[ 0 0 0 -1] [-1 0 0 0] [ 0 1 0 0]266[ 0 0 1 0], [ 0 -1 0 0], [-1 0 0 0]267)268"""269return self.__matrix_action270271def monomial_basis(self):272"""273EXAMPLES::274275sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monomial_basis()276(1, i0, i1, i2)277"""278return self.__monomial_basis279280def rank(self):281"""282The rank of the algebra (as a free module).283284EXAMPLES::285286sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].rank()2874288"""289return self.__dim290291def module(self):292"""293The free module of the algebra.294295sage: H = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]; H296Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field297sage: H.module()298Vector space of dimension 4 over Rational Field299"""300return self.__module301302def monoid(self):303"""304The free monoid of generators of the algebra.305306EXAMPLES::307308sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monoid()309Free monoid on 3 generators (i0, i1, i2)310"""311return self.__free_algebra.monoid()312313def monomial_basis(self):314"""315The free monoid of generators of the algebra as elements of a free316monoid.317318EXAMPLES::319320sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monomial_basis()321(1, i0, i1, i2)322"""323return self.__monomial_basis324325def free_algebra(self):326"""327The free algebra generating the algebra.328329EXAMPLES::330331sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].free_algebra()332Free Algebra on 3 generators (i0, i1, i2) over Rational Field333"""334return self.__free_algebra335336337def hamilton_quatalg(R):338"""339Hamilton quaternion algebra over the commutative ring R,340constructed as a free algebra quotient.341342INPUT:343- R -- a commutative ring344345OUTPUT:346- Q -- quaternion algebra347- gens -- generators for Q348349EXAMPLES::350351sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)352sage: H353Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Integer Ring354sage: i^2355-1356sage: i in H357True358359Note that there is another vastly more efficient models for360quaternion algebras in Sage; the one here is mainly for testing361purposes::362363sage: R.<i,j,k> = QuaternionAlgebra(QQ,-1,-1) # much fast than the above364"""365n = 3366from sage.algebras.free_algebra import FreeAlgebra367from sage.matrix.all import MatrixSpace368A = FreeAlgebra(R, n, 'i')369F = A.monoid()370i, j, k = F.gens()371mons = [ F(1), i, j, k ]372M = MatrixSpace(R,4)373mats = [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]) ]374H3 = FreeAlgebraQuotient(A,mons,mats, names=('i','j','k'))375return H3, H3.gens()376377378379