Path: blob/master/src/sage/combinat/affine_permutation.py
8817 views
r"""1Affine Permutations2"""34#*****************************************************************************5# Copyright (C) 2013 Tom Denton <[email protected]>6#7# Distributed under the terms of the GNU General Public License (GPL)8# as published by the Free Software Foundation; either version 2 of9# the License, or (at your option) any later version.10# http://www.gnu.org/licenses/11#*****************************************************************************1213from sage.misc.cachefunc import cached_method14from sage.misc.misc_c import prod15from sage.misc.constant_function import ConstantFunction16from sage.misc.prandom import randint1718from sage.categories.affine_weyl_groups import AffineWeylGroups19from sage.structure.list_clone import ClonableArray20from sage.structure.unique_representation import UniqueRepresentation21from sage.structure.parent import Parent2223from sage.groups.perm_gps.permgroup_named import SymmetricGroup24from sage.rings.arith import binomial25from sage.combinat.root_system.cartan_type import CartanType26from sage.combinat.root_system.weyl_group import WeylGroup27from sage.combinat.composition import Composition28from sage.combinat.partition import Partition2930class AffinePermutation(ClonableArray):31r"""32An affine permutation, representated in the window notation, and33considered as a bijection from `\ZZ` to `\ZZ`.3435EXAMPLES::3637sage: A=AffinePermutationGroup(['A',7,1])38sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])39sage: p40Type A affine permutation with window [3, -1, 0, 6, 5, 4, 10, 9]41"""42def __init__(self, parent, lst, check=True):43r"""44Initialize ``self``4546INPUT:4748- ``parent`` -- The parent affine permutation group.4950- ``lst`` -- List giving the base window of the affine permutation.5152- ``check``-- Chooses whether to test that the affine permutation is legit.5354EXAMPLES::5556sage: A=AffinePermutationGroup(['A',7,1])57sage: p=A([3, -1, 0, 6, 5, 4, 10, 9]) #indirect doctest58sage: p59Type A affine permutation with window [3, -1, 0, 6, 5, 4, 10, 9]60"""61self._lst=lst62self.k=parent.k63self.n=self.k+164#This N doesn't matter for type A, but comes up in all other types.65if parent.cartan_type()[0]=='A':66self.N=self.n67elif parent.cartan_type()[0] in ['B', 'C', 'D']:68self.N=2*self.k+169elif parent.cartan_type()[0]=='G':70self.N=671else:72raise NotImplementedError, 'Unsupported Cartan Type.'73ClonableArray.__init__(self, parent, lst, check)7475def _repr_(self):76r"""77EXAMPLES::7879sage: A=AffinePermutationGroup(['A',7,1])80sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])81sage: p82Type A affine permutation with window [3, -1, 0, 6, 5, 4, 10, 9]83"""84return "Type "+ self.parent().cartan_type().letter +" affine permutation with window " + str([i for i in self])8586def __rmul__(self, q):87r"""88Given ``self`` and `q`, returns ``self*q``.8990INPUT:9192- ``q`` -- An element of ``self.parent()``9394EXAMPLES::9596sage: A=AffinePermutationGroup(['A',7,1])97sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])98sage: q=A([0, 2, 3, 4, 5, 6, 7, 9])99sage: p.__rmul__(q)100Type A affine permutation with window [1, -1, 0, 6, 5, 4, 10, 11]101"""102l=[self.value(q.value(i)) for i in xrange(1,len(self._lst)+1)]103return self.parent()(l, check=False)104105def __lmul__(self, q):106r"""107Given ``self`` and `q`, returns ``q*self``.108109INPUT:110111- ``q`` -- An element of ``self.parent()``112113EXAMPLES::114115sage: A=AffinePermutationGroup(['A',7,1])116sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])117sage: q=A([0,2,3,4,5,6,7,9])118sage: p.__lmul__(q)119Type A affine permutation with window [3, -1, 1, 6, 5, 4, 10, 8]120"""121#if self.parent().right_to_left:122# self,q=q,self123#... product rule124l=[q.value(self.value(i)) for i in xrange(1,len(self._lst)+1)]125return self.parent()(l, check=False)126127def __mul__(self, q):128r"""129Given ``self`` and `q`, returns ``self*q``.130131INPUT:132133- ``q`` -- An element of ``self.parent()``134135EXAMPLES::136137sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])138sage: s1=AffinePermutationGroup(['A',7,1]).one().apply_simple_reflection(1)139sage: p*s1140Type A affine permutation with window [-1, 3, 0, 6, 5, 4, 10, 9]141sage: p.apply_simple_reflection(1, 'right')142Type A affine permutation with window [-1, 3, 0, 6, 5, 4, 10, 9]143144"""145return self.__rmul__(q)146147@cached_method148def inverse(self):149r"""150Finds the inverse affine permutation.151152EXAMPLES::153154sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])155sage: p.inverse()156Type A affine permutation with window [0, -1, 1, 6, 5, 4, 10, 11]157"""158inv=[self.position(i) for i in xrange(1,len(self._lst)+1)]159return self.parent()(inv, check=False)160161__invert__=inverse162163def apply_simple_reflection(self, i, side='right'):164r"""165Applies a simple reflection.166167INPUT:168169- ``i`` -- an integer.170- ``side`` -- Determines whether to apply the reflection on the 'right' or 'left'. Default 'right'.171172EXAMPLES::173174sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])175sage: p.apply_simple_reflection(3)176Type A affine permutation with window [3, -1, 6, 0, 5, 4, 10, 9]177sage: p.apply_simple_reflection(11)178Type A affine permutation with window [3, -1, 6, 0, 5, 4, 10, 9]179sage: p.apply_simple_reflection(3, 'left')180Type A affine permutation with window [4, -1, 0, 6, 5, 3, 10, 9]181sage: p.apply_simple_reflection(11, 'left')182Type A affine permutation with window [4, -1, 0, 6, 5, 3, 10, 9]183"""184if side=='right':185return self.apply_simple_reflection_right(i)186if side=='left':187return self.apply_simple_reflection_left(i)188189def __call__(self, i):190r"""191Returns the image of the integer `i` under this permutation.192193EXAMPLES::194195sage: A=AffinePermutationGroup(['A',7,1])196sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])197sage: p.value(1) #indirect doctest1983199sage: p.value(9)20011201"""202return self.value(i)203204def is_i_grassmannian(self, i=0, side="right"):205r"""206Test whether ``self`` is `i`-grassmannian, ie, either is the identity or has207``i`` as the sole descent.208209INPUT:210211- ``i`` -- An element of the index set.212- ``side`` -- determines the side on which to check the descents.213214EXAMPLES::215216sage: A=AffinePermutationGroup(['A',7,1])217sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])218sage: p.is_i_grassmannian()219False220sage: q=A.from_word([3,2,1,0])221sage: q.is_i_grassmannian()222True223sage: q=A.from_word([2,3,4,5])224sage: q.is_i_grassmannian(5)225True226sage: q.is_i_grassmannian(2, side='left')227True228"""229if self==self.parent().one(): return True230if self.descents(side)==[i]: return True231return False232233def index_set(self):234r"""235Index set of the affine permutation group.236237EXAMPLES::238239sage: A=AffinePermutationGroup(['A',7,1])240sage: A.index_set()241(0, 1, 2, 3, 4, 5, 6, 7)242"""243return tuple(range(self.k+1))244245def lower_covers(self,side="right"):246r"""247Return lower covers of ``self``.248249The set of affine permutations of one less length related by250multiplication by a simple transposition on the indicated side.251These are the elements that ``self`` covers in weak order.252253EXAMPLES::254255sage: A=AffinePermutationGroup(['A',7,1])256sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])257sage: p.lower_covers()258[Type A affine permutation with window [-1, 3, 0, 6, 5, 4, 10, 9], Type A affine permutation with window [3, -1, 0, 5, 6, 4, 10, 9], Type A affine permutation with window [3, -1, 0, 6, 4, 5, 10, 9], Type A affine permutation with window [3, -1, 0, 6, 5, 4, 9, 10]]259260"""261S=self.descents(side)262return [self.apply_simple_reflection(i, side) for i in S]263264def is_one(self):265r"""266Tests whether the affine permutation is the identity.267268EXAMPLES::269270sage: A=AffinePermutationGroup(['A',7,1])271sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])272sage: p.is_one()273False274sage: q=A.one()275sage: q.is_one()276True277"""278return self==self.parent().one()279280def reduced_word(self):281r"""282Returns a reduced word for the affine permutation.283284EXAMPLES::285286sage: A=AffinePermutationGroup(['A',7,1])287sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])288sage: p.reduced_word()289[0, 7, 4, 1, 0, 7, 5, 4, 2, 1]290"""291#This is about 25% faster than the default algorithm.292x=self293i=0294word=[]295while not x.is_one():296if x.has_descent(i):297x=x.apply_simple_reflection_right(i)298word.append(i)299i=(i+1)%(self.k+1)300word.reverse()301return word302303def signature(self):304r"""305Signature of the affine permutation, `(-1)^l`, where `l` is the length of the permutation.306307EXAMPLES::308309sage: A=AffinePermutationGroup(['A',7,1])310sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])311sage: p.signature()3121313"""314return (-1)**self.length()315316@cached_method317def to_weyl_group_element(self):318r"""319The affine Weyl group element corresponding to the affine permutation.320321EXAMPLES::322323sage: A=AffinePermutationGroup(['A',7,1])324sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])325sage: p.to_weyl_group_element()326[ 0 -1 0 1 0 0 1 0]327[ 1 -1 0 1 0 0 1 -1]328[ 1 -1 0 1 0 0 0 0]329[ 0 0 0 1 0 0 0 0]330[ 0 0 0 1 0 -1 1 0]331[ 0 0 0 1 -1 0 1 0]332[ 0 0 0 0 0 0 1 0]333[ 0 -1 1 0 0 0 1 0]334"""335W=self.parent().weyl_group()336return W.from_reduced_word(self.reduced_word())337338def grassmannian_quotient(self, i=0, side='right'):339r"""340Return Grassmannian quotient.341342Factors ``self`` into a unique product of a Grassmannian and a finite-type343element. Returns a tuple containing the Grassmannain and finite344elements, in order according to side.345346INPUT:347348- ``i`` -- An element of the index set; the descent checked for. Defaults to 0.349350EXAMPLES::351352sage: A=AffinePermutationGroup(['A',7,1])353sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])354sage: gq=p.grassmannian_quotient()355sage: gq356(Type A affine permutation with window [-1, 0, 3, 4, 5, 6, 9, 10], Type A affine permutation with window [3, 1, 2, 6, 5, 4, 8, 7])357sage: gq[0].is_i_grassmannian()358True359sage: 0 not in gq[1].reduced_word()360True361sage: prod(gq)==p362True363364sage: gqLeft=p.grassmannian_quotient(side='left')365sage: 0 not in gqLeft[0].reduced_word()366True367sage: gqLeft[1].is_i_grassmannian(side='left')368True369sage: prod(gqLeft)==p370True371"""372fin=self.parent().one()373gr=self374D=gr.descents(side=side)375while not (D==[i] or D==[]):376m=D[0]377if m==i: m=D[1]378if side=='right':379fin=fin.apply_simple_reflection(m, side='left')380gr =gr.apply_simple_reflection(m, side='right')381else:382fin=fin.apply_simple_reflection(m, side='right')383gr =gr.apply_simple_reflection(m, side='left')384D=gr.descents(side=side)385if side=='right':386return (gr, fin)387else:388return (fin, gr)389390391392class AffinePermutationTypeA(AffinePermutation):393#----------------------394#Type-specific methods.395#(Methods existing in all types, but with type-specific definition.)396#----------------------397def check(self):398r"""399Check that ``self`` is an affine permutation.400401EXAMPLES::402403sage: A=AffinePermutationGroup(['A',7,1])404sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])405sage: p406Type A affine permutation with window [3, -1, 0, 6, 5, 4, 10, 9]407sage: q=A([1,2,3])408Traceback (most recent call last):409...410ValueError: Length of list must be k+1=8.411sage: q=A([1,2,3,4,5,6,7,0])412Traceback (most recent call last):413...414ValueError: Window does not sum to 36.415sage: q=A([1,1,3,4,5,6,7,9])416Traceback (most recent call last):417...418ValueError: Entries must have distinct residues.419"""420if not self:421return422k=self.parent().k423#Type A.424if not len(self)==k+1: raise ValueError("Length of list must be k+1="+str(k+1)+".")425if not (binomial(k+2,2) == sum(self)): raise ValueError("Window does not sum to "+str(binomial((k+2),2))+".")426l=[i%(k+1) for i in self]427l.sort()428if not l == range(k+1): raise ValueError("Entries must have distinct residues.")429430431def value(self, i, base_window=False):432r"""433Return the image of the integer ``i`` under this permutation.434435INPUT:436437- ``base_window`` -- a Boolean, indicating whether `i` is in the base window.438If True, will run a bit faster, but the method will screw up if `i` is not439actually in the index set.440441EXAMPLES::442443sage: A=AffinePermutationGroup(['A',7,1])444sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])445sage: p.value(1)4463447sage: p.value(9)44811449"""450if base_window: self[i-1]451window=(i-1)//(self.k+1)452return self[(i-1)%(self.k+1)]+window*(self.k+1)453454def position(self, i):455r"""456Find the position `j` such the ``self.value(j)=i``457458EXAMPLES::459460sage: A=AffinePermutationGroup(['A',7,1])461sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])462sage: p.position(3)4631464sage: p.position(11)4659466"""467for r in xrange(self.k+1):468if (self[r]%(self.k+1))==i%(self.k+1):469#i sits in position i, but some number of windows away.470diff=(i-self[r])//(self.k+1)471return r+diff*(self.k+1)+1472return False473474def apply_simple_reflection_right(self, i):475r"""476Applies the simple reflection to positions `i`, `i+1`.477`i` is allowed to be any integer.478479EXAMPLES::480481sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])482sage: p.apply_simple_reflection_right(3)483Type A affine permutation with window [3, -1, 6, 0, 5, 4, 10, 9]484sage: p.apply_simple_reflection_right(11)485Type A affine permutation with window [3, -1, 6, 0, 5, 4, 10, 9]486"""487j=i%(self.k+1)488#Cloning is currently kinda broken, in that caches don't clear which489#leads to strangeness with the cloned object.490#The clone approach is quite a bit (2x) faster, though, so this should491#switch once the caching situation is fixed.492#with self.clone(check=False) as l:493l = self[:]494if j==0:495a = l[0]496l[0] = l[-1] - (self.k+1)497l[-1] = a +(self.k+1)498else:499a = l[j-1]500l[j-1] = l[j]501l[j] = a502#return l503return self.parent()(l,check=False)504505def apply_simple_reflection_left(self, i):506r"""507Applies simple reflection to the values `i`, `i+1`.508509EXAMPLES::510511sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])512sage: p.apply_simple_reflection_left(3)513Type A affine permutation with window [4, -1, 0, 6, 5, 3, 10, 9]514sage: p.apply_simple_reflection_left(11)515Type A affine permutation with window [4, -1, 0, 6, 5, 3, 10, 9]516"""517#Here are a couple other methods we tried out, but turned out518#to be slower than the current implementation.519#1) This one was very bad:520# return self.inverse().apply_simple_reflection_right(i).inverse()521#2) Also bad, though not quite so bad:522# return (self.parent().simple_reflection(i))*self523i=i%(self.k+1)524#Cloning is currently kinda broken, in that caches don't clear which525#leads to strangeness with the cloned object.526#The clone approach is quite a bit faster, though, so this should switch527#once the caching situation is fixed.528#with self.clone(check=False) as l:529l=[]530if i!=self.k:531for m in xrange(self.k+1):532res=self[m]%(self.k+1)533if res==i :534l.append(self[m]+1)535elif res==i+1:536l.append(self[m]-1)537else:538l.append(self[m])539if i==self.k:540for m in xrange(self.k+1):541res=self[m]%(self.k+1)542if res==i :543l.append(self[m]+1)544elif res==0:545l.append(self[m]-1)546else:547l.append(self[m])548return self.parent()(l, check=False)549550def has_right_descent(self, i):551r"""552Determines whether there is a descent at `i`.553554INPUT:555556- ``i`` -- an integer.557558EXAMPLES::559560sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])561sage: p.has_right_descent(1)562True563sage: p.has_right_descent(9)564True565sage: p.has_right_descent(0)566False567"""568return self.value(i)>self.value(i+1)569570def has_left_descent(self, i):571r"""572Determines whether there is a descent at `i`.573574INPUT:575576- ``i`` -- an integer.577578EXAMPLES::579580sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])581sage: p.has_left_descent(1)582True583sage: p.has_left_descent(9)584True585sage: p.has_left_descent(0)586True587"""588#This is much faster thant he default method of taking the inverse and589#then finding right descents...590return self.position(i)>self.position(i+1)591592def to_type_a(self):593r"""594Returns an embedding of ``self`` into the affine permutation group of595type A. (For Type `A`, just returns self.)596597EXAMPLES::598599sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])600sage: p.to_type_a()==p601True602"""603return self604605#----------------------606#Type-A-specific methods.607#Only available in Type A.608#----------------------609610def flip_automorphism(self):611r"""612The Dynkin diagram automorphism which fixes `s_0` and reverses all613other indices.614615EXAMPLES::616617sage: A=AffinePermutationGroup(['A',7,1])618sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])619sage: p.flip_automorphism()620Type A affine permutation with window [0, -1, 5, 4, 3, 9, 10, 6]621"""622#Note: There should be a more combinatorial (ie, faster) way to do this.623w=[(self.k+1-i)%(self.k+1) for i in self.reduced_word()]624return self.parent().from_word(w)625626def promotion(self):627r"""628The Dynkin diagram automorphism which sends `s_i` to `s_{i+1}`.629630EXAMPLES::631632sage: A=AffinePermutationGroup(['A',7,1])633sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])634sage: p.promotion()635Type A affine permutation with window [2, 4, 0, 1, 7, 6, 5, 11]636"""637l=[]638l.append(self._lst[-1]-self.k)639for i in xrange(1,self.k+1):640l.append(self._lst[i-1]+1)641return self.parent()(l)642643def maximal_cyclic_factor(self, typ='decreasing', side='right', verbose=False):644r"""645For an affine permutation `x`, finds the unique maximal subset `A`646of the index set such that `x=yd_A` is a reduced product.647648INPUT:649650- ``typ`` -- 'increasing' or 'decreasing.' Determines the type of651maximal cyclic element found.652653- ``side`` -- 'right' or 'left'.654655- ``verbose`` -- True or False. If True, outputs information about how656the cyclically increasing element was found.657658EXAMPLES::659660sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])661sage: p.maximal_cyclic_factor()662[7, 5, 4, 2, 1]663sage: p.maximal_cyclic_factor(side='left')664[1, 0, 7, 5, 4]665sage: p.maximal_cyclic_factor('increasing','right')666[4, 5, 7, 0, 1]667sage: p.maximal_cyclic_factor('increasing','left')668[0, 1, 2, 4, 5]669"""670k=self.k671if side[0]=='r':672Descents=self.descents(side='right')673side='right'674else:675Descents=self.descents(side='left')676side='left'677#for now, assume side is 'right')678best_T=[]679for i in Descents:680y=self.clone().apply_simple_reflection(i,side)681T=[i]682j=i683for count in xrange(1,self.k):684if (typ[0],side[0])==('d','r'): j=(j+1)%(k+1)685if (typ[0],side[0])==('i','r'): j=(j-1)%(k+1)686if (typ[0],side[0])==('d','l'): j=(j-1)%(k+1)687if (typ[0],side[0])==('i','l'): j=(j+1)%(k+1)688if y.has_descent(j, side):689y=y.apply_simple_reflection(j,side)690T.append(j%(k+1))691if verbose:692print i, T693if len(T)>len(best_T):694best_T=T695#if (typ[0],side[0])==('i','r'): best_T.reverse()696#if (typ[0],side[0])==('d','l'): best_T.reverse()697#if typ[0]=='d': best_T.reverse()698if side[0]=='r': best_T.reverse()699return best_T700701702def maximal_cyclic_decomposition(self, typ='decreasing', side='right', verbose=False):703r"""704Finds the unique maximal decomposition of ``self`` into cyclically705decreasing/increasing elements.706707INPUT:708709- ``typ`` -- 'increasing' or 'decreasing' (default: 'decreasing'.)710Chooses whether to find increasing or deacreasing sets.711712- ``side`` -- 'right' or 'left' (default: 'right'.) Chooses whether to713find maximal sets starting from the left or the right.714715- ``verbose`` -- Print extra information while finding the decomposition.716717EXAMPLES::718719sage: p=AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])720sage: p.maximal_cyclic_decomposition()721[[0, 7], [4, 1, 0], [7, 5, 4, 2, 1]]722sage: p.maximal_cyclic_decomposition(side='left')723[[1, 0, 7, 5, 4], [1, 0, 5], [2, 1]]724sage: p.maximal_cyclic_decomposition(typ='increasing', side='right')725[[1], [5, 0, 1, 2], [4, 5, 7, 0, 1]]726sage: p.maximal_cyclic_decomposition(typ='increasing', side='left')727[[0, 1, 2, 4, 5], [4, 7, 0, 1], [7]]728729TESTS::730731sage: A=AffinePermutationGroup(['A',7,1])732sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])733sage: S=p.maximal_cyclic_decomposition()734sage: p==prod(A.from_word(l) for l in S)735True736sage: S=p.maximal_cyclic_decomposition(typ='increasing', side='left')737sage: p==prod(A.from_word(l) for l in S)738True739sage: S=p.maximal_cyclic_decomposition(typ='increasing', side='right')740sage: p==prod(A.from_word(l) for l in S)741True742sage: S=p.maximal_cyclic_decomposition(typ='decreasing', side='right')743sage: p==prod(A.from_word(l) for l in S)744True745"""746y=self.clone()747listy=[]748if verbose: print 'length of x:', self.length()749while not y.is_one():750S=y.maximal_cyclic_factor(typ, side, verbose)751listy.append(S[:])752if side[0]=='r': S.reverse()753for i in S:754if side[0]=='r':755y=y.apply_simple_reflection_right(i)756else:757y=y.apply_simple_reflection_left(i)758if verbose: print S, y.length()759if side[0]=='r': listy.reverse()760return listy761762def to_lehmer_code(self, typ='decreasing', side='right'):763r"""764Returns the affine Lehmer code.765766There are four such codes; the options ``typ`` and ``side`` determine which767code is generated. The codes generated are the shape of the maximal768cyclic decompositions of ``self`` according to the given ``typ`` and ``side``769options.770771INPUT:772773- ``typ`` -- 'increasing' or 'decreasing' (default: 'decreasing'.)774Chooses whether to find increasing or deacreasing sets.775776- ``side`` -- 'right' or 'left' (default: 'right'.) Chooses whether to777find maximal sets starting from the left or the right.778779EXAMPLES::780781sage: A=AffinePermutationGroup(['A',7,1])782sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])783sage: CP=CartesianProduct( ('increasing','decreasing'),('left','right') )784sage: for a in CP:785....: p.to_lehmer_code(a[0],a[1])786[2, 3, 2, 0, 1, 2, 0, 0]787[2, 2, 0, 0, 2, 1, 0, 3]788[3, 1, 0, 0, 2, 1, 0, 3]789[0, 3, 3, 0, 1, 2, 0, 1]790sage: for a in CP:791....: A.from_lehmer_code(p.to_lehmer_code(a[0],a[1]), a[0],a[1])==p792True793True794True795True796"""797code=[0 for i in xrange(0,self.k+1)]798if typ[0]=='i' and side[0]=='r':799#Find number of positions to the right of position i with smaller800#value than the number in position i.801for i in xrange(0,self.k+1):802a=self(i)803for j in xrange(i+1, i+self.k+1):804b=self(j)805if b<a: code[i]+=((a-b)//(self.k+1)+1)806if typ[0]=='d' and side[0]=='r':807#Find number of positions to the left of position i with larger808#value than the number in position i. Then cyclically shift809#the resulting vector.810for i in xrange(0,self.k+1):811a=self(i)812for j in xrange(i-self.k, i):813b=self(j)814#A small rotation is necessary for the reduced word from815#the lehmer code to match the element.816if a<b: code[i-1]+=((b-a)//(self.k+1)+1)817if typ[0]=='i' and side[0]=='l':818#Find number of positions to the right of i smaller than i, then819#cyclically shift the resulting vector.820for i in xrange(0,self.k+1):821pos=self.position(i)822for j in xrange(pos+1, pos+self.k+1):823b=self(j)824#A small rotation is necessary for the reduced word from825#the lehmer code to match the element.826if b<i: code[i-1]+=((i-b)//(self.k+1)+1)827if typ[0]=='d' and side[0]=='l':828#Find number of positions to the left of i larger than i.829for i in xrange(0,self.k+1):830pos=self.position(i)831for j in xrange(pos-self.k, pos):832b=self(j)833if b>i: code[i]+=((b-i)//(self.k+1)+1)834return Composition(code)835836def is_fully_commutative(self):837r"""838Determines whether ``self`` is fully commutative, ie, has no reduced words839with a braid.840841EXAMPLES::842843sage: A=AffinePermutationGroup(['A',7,1])844sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])845sage: p.is_fully_commutative()846False847sage: q=A([-3, -2, 0, 7, 9, 2, 11, 12])848sage: q.is_fully_commutative()849True850"""851if self==self.parent().one(): return True852c=self.to_lehmer_code()853firstnonzero=None854m=-1855for i in range(self.n):856if c[i]>0:857if firstnonzero==None: firstnonzero=i858if m!=-1 and c[i]-(i-m) >= c[m]: return False859m=i860#now check m (the last non-zero) against firstnonzero.861d=self.n-(m-firstnonzero)862if c[firstnonzero]-d >= c[m]: return False863return True864865def to_bounded_partition(self, typ='decreasing', side='right'):866r"""867Returns the `k`-bounded partition associated to the dominant element868obtained by sorting the Lehmer code.869870INPUT:871872- ``typ`` -- 'increasing' or 'decreasing' (default: 'decreasing'.)873Chooses whether to find increasing or deacreasing sets.874875- ``side`` -- 'right' or 'left' (default: 'right'.) Chooses whether to876find maximal sets starting from the left or the right.877878EXAMPLES::879880sage: A=AffinePermutationGroup(['A',2,1])881sage: p=A.from_lehmer_code([4,1,0])882sage: p.to_bounded_partition()883[2, 1, 1, 1]884"""885c=list(self.to_lehmer_code(typ,side))886c.sort()887c.reverse()888return Partition(c).conjugate()889890def to_core(self, typ='decreasing', side='right'):891r"""892Returns the core associated to the dominant element obtained by sorting893the Lehmer code.894895INPUT:896897- ``typ`` -- 'increasing' or 'decreasing' (default: 'decreasing'.)898899- ``side`` -- 'right' or 'left' (default: 'right'.) Chooses whether to900find maximal sets starting from the left or the right.901902EXAMPLES::903904sage: A=AffinePermutationGroup(['A',2,1])905sage: p=A.from_lehmer_code([4,1,0])906sage: p.to_bounded_partition()907[2, 1, 1, 1]908sage: p.to_core()909[4, 2, 1, 1]910"""911return self.to_bounded_partition(typ,side).to_core(self.k)912913def to_dominant(self, typ='decreasing', side='right'):914r"""915Finds the Lehmer code and then sorts it. Returns the affine permutation916with the given sorted Lehmer code; this element is 0-dominant.917918INPUT:919920- ``typ`` -- 'increasing' or 'decreasing' (default: 'decreasing'.)921Chooses whether to find increasing or deacreasing sets.922923- ``side`` -- 'right' or 'left' (default: 'right'.) Chooses whether to924find maximal sets starting from the left or the right.925926EXAMPLES::927928sage: A=AffinePermutationGroup(['A',7,1])929sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])930sage: p.to_dominant()931Type A affine permutation with window [-2, -1, 1, 3, 4, 8, 10, 13]932sage: p.to_dominant(typ='increasing', side='left')933Type A affine permutation with window [3, 4, -1, 5, 0, 9, 6, 10]934"""935if self.is_i_grassmannian(side=side): return self936c=list(self.to_lehmer_code(typ,side))937c.sort()938c.reverse()939return self.parent().from_lehmer_code(c, typ, side)940941def tableau_of_word(self, w, typ='decreasing', side='right', alpha=None):942r"""943Finds a tableau on the Lehmer code of ``self`` corresponding to the given944reduced word.945946For a full description of this algorithm, see [D2012]_.947948INPUT:949950- ``w`` -- a reduced word for self.951- ``typ`` -- 'increasing' or 'decreasing.' The type of Lehmer code used.952- ``side`` -- 'right' or 'left.'953- ``alpha`` -- A content vector. w should be of type alpha. Specifying954alpha produces semistandard tableaux.955956REFERENCES:957958.. [D2012] tom denton. Canonical Decompositions of Affine Permutations,959Affine Codes, and Split `k`-Schur Functions. Electronic Journal of960Combinatorics, 2012.961962EXAMPLES::963964sage: A=AffinePermutationGroup(['A',7,1])965sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])966sage: p.tableau_of_word(p.reduced_word())967[[], [1, 6, 9], [2, 7, 10], [], [3], [4, 8], [], [5]]968sage: A=AffinePermutationGroup(['A',7,1])969sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])970sage: w=p.reduced_word()971sage: w972[0, 7, 4, 1, 0, 7, 5, 4, 2, 1]973sage: alpha=[5,3,2]974sage: p.tableau_of_word(p.reduced_word(), alpha=alpha)975[[], [1, 2, 3], [1, 2, 3], [], [1], [1, 2], [], [1]]976sage: p.tableau_of_word(p.reduced_word(), side='left')977[[1, 4, 9], [6], [], [], [3, 7], [8], [], [2, 5, 10]]978sage: p.tableau_of_word(p.reduced_word(), typ='increasing', side='right')979[[9, 10], [1, 2], [], [], [3, 4], [8], [], [5, 6, 7]]980sage: p.tableau_of_word(p.reduced_word(), typ='increasing', side='left')981[[1, 2], [4, 5, 6], [9, 10], [], [3], [7, 8], [], []]982"""983g=self.parent().simple_reflections()984#check w is reduced....:should probably throw an exception otherwise.985x0=prod([g[i] for i in w])986if x0.length()!=len(w): raise ValueError("Word was not reduced.")987if alpha==None:988alpha=Composition([1 for i in w])989else:990if sum(alpha)!=len(w): raise ValueError("Size of alpha must match length of w.")991alpha=Composition(alpha)992#TODO: We should probably check that w is of type alpha! probably a different function.993#Now we actually build the recording tableau.994tab=[ [] for i in xrange(self.k+1) ]995label=1996al_index=0997j=0998x=self.parent().one()999cx=x.to_lehmer_code(typ, side)1000n=len(w)-11001for i in xrange(len(w)):1002if side[0]=='r':1003#y=g[w[n-i]]*x1004y=x.apply_simple_reflection_left(w[n-i])1005else:1006y=x.apply_simple_reflection_right(w[i])1007cy=y.to_lehmer_code(typ, side)1008for r in xrange(self.k+1):1009if cy[r]>cx[r]:1010tab[r].append(label)1011j+=11012if j==alpha[al_index]:1013al_index+=11014j=01015label+=11016break1017x=y1018cx=cy1019return tab10201021#-------------------------------------------------------------------------------1022class AffinePermutationTypeC(AffinePermutation):1023#----------------------1024#Type-specific methods.1025#(Methods existing in all types, but with type-specific definition.)1026#----------------------1027def check(self):1028r"""1029Check that ``self`` is an affine permutation.10301031EXAMPLES::10321033sage: C=AffinePermutationGroup(['C',4,1])1034sage: x=C([-1,5,3,7])1035sage: x1036Type C affine permutation with window [-1, 5, 3, 7]1037"""1038if not self:1039return1040k=self.parent().k1041if not len(self)==k: raise ValueError( "Length of list must be k="+str(k)+".")1042reslist=[]1043for i in self:1044r=i%self.N1045if r==0: raise ValueError( "Entries may not have residue 0 mod 2k+1.")1046if not (r not in reslist and self.N-r not in reslist): raise ValueError( "Entries must have distinct residues.")1047reslist.append(r)10481049def value(self, i):1050r"""1051Returns the image of the integer `i` under this permutation.10521053EXAMPLES::10541055sage: C=AffinePermutationGroup(['C',4,1])1056sage: x=C.one()1057sage: [x.value(i) for i in range(-10,10)]==range(-10,10)1058True1059"""1060N=(2*self.k+1)1061window=i//N1062index=i%N1063if index==0: return i1064if index<=self.k:1065return self[index-1]+window*N1066if index>self.k:1067return -(self[N-index-1]-N)+window*N10681069def position(self, i):1070r"""1071Find the position `j` such the ``self.value(j)=i``10721073EXAMPLES::10741075sage: C=AffinePermutationGroup(['C',4,1])1076sage: x=C.one()1077sage: [x.position(i) for i in range(-10,10)]==range(-10,10)1078True1079"""1080N=(2*self.k+1)1081index=i%N1082if index==0: return i1083for r in xrange(len(self)):1084if (self[r]%N)==index:1085#i sits in position i, but some number of windows away.1086diff=(i-self[r])//N1087return r+diff*N+11088if (self[r]%N)==N-index:1089#then we sit some number of windows from position -r.1090diff=(i+self[r])//N1091return -r+diff*N-11092return False10931094def apply_simple_reflection_right(self, i):1095r"""1096Applies the simple reflection indexed by `i` on positions.10971098EXAMPLES::10991100sage: C=AffinePermutationGroup(['C',4,1])1101sage: x=C([-1,5,3,7])1102sage: for i in C.index_set(): x.apply_simple_reflection_right(i)1103Type C affine permutation with window [1, 5, 3, 7]1104Type C affine permutation with window [5, -1, 3, 7]1105Type C affine permutation with window [-1, 3, 5, 7]1106Type C affine permutation with window [-1, 5, 7, 3]1107Type C affine permutation with window [-1, 5, 3, 2]1108"""1109if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1110j=i1111l = self[:]1112if j!=0 and j!=self.k:1113a = l[j-1]1114l[j-1] = l[j]1115l[j] = a1116if j==0:1117l[0]=-l[0]1118if j==self.k:1119l[self.k-1]=self(self.k+1)1120#return l1121return self.parent()(l,check=False)11221123def apply_simple_reflection_left(self, i):1124r"""1125Applies simple reflection indexed by `i` on values.11261127EXAMPLES::11281129sage: C=AffinePermutationGroup(['C',4,1])1130sage: x=C([-1,5,3,7])1131sage: for i in C.index_set(): x.apply_simple_reflection_left(i)1132Type C affine permutation with window [1, 5, 3, 7]1133Type C affine permutation with window [-2, 5, 3, 8]1134Type C affine permutation with window [-1, 5, 2, 6]1135Type C affine permutation with window [-1, 6, 4, 7]1136Type C affine permutation with window [-1, 4, 3, 7]1137"""1138if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1139j=self.N-i1140l=[]1141if i!=self.k and i!=0:1142for m in xrange(self.k):1143res=self[m]%self.N1144if res==i :1145l.append(self[m]+1)1146elif res==i+1:1147l.append(self[m]-1)1148elif res==j:1149l.append(self[m]-1)1150elif res==j-1:1151l.append(self[m]+1)1152else:1153l.append(self[m])1154elif i==0:1155for m in xrange(self.k):1156res=self[m]%self.N1157if res==1:1158l.append(self[m]-2)1159elif res==self.N-1:1160l.append(self[m]+2)1161else:1162l.append(self[m])1163elif i==self.k:1164for m in xrange(self.k):1165res=self[m]%self.N1166if res==i:1167l.append(self[m]+1)1168elif res==j:1169l.append(self[m]-1)1170else:1171l.append(self[m])1172return self.parent()(l, check=False)11731174def has_right_descent(self, i):1175r"""1176Determines whether there is a descent at index `i`.11771178INPUT:11791180- ``i`` -- an integer.11811182EXAMPLES::11831184sage: C=AffinePermutationGroup(['C',4,1])1185sage: x=C([-1,5,3,7])1186sage: for i in C.index_set(): x.has_right_descent(i)1187True1188False1189True1190False1191True1192"""1193return self.value(i)>self.value(i+1)11941195def has_left_descent(self, i):1196r"""1197Determines whether there is a descent at `i`.11981199INPUT:12001201- ``i`` -- an integer.12021203EXAMPLES::12041205sage: C=AffinePermutationGroup(['C',4,1])1206sage: x=C([-1,5,3,7])1207sage: for i in C.index_set(): x.has_left_descent(i)1208True1209False1210True1211False1212True1213"""1214#This is much faster thant he default method of taking the inverse and1215#then finding right descents...1216return self.position(i)>self.position(i+1)12171218def to_type_a(self):1219r"""1220Returns an embedding of ``self`` into the affine permutation group of1221type `A`.12221223EXAMPLES::12241225sage: C=AffinePermutationGroup(['C',4,1])1226sage: x=C([-1,5,3,7])1227sage: x.to_type_a()1228Type A affine permutation with window [-1, 5, 3, 7, 2, 6, 4, 10, 9]1229"""1230A=AffinePermutationGroup(['A', self.N-1, 1])1231return A([self.value(i) for i in range(1,self.N+1)])123212331234class AffinePermutationTypeB(AffinePermutationTypeC):1235#----------------------1236#Type-specific methods.1237#(Methods existing in all types, but with type-specific definition.)1238#----------------------1239def check(self):1240r"""1241Check that ``self`` is an affine permutation.12421243EXAMPLES::12441245sage: B=AffinePermutationGroup(['B',4,1])1246sage: x=B([-5,1,6,-2])1247sage: x1248Type B affine permutation with window [-5, 1, 6, -2]1249"""1250if not self:1251return1252k=self.parent().k1253#Check window length.1254if not len(self)==k: raise ValueError( "Length of list must be k="+str(k)+".")1255#Check for repeated residues.1256reslist=[]1257for i in self:1258r=i%self.N1259if r==0: raise ValueError( "Entries may not have residue 0 mod 2k+1.")1260if not( r not in reslist and self.N-r not in reslist ): raise ValueError( "Entries must have distinct residues.")1261reslist.append(r)1262#Check that we have an even number of 'small' elements right of the zeroth entry.1263s=sum([-i//self.N+1 for i in [self.value(j) for j in range(1,self.N+1)] if i<0])1264if not s%2==0: raise ValueError( 'Type B affine permutations have an even number of entries less than 0 to the right of the 0th position.')126512661267def apply_simple_reflection_right(self, i):1268r"""1269Applies the simple reflection indexed by `i` on positions.12701271EXAMPLES::12721273sage: B=AffinePermutationGroup(['B',4,1])1274sage: p=B([-5,1,6,-2])1275sage: p.apply_simple_reflection_right(1)1276Type B affine permutation with window [1, -5, 6, -2]1277sage: p.apply_simple_reflection_right(0)1278Type B affine permutation with window [-1, 5, 6, -2]1279sage: p.apply_simple_reflection_right(4)1280Type B affine permutation with window [-5, 1, 6, 11]1281"""1282if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1283j=i1284l = self[:]1285if j!=0 and j!=self.k:1286#just swap l[j], l[j-1]1287(l[j-1],l[j])=(l[j],l[j-1])1288if j==0:1289l[0]=-self(2)1290l[1]=-self(1)1291if j==self.k:1292l[self.k-1]=self(self.k+1)1293#return l1294return self.parent()(l,check=False)12951296def apply_simple_reflection_left(self, i):1297r"""1298Applies simple reflection indexed by `i` on values.12991300EXAMPLES::13011302sage: B=AffinePermutationGroup(['B',4,1])1303sage: p=B([-5,1,6,-2])1304sage: p.apply_simple_reflection_left(0)1305Type B affine permutation with window [-5, -2, 6, 1]1306sage: p.apply_simple_reflection_left(2)1307Type B affine permutation with window [-5, 1, 7, -3]1308sage: p.apply_simple_reflection_left(4)1309Type B affine permutation with window [-4, 1, 6, -2]1310"""1311if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1312j=self.N-i1313l=[]1314if i!=self.k and i!=0:1315for m in xrange(self.k):1316res=self[m]%self.N1317if res==i :1318l.append(self[m]+1)1319elif res==i+1:1320l.append(self[m]-1)1321elif res==j:1322l.append(self[m]-1)1323elif res==j-1:1324l.append(self[m]+1)1325else:1326l.append(self[m])1327elif i==0:1328for m in xrange(self.k):1329res=self[m]%self.N1330if res==1:1331l.append(self[m]-3)1332elif res==self.N-2:1333l.append(self[m]+3)1334elif res==2:1335l.append(self[m]-3)1336elif res==self.N-1:1337l.append(self[m]+3)1338else:1339l.append(self[m])1340elif i==self.k:1341for m in xrange(self.k):1342res=self[m]%self.N1343if res==i:1344l.append(self[m]+1)1345elif res==j:1346l.append(self[m]-1)1347else:1348l.append(self[m])1349return self.parent()(l, check=False)13501351def has_right_descent(self, i):1352r"""1353Determines whether there is a descent at index `i`.13541355INPUT:13561357- ``i`` -- an integer.13581359EXAMPLES::13601361sage: B=AffinePermutationGroup(['B',4,1])1362sage: p=B([-5,1,6,-2])1363sage: [p.has_right_descent(i) for i in B.index_set()]1364[True, False, False, True, False]1365"""1366if i==0: return self.value(-2)>self.value(1)1367return self.value(i)>self.value(i+1)13681369def has_left_descent(self, i):1370r"""1371Determines whether there is a descent at `i`.13721373INPUT:13741375- ``i`` -- an integer.13761377EXAMPLES::13781379sage: B=AffinePermutationGroup(['B',4,1])1380sage: p=B([-5,1,6,-2])1381sage: [p.has_left_descent(i) for i in B.index_set()]1382[True, True, False, False, True]1383"""1384if i==0: return self.position(-2)>self.position(1)1385return self.position(i)>self.position(i+1)138613871388class AffinePermutationTypeD(AffinePermutationTypeC):1389#----------------------1390#Type-specific methods.1391#(Methods existing in all types, but with type-specific definition.)1392#----------------------1393def check(self):1394r"""1395Check that ``self`` is an affine permutation.13961397EXAMPLES::13981399sage: D=AffinePermutationGroup(['D',4,1])1400sage: p=D([1,-6,5,-2])1401sage: p1402Type D affine permutation with window [1, -6, 5, -2]1403"""1404if not self:1405return1406k=self.parent().k1407#Check window length.1408if len(self)!=k: raise ValueError( "Length of list must be k="+str(k)+".")1409#Check for repeated residues.1410reslist=[]1411for i in self:1412r=i%self.N1413if r==0: raise ValueError( "Entries may not have residue 0 mod 2k+1.")1414if not ( r not in reslist and self.N-r not in reslist ): raise ValueError( "Entries must have distinct residues.")1415reslist.append(r)1416#Check that we have an even number of 'big' elements left of the kth entry.1417s=sum([i//self.N+1-(i%self.N<=self.k) for i in [self.value(j) for j in range(-self.k,self.k+1)] if i>self.k])1418if not s%2==0: raise ValueError( 'Type D affine permutations have an even number of entries greater than x.k weakly to the left of the x.k position.')1419#Check that we have an even number of 'small' elements right of the zeroth entry.1420s=sum([-i//self.N+1 for i in [self.value(j) for j in range(1,self.N+1)] if i<0])1421if not s%2==0: raise ValueError( 'Type D affine permutations have an even number of entries less than 0 to the right of the 0th position.')14221423def apply_simple_reflection_right(self, i):1424r"""1425Applies the simple reflection indexed by `i` on positions.14261427EXAMPLES::14281429sage: D=AffinePermutationGroup(['D',4,1])1430sage: p=D([1,-6,5,-2])1431sage: p.apply_simple_reflection_right(0)1432Type D affine permutation with window [6, -1, 5, -2]1433sage: p.apply_simple_reflection_right(1)1434Type D affine permutation with window [-6, 1, 5, -2]1435sage: p.apply_simple_reflection_right(4)1436Type D affine permutation with window [1, -6, 11, 4]1437"""1438if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1439j=i1440l = self[:]1441if j!=0 and j!=self.k:1442a = l[j-1]1443l[j-1] = l[j]1444l[j] = a1445if j==0:1446c=l[0]1447l[0]=-l[1]1448l[1]=-c1449if j==self.k:1450l[self.k-2]=self(self.k+1)1451l[self.k-1]=self(self.k+2)1452#return l1453return self.parent()(l,check=False)14541455def apply_simple_reflection_left(self, i):1456r"""1457Applies simple reflection indexed by `i` on values.14581459EXAMPLES::14601461sage: D=AffinePermutationGroup(['D',4,1])1462sage: p=D([1,-6,5,-2])1463sage: p.apply_simple_reflection_left(0)1464Type D affine permutation with window [-2, -6, 5, 1]1465sage: p.apply_simple_reflection_left(1)1466Type D affine permutation with window [2, -6, 5, -1]1467sage: p.apply_simple_reflection_left(4)1468Type D affine permutation with window [1, -4, 3, -2]1469"""1470if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1471j=self.N-i1472l=[]1473if i!=self.k and i!=0:1474for m in xrange(self.k):1475res=self[m]%self.N1476if res==i :1477l.append(self[m]+1)1478elif res==i+1:1479l.append(self[m]-1)1480elif res==j:1481l.append(self[m]-1)1482elif res==j-1:1483l.append(self[m]+1)1484else:1485l.append(self[m])1486elif i==0:1487for m in xrange(self.k):1488res=self[m]%self.N1489if res==1:1490l.append(self[m]-3)1491elif res==self.N-2:1492l.append(self[m]+3)1493elif res==2:1494l.append(self[m]-3)1495elif res==self.N-1:1496l.append(self[m]+3)1497else:1498l.append(self[m])1499elif i==self.k:1500for m in xrange(self.k):1501res=self[m]%self.N1502if res==self.k:1503l.append(self[m]+2)1504elif res==self.k+2:1505l.append(self[m]-2)1506elif res==self.k-1:1507l.append(self[m]+2)1508elif res==self.k+1:1509l.append(self[m]-2)1510else:1511l.append(self[m])1512return self.parent()(l, check=False)15131514def has_right_descent(self, i):1515r"""1516Determines whether there is a descent at index `i`.15171518INPUT:15191520- ``i`` -- an integer.15211522EXAMPLES::15231524sage: D=AffinePermutationGroup(['D',4,1])1525sage: p=D([1,-6,5,-2])1526sage: [p.has_right_descent(i) for i in D.index_set()]1527[True, True, False, True, False]1528"""1529if i==0: return self.value(-2)>self.value(1)1530if i==self.k: return self.value(i)>self.value(i+2)1531return self.value(i)>self.value(i+1)15321533def has_left_descent(self, i):1534r"""1535Determines whether there is a descent at `i`.15361537INPUT:15381539- ``i`` -- an integer.15401541EXAMPLES::15421543sage: D=AffinePermutationGroup(['D',4,1])1544sage: p=D([1,-6,5,-2])1545sage: [p.has_left_descent(i) for i in D.index_set()]1546[True, True, False, True, True]1547"""1548if i==0: return self.position(-2)>self.position(1)1549if i==self.k: return self.position(i)>self.position(i+2)1550return self.position(i)>self.position(i+1)155115521553class AffinePermutationTypeG(AffinePermutation):1554#----------------------1555#Type-specific methods.1556#(Methods existing in all types, but with type-specific definition.)1557#----------------------1558def check(self):1559r"""1560Check that ``self`` is an affine permutation.15611562EXAMPLES::15631564sage: G=AffinePermutationGroup(['G',2,1])1565sage: p=G([2, 10, -5, 12, -3, 5])1566sage: p1567Type G affine permutation with window [2, 10, -5, 12, -3, 5]1568"""1569if not self:1570return1571if not len(self)==6: raise ValueError( "Length of list must be 6.")1572#Check that we have an even number of 'big' elements left of the 7th entry.1573s=sum([i//6-(i%6==0) for i in self._lst if i>6])1574if not s%2==0: raise ValueError( 'Type G affine permutations have an even number of entries greater than 6 to the left of the 7th position.')1575#Check that we have an even number of 'small' elements right of the zeroth entry.1576s=sum([-i//6+1 for i in self._lst if i<=0])1577if not s%2==0: raise ValueError( 'Type G affine permutations have an even number of entries less than 0 to the right of the 0th position.')15781579def value(self, i, base_window=False):1580r"""1581Returns the image of the integer `i` under this permutation.15821583INPUT:15841585- ``base_window`` -- a Boolean indicating whether `i` is between 1 and1586`k+1`. If True, will run a bit faster, but the method will screw up1587if `i` is not actually in the index set.15881589EXAMPLES::15901591sage: G=AffinePermutationGroup(['G',2,1])1592sage: p=G([2, 10, -5, 12, -3, 5])1593sage: [p.value(i) for i in [1..12]]1594[2, 10, -5, 12, -3, 5, 8, 16, 1, 18, 3, 11]1595"""1596N=61597if base_window: self[i-1]1598window=(i-1)//N1599return self[(i-1)%N]+window*(N)16001601def position(self, i):1602r"""1603Find the position `j` such the ``self.value(j)=i``16041605EXAMPLES::16061607sage: G=AffinePermutationGroup(['G',2,1])1608sage: p=G([2, 10, -5, 12, -3, 5])1609sage: [p.position(i) for i in p._lst]1610[1, 2, 3, 4, 5, 6]1611"""1612N=61613for r in xrange(N):1614if self[r]%N==i%N:1615#i sits in position i, but some number of windows away.1616diff=(i-self[r])//N1617return r+diff*N+11618return False16191620def apply_simple_reflection_right(self, i):1621r"""1622Applies the simple reflection indexed by `i` on positions.16231624EXAMPLES::16251626sage: G=AffinePermutationGroup(['G',2,1])1627sage: p=G([2, 10, -5, 12, -3, 5])1628sage: p.apply_simple_reflection_right(0)1629Type G affine permutation with window [-9, -1, -5, 12, 8, 16]1630sage: p.apply_simple_reflection_right(1)1631Type G affine permutation with window [10, 2, 12, -5, 5, -3]1632sage: p.apply_simple_reflection_right(2)1633Type G affine permutation with window [2, -5, 10, -3, 12, 5]1634"""1635if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1636j=i1637l = self[:]1638if j==1:1639l[0]=self(2)1640l[1]=self(1)1641l[2]=self(4)1642l[3]=self(3)1643l[4]=self(6)1644l[5]=self(5)1645elif j==2:1646l[1]=self(3)1647l[2]=self(2)1648l[3]=self(5)1649l[4]=self(4)1650elif j==0:1651l[0]=self(-1)1652l[1]=self(0)1653l[4]=self(7)1654l[5]=self(8)1655#return l1656return self.parent()(l,check=False)16571658def apply_simple_reflection_left(self, i):1659r"""1660Applies simple reflection indexed by `i` on values.16611662EXAMPLES::16631664sage: G=AffinePermutationGroup(['G',2,1])1665sage: p=G([2, 10, -5, 12, -3, 5])1666sage: p.apply_simple_reflection_left(0)1667Type G affine permutation with window [0, 10, -7, 14, -3, 7]1668sage: p.apply_simple_reflection_left(1)1669Type G affine permutation with window [1, 9, -4, 11, -2, 6]1670sage: p.apply_simple_reflection_left(2)1671Type G affine permutation with window [3, 11, -5, 12, -4, 4]1672"""1673if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1674l=[]1675if i==1:1676for m in xrange(6):1677res=self[m]%61678if res==1 or res==3 or res==5:1679l.append(self[m]+1)1680elif res==2 or res==4 or res==0:1681l.append(self[m]-1)1682else:1683l.append(self[m])1684elif i==2:1685for m in xrange(6):1686res=self[m]%61687if res==2 or res==4:1688l.append(self[m]+1)1689elif res==3 or res==5:1690l.append(self[m]-1)1691else:1692l.append(self[m])1693elif i==0:1694for m in xrange(6):1695res=self[m]%61696if res==1 or res==2:1697l.append(self[m]-2)1698elif res==5 or res==0:1699l.append(self[m]+2)1700else:1701l.append(self[m])1702return self.parent()(l, check=False)17031704def has_right_descent(self, i):1705r"""1706Determines whether there is a descent at index `i`.17071708INPUT:17091710- ``i`` -- an integer.17111712EXAMPLES::17131714sage: G=AffinePermutationGroup(['G',2,1])1715sage: p=G([2, 10, -5, 12, -3, 5])1716sage: [p.has_right_descent(i) for i in G.index_set()]1717[False, False, True]1718"""1719if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1720if i==0: return self.value(0)>self.value(2)1721return self.value(i)>self.value(i+1)17221723def has_left_descent(self, i):1724r"""1725Determines whether there is a descent at `i`.17261727INPUT:17281729- ``i`` -- an integer.17301731EXAMPLES::17321733sage: G=AffinePermutationGroup(['G',2,1])1734sage: p=G([2, 10, -5, 12, -3, 5])1735sage: [p.has_left_descent(i) for i in G.index_set()]1736[False, True, False]1737"""1738if not i in self.parent().index_set(): raise ValueError('Index not in index set.')1739if i==0: return self.position(0)>self.position(2)1740return self.position(i)>self.position(i+1)17411742def to_type_a(self):1743r"""1744Returns an embedding of ``self`` into the affine permutation group of1745type A.17461747EXAMPLES::17481749sage: G=AffinePermutationGroup(['G',2,1])1750sage: p=G([2, 10, -5, 12, -3, 5])1751sage: p.to_type_a()1752Type A affine permutation with window [2, 10, -5, 12, -3, 5]1753"""1754A=AffinePermutationGroup(['A', 5, 1])1755return A(self._lst)17561757175817591760#-------------------------------------------------------------------------1761# Class of all affine permutations.1762#-------------------------------------------------------------------------17631764def AffinePermutationGroup(cartan_type):1765"""1766Wrapper function for specific affine permutation groups.17671768These are combinatorial implmentations of the affine Weyl groups of1769types `A`, `B`, `C`, `D`, and `G` as permutations of the set of all integers.1770the basic algorithms are derived from [BjBr]_ and [Erik]_.17711772REFERENCES:17731774.. [BjBr] Bjorner and Brenti. Combinatorics of Coxeter Groups. Springer, 2005.1775.. [Erik] H. Erikson. Computational and Combinatorial Aspects of Coxeter1776Groups. Thesis, 1995.17771778EXAMPLES::17791780sage: ct=CartanType(['A',7,1])1781sage: A=AffinePermutationGroup(ct)1782sage: A1783The group of affine permutations of type ['A', 7, 1]17841785We define an element of ``A``:1786::17871788sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])1789sage: p1790Type A affine permutation with window [3, -1, 0, 6, 5, 4, 10, 9]17911792We find the value `p(1)`, considering `p` as a bijection on the integers. This1793is the same as calling the 'value' method:1794::17951796sage: p.value(1)179731798sage: p(1)==p.value(1)1799True18001801We can also find the position of the integer 3 in `p` considered as a sequence,1802equivalent to finding `p^{-1}(3)`:1803::18041805sage: p.position(3)180611807sage: (p^-1)(3)1808118091810Since the affine permutation group is a group, we demonstrate its group properties:1811::18121813sage: A.one()1814Type A affine permutation with window [1, 2, 3, 4, 5, 6, 7, 8]18151816sage: q=A([0, 2, 3, 4, 5, 6, 7, 9])1817sage: p*q1818Type A affine permutation with window [1, -1, 0, 6, 5, 4, 10, 11]1819sage: q*p1820Type A affine permutation with window [3, -1, 1, 6, 5, 4, 10, 8]18211822sage: p^-11823Type A affine permutation with window [0, -1, 1, 6, 5, 4, 10, 11]1824sage: p^-1*p==A.one()1825True1826sage: p*p^-1==A.one()1827True18281829If we decide we prefer the Weyl Group implementation of the affine Weyl1830group, we can easily get it:1831::18321833sage: p.to_weyl_group_element()1834[ 0 -1 0 1 0 0 1 0]1835[ 1 -1 0 1 0 0 1 -1]1836[ 1 -1 0 1 0 0 0 0]1837[ 0 0 0 1 0 0 0 0]1838[ 0 0 0 1 0 -1 1 0]1839[ 0 0 0 1 -1 0 1 0]1840[ 0 0 0 0 0 0 1 0]1841[ 0 -1 1 0 0 0 1 0]18421843We can find a reduced word and do all of the other things one expects in1844a Coxeter group:1845::18461847sage: p.has_right_descent(1)1848True1849sage: p.apply_simple_reflection(1)1850Type A affine permutation with window [-1, 3, 0, 6, 5, 4, 10, 9]1851sage: p.apply_simple_reflection(0)1852Type A affine permutation with window [1, -1, 0, 6, 5, 4, 10, 11]1853sage: p.reduced_word()1854[0, 7, 4, 1, 0, 7, 5, 4, 2, 1]1855sage: p.length()18561018571858The following methods are particular to Type `A`.1859We can check if the element is fully commutative:1860::18611862sage: p.is_fully_commutative()1863False1864sage: q.is_fully_commutative()1865True18661867And we can also compute the affine Lehmer code of the permutation, a weak1868composition with `k+1` entries:1869::18701871sage: p.to_lehmer_code()1872[0, 3, 3, 0, 1, 2, 0, 1]18731874Once we have the Lehmer code, we can obtain a `k`-bounded partition by1875sorting the Lehmer code, and then reading the row lengths.1876There is a unique 0-Grassmanian (dominant) affine permutation associated1877to this `k`-bounded partition, and a `k`-core as well.1878::18791880sage: p.to_bounded_partition()1881[5, 3, 2]1882sage: p.to_dominant()1883Type A affine permutation with window [-2, -1, 1, 3, 4, 8, 10, 13]1884sage: p.to_core()1885[5, 3, 2]18861887Finally, we can take a reduced word for `p` and insert it to find a1888standard composition tableau associated uniquely to that word.1889::18901891sage: p.tableau_of_word(p.reduced_word())1892[[], [1, 6, 9], [2, 7, 10], [], [3], [4, 8], [], [5]]18931894We can also form affine permutation groups in types `B`, `C`, `D`, and `G`.1895::18961897sage: B=AffinePermutationGroup(['B',4,1])1898sage: B.an_element()1899Type B affine permutation with window [-1, 3, 4, 11]19001901sage: C=AffinePermutationGroup(['C',4,1])1902sage: C.an_element()1903Type C affine permutation with window [2, 3, 4, 10]19041905sage: D=AffinePermutationGroup(['D',4,1])1906sage: D.an_element()1907Type D affine permutation with window [-1, 3, 11, 5]19081909sage: G=AffinePermutationGroup(['G',2,1])1910sage: G.an_element()1911Type G affine permutation with window [0, 4, -1, 8, 3, 7]1912"""1913ct=CartanType(cartan_type)1914if ct.letter=='A': return AffinePermutationGroupTypeA(ct)1915if ct.letter=='B': return AffinePermutationGroupTypeB(ct)1916if ct.letter=='C': return AffinePermutationGroupTypeC(ct)1917if ct.letter=='D': return AffinePermutationGroupTypeD(ct)1918if ct.letter=='G': return AffinePermutationGroupTypeG(ct)1919raise NotImplementedError('Cartan type provided is not implemented as an affine permutation group.')192019211922class AffinePermutationGroupGeneric(UniqueRepresentation, Parent):1923"""1924The generic affine permutation group class, in which we define all type-free1925methods for the specific affine permutation groups.1926"""19271928#----------------------1929#Type-free methods.1930#----------------------19311932def __init__(self, cartan_type):1933r"""1934TESTS::19351936sage: AffinePermutationGroup(['A',7,1])1937The group of affine permutations of type ['A', 7, 1]1938"""1939Parent.__init__(self, category = AffineWeylGroups())1940ct=CartanType(cartan_type)1941self.k=ct.n1942self.n=ct.rank()1943#This N doesn't matter for type A, but comes up in all other types.1944if ct.letter=='A':1945self.N=self.k+11946elif ct.letter=='B' or ct.letter=='C' or ct.letter=='D':1947self.N=2*self.k+11948elif ct.letter=='G':1949self.N=61950self._cartan_type=ct19511952def _element_constructor_(self, *args, **keywords):1953r"""1954TESTS::19551956sage: AffinePermutationGroup(['A',7,1])([3, -1, 0, 6, 5, 4, 10, 9])1957Type A affine permutation with window [3, -1, 0, 6, 5, 4, 10, 9]1958"""1959return self.element_class(self, *args, **keywords)19601961def _repr_(self):1962r"""1963TESTS::19641965sage: AffinePermutationGroup(['A',7,1])1966The group of affine permutations of type ['A', 7, 1]1967"""1968return "The group of affine permutations of type "+str(self.cartan_type())19691970def _test_coxeter_relations(self, tester=None):1971r"""1972Tests whether the Coxeter relations hold for ``self``.1973This should probably be implemented at the Coxeter groups level.19741975TESTS::19761977sage: A=AffinePermutationGroup(['A',7,1])1978sage: A._test_coxeter_relations()1979"""1980ct=self.cartan_type()1981D=ct.coxeter_diagram()1982s=self.simple_reflections()1983for e in D.edges():1984l=s[e[0]]*s[e[1]]1985assert l**(e[2])==self.one(), 'Dynkin relation fails.'19861987def _test_enumeration(self, n=4, tester=None):1988r"""1989Test that ``self`` has same number of elements of length ``n`` as the1990Weyl Group implementation.19911992Combined with ``self._test_coxeter_relations`` this shows isomorphism1993up to length ``n``.19941995TESTS::19961997sage: A=AffinePermutationGroup(['A',7,1])1998sage: A._test_coxeter_relations(3)1999"""2000n1=len(list(self.elements_of_length(n)))2001W=self.weyl_group()2002I=W.weak_order_ideal(ConstantFunction(True), side='right')2003n2=len(list(I.elements_of_depth_iterator(n)))2004assert n1==n2, 'Number of (ranked) elements of affine permutation group disagrees with Weyl group.'20052006def weyl_group(self):2007r"""2008Returns the Weyl Group of the same type as ``self``.20092010EXAMPLES::20112012sage: A=AffinePermutationGroup(['A',7,1])2013sage: A.weyl_group()2014Weyl Group of type ['A', 7, 1] (as a matrix group acting on the root space)2015"""2016return WeylGroup(self._cartan_type)20172018def classical(self):2019r"""2020Returns the finite permutation group.20212022EXAMPLES::20232024sage: A=AffinePermutationGroup(['A',7,1])2025sage: A.classical()2026Symmetric group of order 8! as a permutation group2027"""2028if self._cartan_type.letter=='A':2029return SymmetricGroup(self.k+1)2030return WeylGroup(self._cartan_type.classical())20312032def cartan_type(self):2033r"""2034Returns the Cartan type of ``self``.20352036EXAMPLES::20372038sage: AffinePermutationGroup(['A',7,1]).cartan_type()2039['A', 7, 1]2040"""2041return self._cartan_type20422043def cartan_matrix(self):2044r"""2045Returns the Cartan matrix of ``self``.20462047EXAMPLES::20482049sage: AffinePermutationGroup(['A',7,1]).cartan_matrix()2050[ 2 -1 0 0 0 0 0 -1]2051[-1 2 -1 0 0 0 0 0]2052[ 0 -1 2 -1 0 0 0 0]2053[ 0 0 -1 2 -1 0 0 0]2054[ 0 0 0 -1 2 -1 0 0]2055[ 0 0 0 0 -1 2 -1 0]2056[ 0 0 0 0 0 -1 2 -1]2057[-1 0 0 0 0 0 -1 2]2058"""2059return self.cartan_type().cartan_matrix()20602061def is_crystallographic(self):2062r"""2063Tells whether the affine permutation group is crystallographic.20642065EXAMPLES::20662067sage: AffinePermutationGroup(['A',7,1]).is_crystallographic()2068True2069"""2070return self.cartan_type().is_crystallographic()20712072def index_set(self):2073r"""2074EXAMPLES::20752076sage: AffinePermutationGroup(['A',7,1]).index_set()2077(0, 1, 2, 3, 4, 5, 6, 7)2078"""2079return self.cartan_type().index_set()20802081_index_set=index_set20822083def reflection_index_set(self):2084r"""2085EXAMPLES::20862087sage: AffinePermutationGroup(['A',7,1]).index_set()2088(0, 1, 2, 3, 4, 5, 6, 7)2089"""2090return self.cartan_type().index_set()20912092def rank(self):2093r"""2094Rank of the affine permutation group, equal to `k+1`.20952096EXAMPLES::20972098sage: AffinePermutationGroup(['A',7,1]).rank()209982100"""2101return self.k+121022103def random_element(self, n):2104r"""2105Returns a random affine permutation of length `n`.21062107Starts at the identity, then chooses an upper cover at random.2108Not very uniform: actually constructs a uniformly random reduced word2109of length `n`. Thus we most likely get elements with lots of reduced2110words!21112112EXAMPLES::21132114sage: A=AffinePermutationGroup(['A',7,1])2115sage: p=A.random_element(10)2116sage: p.length()==102117True2118"""2119x=self.one()2120for i in xrange(1,n+1):2121antiD=x.descents(positive=True)2122x=x.apply_simple_reflection_right(antiD[ randint(0, len(antiD)-1) ])2123return x21242125def from_word(self, w):2126r"""2127Builds an affine permutation from a given word.2128Note: Already in category as ``from_reduced_word``, but this is less2129typing!21302131EXAMPLES::21322133sage: A=AffinePermutationGroup(['A',7,1])2134sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])2135sage: A.from_word([0, 7, 4, 1, 0, 7, 5, 4, 2, 1])2136Type A affine permutation with window [3, -1, 0, 6, 5, 4, 10, 9]2137"""2138return self.from_reduced_word(w)21392140@cached_method2141def _an_element_(self):2142r"""2143Returns a Coxeter element.21442145EXAMPLES::21462147sage: A=AffinePermutationGroup(['A',7,1])2148sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])2149sage: A.from_word([0, 7, 4, 1, 0, 7, 5, 4, 2, 1])2150Type A affine permutation with window [3, -1, 0, 6, 5, 4, 10, 9]2151"""2152return self.from_reduced_word(self.index_set())21532154def elements_of_length(self, n):2155r"""2156Returns all elements of length `n`.21572158EXAMPLES::21592160sage: A=AffinePermutationGroup(['A',2,1])2161sage: [len(list(A.elements_of_length(i))) for i in [0..5]]2162[1, 3, 6, 9, 12, 15]2163"""2164#Note: This is type-free, and should probably be included in Coxeter Groups.2165I=self.weak_order_ideal(ConstantFunction(True), side='right')2166return I.elements_of_depth_iterator(n)216721682169class AffinePermutationGroupTypeA(AffinePermutationGroupGeneric):2170#------------------------2171#Type-specific methods.2172#(Methods in all types, but with specific definition.)2173#------------------------21742175def one(self):2176r"""2177Returns the identity element.21782179EXAMPLES::21802181sage: AffinePermutationGroup(['A',7,1]).one()2182Type A affine permutation with window [1, 2, 3, 4, 5, 6, 7, 8]21832184TESTS::21852186sage: A=AffinePermutationGroup(['A',5,1])2187sage: A==loads(dumps(A))2188True2189sage: TestSuite(A).run()2190"""2191return self([i for i in xrange(1,self.k+2)])21922193#------------------------2194#Type-unique methods.2195#(Methods which do not exist in all types.)2196#------------------------2197def from_lehmer_code(self, C, typ='decreasing', side='right'):2198r"""2199Returns the affine permutation with the supplied Lehmer code (a weak2200composition with `k+1` parts, at least one of which is 0).22012202INPUT:22032204- ``typ`` -- 'increasing' or 'decreasing': type of product.2205(default: 'decreasing'.)2206- ``side`` -- 'right' or 'left': Whether the decomposition is from2207the right or left. (default: 'right'.)22082209EXAMPLES::22102211sage: A=AffinePermutationGroup(['A',7,1])2212sage: p=A([3, -1, 0, 6, 5, 4, 10, 9])2213sage: p.to_lehmer_code()2214[0, 3, 3, 0, 1, 2, 0, 1]2215sage: A.from_lehmer_code(p.to_lehmer_code())==p2216True2217sage: CP=CartesianProduct( ('increasing','decreasing'),('left','right') )2218sage: for a in CP:2219....: A.from_lehmer_code(p.to_lehmer_code(a[0],a[1]),a[0],a[1])==p2220True2221True2222True2223True2224"""2225if not len(C)-1==self.k: raise ValueError( "Composition must have "+str(self.k+1)+" entries." )2226if not 0 in C: raise ValueError( "Composition must contain a zero entry." )2227k=self.k2228#Find a zero entry in C.2229for r in xrange(self.k+1):2230if C[r]==0: break2231D=list(C)2232#The s0 and t0 are +-1, dependent on typ and side.2233if (typ[0],side[0])==('d','r'): (t0,s0)=(-1, 1)2234if (typ[0],side[0])==('i','r'): (t0,s0)=( 1, 1)2235if (typ[0],side[0])==('d','l'): (t0,s0)=(-1,-1)2236if (typ[0],side[0])==('i','l'): (t0,s0)=( 1,-1)2237row=02238#Method is to build a reduced word from the composition.2239#We create a list of cyclically in/decreasing words appearing in2240#the decomposition corresponding to the composition C,2241#and then build the element.2242listy=[]2243while sum(D)>0:2244l=['x' for i in xrange(self.k+1)]2245ll=[]2246#read off a row of C.2247for j in xrange(self.k+1):2248pos=(r + s0*t0*j)%(k+1)2249residue=( r + s0*t0*(row + j) )%(k+1)2250if D[pos]!=0:2251ll.append(residue)2252l[pos]=[residue]2253D[pos]-=12254if side[0]=='l': ll.reverse()2255listy.append(ll)2256row+=12257if side[0]=='r': listy.reverse()2258x=self.one()2259for ll in listy:2260for i in ll:2261x=x.apply_simple_reflection_right(i)2262return x22632264Element = AffinePermutationTypeA22652266class AffinePermutationGroupTypeC(AffinePermutationGroupGeneric):2267#------------------------2268#Type-specific methods.2269#(Methods in all types, but with specific definition.)2270#------------------------22712272def one(self):2273r"""2274Returns the identity element.22752276EXAMPLES::22772278sage: ct=CartanType(['C',4,1])2279sage: C=AffinePermutationGroup(ct)2280sage: C.one()2281Type C affine permutation with window [1, 2, 3, 4]2282sage: C.one()*C.one()==C.one()2283True22842285TESTS::22862287sage: C=AffinePermutationGroup(['C',4,1])2288sage: C==loads(dumps(C))2289True2290sage: TestSuite(C).run()2291"""2292return self([i for i in xrange(1,self.k+1)])22932294Element = AffinePermutationTypeC229522962297class AffinePermutationGroupTypeB(AffinePermutationGroupTypeC):2298#------------------------2299#Type-specific methods.2300#(Methods in all types, but with specific definition.)2301#------------------------2302Element = AffinePermutationTypeB23032304class AffinePermutationGroupTypeC(AffinePermutationGroupTypeC):2305#------------------------2306#Type-specific methods.2307#(Methods in all types, but with specific definition.)2308#------------------------2309Element = AffinePermutationTypeC23102311class AffinePermutationGroupTypeD(AffinePermutationGroupTypeC):2312#------------------------2313#Type-specific methods.2314#(Methods in all types, but with specific definition.)2315#------------------------2316Element = AffinePermutationTypeD23172318class AffinePermutationGroupTypeG(AffinePermutationGroupGeneric):2319#------------------------2320#Type-specific methods.2321#(Methods in all types, but with specific definition.)2322#------------------------2323def one(self):2324r"""2325Returns the identity element.23262327EXAMPLES::23282329sage: AffinePermutationGroup(['G',2,1]).one()2330Type G affine permutation with window [1, 2, 3, 4, 5, 6]23312332TESTS::23332334sage: G=AffinePermutationGroup(['G',2,1])2335sage: G==loads(dumps(G))2336True2337sage: TestSuite(G).run()2338"""2339return self([1,2,3,4,5,6])2340Element = AffinePermutationTypeG2341234223432344