K i rddlmZddlmZddlmZmZddlmZGddeZ d dZ d d Z d d Z y) ) free_group)DefaultPrinting)chainproduct) bisect_leftceZdZdZdZdZdZd$dZedZ dZ dZ e Z ed Z d Zd%d Zd Zd ZdZd&dZdZd'dZd%dZd'dZdZdZdZdZdZdZdZdZdZ dZ!dZ"d%dZ#d Z$d!Z%d"Z&d#Z'y)( CosetTablea Properties ========== [1] `0 \in \Omega` and `\tau(1) = \epsilon` [2] `\alpha^x = \beta \Leftrightarrow \beta^{x^{-1}} = \alpha` [3] If `\alpha^x = \beta`, then `H \tau(\alpha)x = H \tau(\beta)` [4] `\forall \alpha \in \Omega, 1^{\tau(\alpha)} = \alpha` References ========== .. [1] Holt, D., Eick, B., O'Brien, E. "Handbook of Computational Group Theory" .. [2] John J. Cannon; Lucien A. Dimino; George Havas; Jane M. Watson Mathematics of Computation, Vol. 27, No. 123. (Jul., 1973), pp. 463-490. "Implementation and Analysis of the Todd-Coxeter Algorithm" i>Ndc |stj}||_||_||_dg|_t tjd|jjD|_ dgt|jzg|_ dgt|jzg|_ |jDcic]}||jj| c}|_i|_|jj#D]L\}}|dzdk(r |j|dz|j |<.|j|dz |j |<Ng|_|j}t'dj)t+t|Dcgc]}d|z c}d|_dgt|jzg|_ i|_ycc}wcc}w)Nrc3*K|] }||dzf ywN).0gens e/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/combinatorics/coset_table.py z&CosetTable.__init__..@s *5,/R.*5sz, za_%d)r coset_table_max_limitfp_groupsubgroupcoset_table_limitplistr from_iterable generatorsAlenPtableindexA_dict A_dict_invitemsdeduction_stackrjoinrange_grpp_p)selffp_grpr max_cosetsxr"His r__init__zCosetTable.__init__7s#99J   !+e))*5==33*556&TVV$%fS[() 3766:aq$&&,,q/):  ))+ 8HAuqyA~%)[[^a%7"%)[[^a%7"  8 " MMtzzuSV}*M!6A:*MNOPQR &TVV$%;+Ns :#G G ctt|jDcgc]}|j||k(s|c}Scc}w)zSet of live cosets. )r(rr)r+cosets romegazCosetTable.omegaWs4$)TVV#5P%%9OPPPs AAc|j|j|j}|jDcgc] }t |c}|_t |j |_t |j |_|Scc}w)zJ Return a shallow copy of Coset Table instance ``self``. ) __class__rrr!rrr&)r+ self_copyperm_reps rcopyzCosetTable.copy\sd NN4==$--@ :>**Eh4>E 466l $()=)=$> !FsBc<d|jd|jdS)NzCoset Table on z with z as subgroup generators)rrr+s r__str__zCosetTable.__str__gs==$--1 1cL|jsyt|jdzS)zaThe number `n` represents the length of the sublist containing the live cosets. rr)r!maxr4r;s rnz CosetTable.nms! zz4::""r=cBtfdjD S)z The coset table is called complete if it has no undefined entries on the live cosets; that is, `\alpha^x` is defined for all `\alpha \in \Omega` and `x \in A`. c3@K|]}dj|vywN)r!)rr3r+s rrz)CosetTable.is_complete..sIUttzz%00Is)anyr4r;s`r is_completezCosetTable.is_completexsIdjjIIIIr=c|j}|j}t|}||jk\rt d|jz|j dgt|z|j j dgt|jz|}|jj |||||j|<||||j|<|r|jj|j ||j|<|jj|j ||j|<|jj|j|<yy)a This routine is used in the relator-based strategy of Todd-Coxeter algorithm if some `\alpha^x` is undefined. We check whether there is space available for defining a new coset. If there is enough space then we remedy this by adjoining a new coset `\beta` to `\Omega` (i.e to set of live cosets) and put that equal to `\alpha^x`, then make an assignment satisfying Property[1]. If there is not enough space then we halt the Coset Table creation. The maximum amount of space that can be used by Coset Table can be manipulated using the class variable ``CosetTable.coset_table_max_limit``. See Also ======== define_c ethe coset enumeration has defined more than %s cosets. Try with a greater value max number of cosets N) rr!rr ValueErrorappendr rr#r$r)identityr*)r+alphar.modifiedrr! len_tablebetas rdefinezCosetTable.defines/$ FF J .. .P,,-. .  dVCF]#  tfS[()  d'+e T[[^$*/d DOOA&' ,0II,>,>DFF5M$++a. )/3yy/A/ADFF4L+ ,!YY//DHHTN r=c|j}|j}t|}||jk\rt d|jz|j dgt|z|}|j j |||||j|<||||j|<|jj ||fy)aX A variation of ``define`` routine, described on Pg. 165 [1], used in the coset table-based strategy of Todd-Coxeter algorithm. It differs from ``define`` routine in that for each definition it also adds the tuple `(\alpha, x)` to the deduction stack. See Also ======== define rGN) rr!rrrHrIrr#r$r&)r+rKr.rr!rMrNs rdefine_czCosetTable.define_cs FF J .. .P,,-. .  dVCF]#  d'+e T[[^$*/d DOOA&' ##UAJ/r=cN|j}|j}|j}|}d}t|}|} |dz } || kr5|||||'|||||}|dz }|| kr|||||'|| kDr|| k7r|j || y| |k\r5|| ||| '|| ||| } | dz} | |k\r|| ||| '| |kr|j || y| |k(r=| |||||<||| |||<|j j |||fyy)z A variation of ``scan`` routine, described on pg. 165 of [1], which puts at tuple, whenever a deduction occurs, to deduction stack. See Also ======== scan, scan_check, scan_and_fill, scan_and_fill_c rrN)r#r$r!r coincidence_cr&rI r+rKwordr#r$r!fr0rbjs rscan_czCosetTable.scan_cs__     I  E1fq&a/2>aQ)A FA1fq&a/2> q5Av""1a( 1fq*T!W"56BaDG,-A FA1fq*T!W"56B q5   q! $ !V()E!HVDG_ %,-E!HZQ( )  ' 'DG 5 r=cd|j}|j}|j}g}|j|||t |dkDr|j d}|D]}||||} | d|| ||<|j j| |dzf|j|} |j| } || |||j| || ||||| |||j| || |||| || ||<| || ||<t |dkDryy)aQ A variation of ``coincidence`` routine used in the coset-table based method of coset enumeration. The only difference being on addition of a new coset in coset table(i.e new coset introduction), then it is appended to ``deduction_stack``. See Also ======== coincidence rNr) r#r$r!mergerpopr&rIrep) r+rKrNr#r$r!qgammar.deltamunus rrSzCosetTable.coincidence_csL__    5$"!fqjEE!HE 6e VAY/$26E%LA/((//2?%B%BRy+7 2uRy';Q?r:a=1= 2uRyA'?C/1b &),35b *Q-0 6!fqjr=c@|j}|j}|j}|} d} t|} |} | dz } |}|r|jj }d}|s|dk(rd}| | krR|| ||| D|r|j | ||| z}|| ||| } | dz } | | kr|| ||| D| | kDr4| | k7r.|r|j| | dz|zy|j| | y| | k\r\|| ||| N|r%||j | |j|| z}|| ||| } | dz} | | k\r|| ||| N| | kr/|r|j| | dz|zn|j| | n| | k(ro| || ||| <| || ||| <|rPdz|z|j | |j|| <|dz|z|j | |j|| <y|r|j| || ||r|dk(ryy)a ``scan`` performs a scanning process on the input ``word``. It first locates the largest prefix ``s`` of ``word`` for which `\alpha^s` is defined (i.e is not ``None``), ``s`` may be empty. Let ``word=sv``, let ``t`` be the longest suffix of ``v`` for which `\alpha^{t^{-1}}` is defined, and let ``v=ut``. Then three possibilities are there: 1. If ``t=v``, then we say that the scan completes, and if, in addition `\alpha^s = \alpha^{t^{-1}}`, then we say that the scan completes correctly. 2. It can also happen that scan does not complete, but `|u|=1`; that is, the word ``u`` consists of a single generator `x \in A`. In that case, if `\alpha^s = \beta` and `\alpha^{t^{-1}} = \gamma`, then we can set `\beta^x = \gamma` and `\gamma^{x^{-1}} = \beta`. These assignments are known as deductions and enable the scan to complete correctly. 3. See ``coicidence`` routine for explanation of third condition. Notes ===== The code for the procedure of scanning `\alpha \in \Omega` under `w \in A*` is defined on pg. 155 [1] See Also ======== scan_c, scan_check, scan_and_fill, scan_and_fill_c Scan and Fill ============= Performed when the default argument fill=True. Modified Scan ============= Performed when the default argument modified=True rrNrrL) r#r$r!rr)rJr modified_coincidence coincidencerO)r+rKrUyfillrLr#r$r!rVr0rWrXrYb_pf_pflags rscanzCosetTable.scans^__     I  E ))$$CdaiDq&U1XfT!Wo6BdffQitAw88C!HVDG_-Q q&U1XfT!Wo6B 1u611!QR B((A.q&U1Xja&9:FdffQiQ(@AAC!HZQ01Q q&U1Xja&9:F 1u--aCGCK@$$Q*a,-aQ)01aDG,-692gckDFF1Idkk$q'23:=r'#+DFF1Idood1g67 AtAw :Gdair=c|j}|j}|j}|}d}t|}|} |dz } || kr5|||||'|||||}|dz }|| kr|||||'|| kDr|| k(S| |k\r5|| ||| '|| ||| } | dz} | |k\r|| ||| '| |kry| |k(r| |||||<||| |||<y)a Another version of ``scan`` routine, described on, it checks whether `\alpha` scans correctly under `word`, it is a straightforward modification of ``scan``. ``scan_check`` returns ``False`` (rather than calling ``coincidence``) if the scan completes incorrectly; otherwise it returns ``True``. See Also ======== scan, scan_c, scan_and_fill, scan_and_fill_c rrFT)r#r$r!rrTs r scan_checkzCosetTable.scan_check}sP$__     I  E1fq&a/2>aQ)A FA1fq&a/2> q56M1fq*T!W"56BaDG,-A FA1fq*T!W"56B q5 !V()E!HVDG_ %,-E!HZQ( )r=c|j}|j}|||}|||} || k7rt|| } t|| } | || <|rm| |k(r3|j|dz|z|j|z|j|<n5|j|dz|dzz|j|z|j| <|j | yy)a Merge two classes with representatives ``k`` and ``lamda``, described on Pg. 157 [1] (for pseudocode), start by putting ``p[k] = lamda``. It is more efficient to choose the new representative from the larger of the two classes being merged, i.e larger among ``k`` and ``lamda``. procedure ``merge`` performs the merging operation, adds the deleted class representative to the queue ``q``. Parameters ========== 'k', 'lamda' being the two class representatives to be merged. Notes ===== Pg. 86-87 [1] contains a description of this method. See Also ======== coincidence, rep rerN)rr^minr?r*rI) r+klamdar_wrLrr^phipsirbvs rr\zCosetTable.merges2 FFhh!h'%(+ #:S#BC AAaD8$(HHQKOA$5dhhuo$EDHHSM$(HHUOR$72$=dhhqk$IDHHSM HHQK r=c@|j}|}||}|r|dd}||k7r|r||<|}||}||k7r|rJ|}||k7r>|}||}|||<|j||j|z|j|<||k7r>|S|}||}||k7r|||<|}||}||k7r|S)a Parameters ========== `k \in [0 \ldots n-1]`, as for ``self`` only array ``p`` is used Returns ======= Representative of the class containing ``k``. Returns the representative of `\sim` class containing ``k``, it also makes some modification to array ``p`` of ``self`` to ease further computations, described on Pg. 157 [1]. The information on classes under `\sim` is stored in array `p` of ``self`` argument, which will always satisfy the property: `p[\alpha] \sim \alpha` and `p[\alpha]=\alpha \iff \alpha=rep(\alpha)` `\forall \in [0 \ldots n-1]`. So, for `\alpha \in [0 \ldots n-1]`, we find `rep(self, \alpha)` by continually replacing `\alpha` by `p[\alpha]` until it becomes constant (i.e satisfies `p[\alpha] = \alpha`):w To increase the efficiency of later ``rep`` calculations, whenever we find `rep(self, \alpha)=\beta`, we set `p[\gamma] = \beta \forall \gamma \in p-chain` from `\alpha` to `\beta` Notes ===== ``rep`` routine is also described on Pg. 85-87 [1] in Atkinson's algorithm, this results from the fact that ``coincidence`` routine introduces functionality similar to that introduced by the ``minimal_block`` routine on Pg. 85-87 [1]. See Also ======== coincidence, merge N)rr*)r+rrrLrrsrhosrbs rr^zCosetTable.repsX FFh !AUl#EE(C Ul E(C(e# $ dhhrl : ( BB%C,"e, r=c|j}|j}|j}g}|r|j||||n|j |||t |dkDrx|j d} |D]P} || || } | d|| || <|j| |} |j| |} || || |r|j| dz|j| |j| dzz}||j| z|j| |j| z}|j| || |j| |||j | || || ||| || |r|j| dz|j| |j| z}||j| z|j| |j| z}|j| || |j| |||j | || || || || || <| || || <|s|j| dz|j| |j| z|j| z}||j| |j| <|dz|j| |j| <St |dkDrwyy)a The third situation described in ``scan`` routine is handled by this routine, described on Pg. 156-161 [1]. The unfortunate situation when the scan completes but not correctly, then ``coincidence`` routine is run. i.e when for some `i` with `1 \le i \le r+1`, we have `w=st` with `s = x_1 x_2 \dots x_{i-1}`, `t = x_i x_{i+1} \dots x_r`, and `\beta = \alpha^s` and `\gamma = \alpha^{t-1}` are defined but unequal. This means that `\beta` and `\gamma` represent the same coset of `H` in `G`. Described on Pg. 156 [1]. ``rep`` See Also ======== scan rNrer) r#r$r!modified_merger\rr]r^r*r )r+rKrNrtrLr#r$r!r_r`r.rarbrcrws rrgzCosetTable.coincidences&__       tQ 2 JJudA &!fqjEE!HE Ce VAY/$26E%LA/%(;B%(;BRy+7# $ 3DFF5M$++a.4QSU4U UA !$((5/ 1$&&*T[[^2L LA //E"Idkk!n4MqRST JJr59VAY+?Cr:a=1=# $ 3DFF5M$++a.4Q QA !$((5/ 1$&&*T__Q=O2P PA //E"Idooa>P4QSTVWX JJr59Z]+CQG/1b &),35b *Q-0# $ 3DFF5M$++a.4Q QRVRZRZ[`Ra aA9:DFF2Jt{{1~6=>UDFF2Jtq'9:5 C!fqjr=c,|j||dy)a A modified version of ``scan`` routine used in the relator-based method of coset enumeration, described on pg. 162-163 [1], which follows the idea that whenever the procedure is called and the scan is incomplete then it makes new definitions to enable the scan to complete; i.e it fills in the gaps in the scan of the relator or subgroup generator. TriNrm)r+rKrUs r scan_and_fillzCosetTable.scan_and_fillTs %D )r=c||j}|j}|j}t|}|}d}|} |dz } || kr5|||||'|||||}|dz }|| kr|||||'|| kDr|| k7r|j || y| |k\r5|| ||| '|| ||| } | dz} | |k\r|| ||| '| |kr|j || nW| |k(r=| |||||<||| |||<|j j |||fn|j|||)a~ A modified version of ``scan`` routine, described on Pg. 165 second para. [1], with modification similar to that of ``scan_anf_fill`` the only difference being it calls the coincidence procedure used in the coset-table based method i.e. the routine ``coincidence_c`` is used. See Also ======== scan, scan_and_fill rrN)r#r$r!rrSr&rIrQ) r+rKrUr#r$r!rWrVr0rXrYs rscan_and_fill_czCosetTable.scan_and_fill_c`s__   I    Eq&U1XfT!Wo6B!HVDG_-Qq&U1XfT!Wo6B1u6&&q!,q&U1Xja&9:F!HZQ01Qq&U1Xja&9:F1u""1a(a,-aQ)01aDG,-$$++QQL9 aa))r=c|jj}|j}|jD]%}|D]}|j |||||ks%'y)aO When combined with the HLT method this is known as HLT+Lookahead method of coset enumeration, described on pg. 164 [1]. Whenever ``define`` aborts due to lack of space available this procedure is executed. This routine helps in recovering space resulting from "coincidence" of cosets. N)rrelatorsrr4rm)r+RrrNrts r look_aheadzCosetTable.look_aheads\ MM " " FFJJ D  $"T7T>  r=c8|j}|j}t|jdkDrt|jtj k\r |j |jdd=^|jj\}}|||k(r#|D]}|j|||||ksn|||j|}|+|||k(r#|D]}|j|||||ksnt|jdkDryy)z Processes the deductions that have been pushed onto ``deduction_stack``, described on Pg. 166 [1] and is used in coset-table based enumeration. See Also ======== deduction_stack rN) rr!rr&r max_stack_sizerr]rZr#) r+R_c_x R_c_x_invrr!rKr.rtrNs rprocess_deductionszCosetTable.process_deductionss FF $&&'!+4''(J,E,EE!((+//335qU8u$"" E1-U8e+!"< A/DAdGtO"AKKa(w~$&&'!+r=cDj}tjdkDryjj\}t fd|Dsy|j |t fd|DsytjdkDryy)z A variation of ``process_deductions``, this calls ``scan_check`` wherever ``process_deductions`` calls ``scan``, described on Pg. [1]. See Also ======== process_deductions rc3BK|]}j|ywrCro)rrtrKr+s rrz6CosetTable.process_deductions_check..s@Qtua0@Fc3BK|]}j|ywrCr)rrtrNr+s rrz6CosetTable.process_deductions_check..sG4??43GrT)r!rr&r]allr#)r+rrr!r.rKrNs` @@rprocess_deductions_checkz#CosetTable.process_deductions_checks $&&'!+++//1HE1@%@@< A/DGYGG $&&'!+r=c|j}|j}|j}|D]}||||}||||||||<|||||<tt |j D]I}|j ||k(s|||||k(r |||||<0|||||k(s?|||||<Ky)zSwitch the elements `\beta, \gamma \in \Omega` of ``self``, used by the ``standardize`` procedure, described on Pg. 167 [1]. See Also ======== standardize N)rr#r!r(rr) r+rNr`rr#r!r.zrKs rswitchzCosetTable.switchs FF  7Ae VAY'A&+Dk&)&>> from sympy.combinatorics import free_group >>> from sympy.combinatorics.fp_groups import FpGroup, coset_enumeration_r >>> F, x, y = free_group("x, y") # Example 5.3 from [1] >>> f = FpGroup(F, [x**2*y**2, x**3*y**5]) >>> C = coset_enumeration_r(f, []) >>> C.compress() >>> C.table [[1, 3, 1, 3], [2, 0, 2, 0], [3, 1, 3, 1], [0, 2, 0, 2]] >>> C.standardize() >>> C.table [[1, 2, 1, 2], [3, 0, 3, 0], [0, 3, 0, 3], [2, 1, 2, 1]] rN)rr#rr(r@r!r)r+rr#r`rKr.rNs r standardizezCosetTable.standardizesF FFdff q1 HE1::e$VAY/Du}%<KKt, DFF? r=c d}|j}|j}|j}|j}t t t |jDcgc]}|j||k7s|c}}|jD]8}|dz }||k7s|D]&} |||| } | |||| <|| || |k((:tt |dz|_|t |jd=|D]?} t t |jD]} | | xxt|| | zcc<Aycc}w)z]Removes the non-live cosets from the coset table, described on pg. 167 [1]. rrN) rr#r$r!tupler(rrr4rr) r+r`rr#r$r!r0chirKr.rNrowrYs rcompresszCosetTable.compresss=  FF__  c$&&k 2E1dffQi1nQEFZZ 8E QJE~ 8A <q 2D.2E%L+$K 1 .%7 8 8eEAI&' #dff+,  3C3tvv;' 3A+c3q622 3 3)Fs D;0D;c8ttjd|D}t}|D]}|j |}g}|j D]<}|Dchc] }|d|k(s |}}|j ||j|>|Scc}w)Nc3bK|]'}|j|dzjf)ywr cyclic_conjugatesrrels rrz(CosetTable.conjugates..Bs6'=36),(=(=(?b++-(/'=-/r)rrrsetunionrrIdifference_update) r+rR_cR_set conjugateR_c_listr.rUrWs r conjugateszCosetTable.conjugatesAs5&&'=:;'==> +IKK *E + 'A"'8$47a<8A8 OOA   # #A & '9s  B+Bc|jD]\}|j||j|}|dk(r|jjcS||ksE|j ||dzzcSy)a Compute the coset representative of a given coset. Examples ======== >>> from sympy.combinatorics import free_group >>> from sympy.combinatorics.fp_groups import FpGroup, coset_enumeration_r >>> F, x, y = free_group("x, y") >>> f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y]) >>> C = coset_enumeration_r(f, [x]) >>> C.compress() >>> C.table [[0, 0, 1, 2], [1, 1, 2, 0], [2, 2, 0, 1]] >>> C.coset_representative(0) >>> C.coset_representative(1) y >>> C.coset_representative(2) y**-1 rrN)rr!r#rrJcoset_representative)r+r3r.r`s rrzCosetTable.coset_representativeNsj. >AJJu%dkk!n5Ez}}---u}0072==  >r=c,|j||dy)a Define a function p_p from from [1..n] to A* as an additional component of the modified coset table. Parameters ========== \alpha \in \Omega x \in A* See Also ======== define TreN)rO)r+rKr.s rmodified_definezCosetTable.modified_defineps" E1t ,r=c0|j||||dy)z Parameters ========== \alpha \in \Omega w \in A* y \in (YUY^-1) fill -- `modified_scan_and_fill` when set to True. See Also ======== scan T)rhrirLNr)r+rKrtrhris r modified_scanzCosetTable.modified_scans %adT :r=c.|j|||dy)NTr~)r)r+rKrtrhs rmodified_scan_and_fillz!CosetTable.modified_scan_and_fills 5!QT2r=c0|j||||dy)a Parameters ========== 'k', 'lamda' -- the two class representatives to be merged. q -- queue of length l of elements to be deleted from `\Omega` *. w -- Word in (YUY^-1) See Also ======== merge TrtrLN)r\)r+rrrsrtr_s rr|zCosetTable.modified_merges 1eQ!d 3r=c*|j|dy)z Parameters ========== `k \in [0 \ldots n-1]` See Also ======== rep TreN)r^)r+rrs r modified_repzCosetTable.modified_reps T"r=c.|j|||dy)z Parameters ========== A coincident pair `\alpha, \beta \in \Omega, w \in Y \cup Y^{-1}` See Also ======== coincidence TrN)rg)r+rKrNrts rrfzCosetTable.modified_coincidences D9r=rC)F)NFF)NF)(__name__ __module__ __qualname____doc__rrrr1propertyr4r9r<__repr__r@rErOrQrZrSrmror\r^rgrrrrrrrrrrrrrr|rrfrr=rr r s.$N@QQ 1H ##J%0N0<*6^#6J^;D*X&PDP8Cv ***Z(@,70-` 3D >D-&; 34 # :r=r Nc$t|||}|r|j}|j}n|j}|j}|r(|j dd|_|j dd|_|j} |j} |j } tt|D]5} |r%|d|| |jj| *|d|| 7d} | |jkr| | | k(rj | D]6}|r|| ||jjn || || | | ks6n| | | k(r&| D]!}|j | | ||| |#| dz } | |jkr|S#t$r}|r|cYd}~S|d}~wwxYw)a This is easier of the two implemented methods of coset enumeration. and is often called the HLT method, after Hazelgrove, Leech, Trotter The idea is that we make use of ``scan_and_fill`` makes new definitions whenever the scan is incomplete to enable the scan to complete; this way we fill in the gaps in the scan of the relator or subgroup generator, that's why the name relator-based method. An instance of `CosetTable` for `fp_grp` can be passed as the keyword argument `draft` in which case the coset enumeration will start with that instance and attempt to complete it. When `incomplete` is `True` and the function is unable to complete for some reason, the partially complete table will be returned. # TODO: complete the docstring See Also ======== scan_and_fill, Examples ======== >>> from sympy.combinatorics.free_groups import free_group >>> from sympy.combinatorics.fp_groups import FpGroup, coset_enumeration_r >>> F, x, y = free_group("x, y") # Example 5.1 from [1] >>> f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y]) >>> C = coset_enumeration_r(f, [x]) >>> for i in range(len(C.p)): ... if C.p[i] == i: ... print(C.table[i]) [0, 0, 1, 2] [1, 1, 2, 0] [2, 2, 0, 1] >>> C.p [0, 1, 2, 1, 1] # Example from exercises Q2 [1] >>> f = FpGroup(F, [x**2*y**2, y**-1*x*y*x**-3]) >>> C = coset_enumeration_r(f, []) >>> C.compress(); C.standardize() >>> C.table [[1, 2, 3, 4], [5, 0, 6, 7], [0, 5, 7, 6], [7, 6, 5, 0], [6, 7, 0, 5], [2, 1, 4, 3], [3, 4, 2, 1], [4, 3, 1, 2]] # Example 5.2 >>> f = FpGroup(F, [x**2, y**3, (x*y)**3]) >>> Y = [x*y] >>> C = coset_enumeration_r(f, Y) >>> for i in range(len(C.p)): ... if C.p[i] == i: ... print(C.table[i]) [1, 1, 2, 1] [0, 0, 0, 2] [3, 3, 1, 0] [2, 2, 3, 3] # Example 5.3 >>> f = FpGroup(F, [x**2*y**2, x**3*y**5]) >>> Y = [] >>> C = coset_enumeration_r(f, Y) >>> for i in range(len(C.p)): ... if C.p[i] == i: ... print(C.table[i]) [1, 3, 1, 3] [2, 0, 2, 0] [3, 1, 3, 1] [0, 2, 0, 2] # Example 5.4 >>> F, a, b, c, d, e = free_group("a, b, c, d, e") >>> f = FpGroup(F, [a*b*c**-1, b*c*d**-1, c*d*e**-1, d*e*a**-1, e*a*b**-1]) >>> Y = [a] >>> C = coset_enumeration_r(f, Y) >>> for i in range(len(C.p)): ... if C.p[i] == i: ... print(C.table[i]) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # example of "compress" method >>> C.compress() >>> C.table [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] # Exercises Pg. 161, Q2. >>> F, x, y = free_group("x, y") >>> f = FpGroup(F, [x**2*y**2, y**-1*x*y*x**-3]) >>> Y = [] >>> C = coset_enumeration_r(f, Y) >>> C.compress() >>> C.standardize() >>> C.table [[1, 2, 3, 4], [5, 0, 6, 7], [0, 5, 7, 6], [7, 6, 5, 0], [6, 7, 0, 5], [2, 1, 4, 3], [3, 4, 2, 1], [4, 3, 1, 2]] # John J. Cannon; Lucien A. Dimino; George Havas; Jane M. Watson # Mathematics of Computation, Vol. 27, No. 123. (Jul., 1973), pp. 463-490 # from 1973chwd.pdf # Table 1. Ex. 1 >>> F, r, s, t = free_group("r, s, t") >>> E1 = FpGroup(F, [t**-1*r*t*r**-2, r**-1*s*r*s**-2, s**-1*t*s*t**-2]) >>> C = coset_enumeration_r(E1, [r]) >>> for i in range(len(C.p)): ... if C.p[i] == i: ... print(C.table[i]) [0, 0, 0, 0, 0, 0] Ex. 2 >>> F, a, b = free_group("a, b") >>> Cox = FpGroup(F, [a**6, b**6, (a*b)**2, (a**2*b**2)**2, (a**3*b**3)**5]) >>> C = coset_enumeration_r(Cox, [a]) >>> index = 0 >>> for i in range(len(C.p)): ... if C.p[i] == i: ... index += 1 >>> index 500 # Ex. 3 >>> F, a, b = free_group("a, b") >>> B_2_4 = FpGroup(F, [a**4, b**4, (a*b)**4, (a**-1*b)**4, (a**2*b)**4, (a*b**2)**4, (a**2*b**2)**4, (a**-1*b*a*b)**4, (a*b**-1*a*b)**4]) >>> C = coset_enumeration_r(B_2_4, [a]) >>> index = 0 >>> for i in range(len(C.p)): ... if C.p[i] == i: ... index += 1 >>> index 1024 References ========== .. [1] Holt, D., Eick, B., O'Brien, E. "Handbook of computational group theory" r-Nrr)r rrrrOr!rrr#r(rr)rr@rJrH)r,Yr-draft incompleterLC_scan_and_fill_definerr#rr0rKrtr.es rcoset_enumeration_rrsx 614A11##(( ++a.ggajA XXF A 3q6]$  1adAFF$5$5a$8 9 1ad # $ E !##+ U8u  A&uaA&ua0x%'U8u$#.775>&)4<#E1-.  ' !##+( H  H s067E6.%E6 E66 F?F FF  Fc$t|||||dS)a Introduce a new set of symbols y \in Y that correspond to the generators of the subgroup. Store the elements of Y as a word P[\alpha, x] and compute the coset table similar to that of the regular coset enumeration methods. Examples ======== >>> from sympy.combinatorics.free_groups import free_group >>> from sympy.combinatorics.fp_groups import FpGroup >>> from sympy.combinatorics.coset_table import modified_coset_enumeration_r >>> F, x, y = free_group("x, y") >>> f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y]) >>> C = modified_coset_enumeration_r(f, [x]) >>> C.table [[0, 0, 1, 2], [1, 1, 2, 0], [2, 2, 0, 1], [None, 1, None, None], [1, 3, None, None]] See Also ======== coset_enumertation_r References ========== .. [1] Holt, D., Eick, B., O'Brien, E., "Handbook of Computational Group Theory", Section 5.3.2 T)r-rrrL)r)r,rr-rrs rmodified_coset_enumeration_rrs!@ vqZu(2T CCr=c|j}|j}t|||}|r|jdd|_|jdd|_|j |_t tt|j|D]B\}} |j||j| &|j j|| fD|j} |D cgc]} | j} } ttjd| D} t!}| D]}|j#|}g}|jD]<} |Dchc] }|d| k(s |}}|j||j%|>|D]}|j'd|| D]4} |j)||j| ||j*| 6d}|t|jkr|j||k(r |jD]z} |j||k7rnf|j||j| 7|j-|| |j)||j| ||j*| ||dz }|t|jkr|Scc} wcc}w#t.$r}|r|cYd}~S|d}~wwxYw)aV >>> from sympy.combinatorics.free_groups import free_group >>> from sympy.combinatorics.fp_groups import FpGroup, coset_enumeration_c >>> F, x, y = free_group("x, y") >>> f = FpGroup(F, [x**3, y**3, x**-1*y**-1*x*y]) >>> C = coset_enumeration_c(f, [x]) >>> C.table [[0, 0, 1, 2], [1, 1, 2, 0], [2, 2, 0, 1]] rNc3bK|]'}|j|dzjf)ywr rrs rrz&coset_enumeration_c..s3#"%($9$9$;c2g=X=X=Z#[#"rrr)rrr r!rr&rr(rr#rIridentity_cyclic_reductionrrrrrrrrr$rQrH)r,rr-rrXrrrKr.rr R_cyc_redrrrrrUrWrtrs rcoset_enumeration_crs AA614A ++a.ggaj!11c!''l 3Q7 5HE1wwu~ahhqk*6!!((%4 5 A<=>S..0>I> u""#" #"" #C EE'  I&'H SS## 4dtAw!|T 4 4 "#  !Q O Xahhqk2HQ\\!_4MNO E #agg,  33u:  _Ass5zU*wwu~ahhqk2: 5!,,,Xahhqk-BHQ\\Z[_D]^ _   #agg,  H?? 5" H s>J4 J9"J9 AJ>AJ>> KK KKK)NNFF)NNF) sympy.combinatorics.free_groupsrsympy.printing.defaultsr itertoolsrrbisectrr rrrrr=rrsM63$u:u:x;??DD LDH/4!CJ;?;@8 r=