permutations.py 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114
  1. import random
  2. from collections import defaultdict
  3. from collections.abc import Iterable
  4. from functools import reduce
  5. from sympy.core.parameters import global_parameters
  6. from sympy.core.basic import Atom
  7. from sympy.core.expr import Expr
  8. from sympy.core.numbers import int_valued
  9. from sympy.core.numbers import Integer
  10. from sympy.core.sympify import _sympify
  11. from sympy.matrices import zeros
  12. from sympy.polys.polytools import lcm
  13. from sympy.printing.repr import srepr
  14. from sympy.utilities.iterables import (flatten, has_variety, minlex,
  15. has_dups, runs, is_sequence)
  16. from sympy.utilities.misc import as_int
  17. from mpmath.libmp.libintmath import ifac
  18. from sympy.multipledispatch import dispatch
  19. def _af_rmul(a, b):
  20. """
  21. Return the product b*a; input and output are array forms. The ith value
  22. is a[b[i]].
  23. Examples
  24. ========
  25. >>> from sympy.combinatorics.permutations import _af_rmul, Permutation
  26. >>> a, b = [1, 0, 2], [0, 2, 1]
  27. >>> _af_rmul(a, b)
  28. [1, 2, 0]
  29. >>> [a[b[i]] for i in range(3)]
  30. [1, 2, 0]
  31. This handles the operands in reverse order compared to the ``*`` operator:
  32. >>> a = Permutation(a)
  33. >>> b = Permutation(b)
  34. >>> list(a*b)
  35. [2, 0, 1]
  36. >>> [b(a(i)) for i in range(3)]
  37. [2, 0, 1]
  38. See Also
  39. ========
  40. rmul, _af_rmuln
  41. """
  42. return [a[i] for i in b]
  43. def _af_rmuln(*abc):
  44. """
  45. Given [a, b, c, ...] return the product of ...*c*b*a using array forms.
  46. The ith value is a[b[c[i]]].
  47. Examples
  48. ========
  49. >>> from sympy.combinatorics.permutations import _af_rmul, Permutation
  50. >>> a, b = [1, 0, 2], [0, 2, 1]
  51. >>> _af_rmul(a, b)
  52. [1, 2, 0]
  53. >>> [a[b[i]] for i in range(3)]
  54. [1, 2, 0]
  55. This handles the operands in reverse order compared to the ``*`` operator:
  56. >>> a = Permutation(a); b = Permutation(b)
  57. >>> list(a*b)
  58. [2, 0, 1]
  59. >>> [b(a(i)) for i in range(3)]
  60. [2, 0, 1]
  61. See Also
  62. ========
  63. rmul, _af_rmul
  64. """
  65. a = abc
  66. m = len(a)
  67. if m == 3:
  68. p0, p1, p2 = a
  69. return [p0[p1[i]] for i in p2]
  70. if m == 4:
  71. p0, p1, p2, p3 = a
  72. return [p0[p1[p2[i]]] for i in p3]
  73. if m == 5:
  74. p0, p1, p2, p3, p4 = a
  75. return [p0[p1[p2[p3[i]]]] for i in p4]
  76. if m == 6:
  77. p0, p1, p2, p3, p4, p5 = a
  78. return [p0[p1[p2[p3[p4[i]]]]] for i in p5]
  79. if m == 7:
  80. p0, p1, p2, p3, p4, p5, p6 = a
  81. return [p0[p1[p2[p3[p4[p5[i]]]]]] for i in p6]
  82. if m == 8:
  83. p0, p1, p2, p3, p4, p5, p6, p7 = a
  84. return [p0[p1[p2[p3[p4[p5[p6[i]]]]]]] for i in p7]
  85. if m == 1:
  86. return a[0][:]
  87. if m == 2:
  88. a, b = a
  89. return [a[i] for i in b]
  90. if m == 0:
  91. raise ValueError("String must not be empty")
  92. p0 = _af_rmuln(*a[:m//2])
  93. p1 = _af_rmuln(*a[m//2:])
  94. return [p0[i] for i in p1]
  95. def _af_parity(pi):
  96. """
  97. Computes the parity of a permutation in array form.
  98. Explanation
  99. ===========
  100. The parity of a permutation reflects the parity of the
  101. number of inversions in the permutation, i.e., the
  102. number of pairs of x and y such that x > y but p[x] < p[y].
  103. Examples
  104. ========
  105. >>> from sympy.combinatorics.permutations import _af_parity
  106. >>> _af_parity([0, 1, 2, 3])
  107. 0
  108. >>> _af_parity([3, 2, 0, 1])
  109. 1
  110. See Also
  111. ========
  112. Permutation
  113. """
  114. n = len(pi)
  115. a = [0] * n
  116. c = 0
  117. for j in range(n):
  118. if a[j] == 0:
  119. c += 1
  120. a[j] = 1
  121. i = j
  122. while pi[i] != j:
  123. i = pi[i]
  124. a[i] = 1
  125. return (n - c) % 2
  126. def _af_invert(a):
  127. """
  128. Finds the inverse, ~A, of a permutation, A, given in array form.
  129. Examples
  130. ========
  131. >>> from sympy.combinatorics.permutations import _af_invert, _af_rmul
  132. >>> A = [1, 2, 0, 3]
  133. >>> _af_invert(A)
  134. [2, 0, 1, 3]
  135. >>> _af_rmul(_, A)
  136. [0, 1, 2, 3]
  137. See Also
  138. ========
  139. Permutation, __invert__
  140. """
  141. inv_form = [0] * len(a)
  142. for i, ai in enumerate(a):
  143. inv_form[ai] = i
  144. return inv_form
  145. def _af_pow(a, n):
  146. """
  147. Routine for finding powers of a permutation.
  148. Examples
  149. ========
  150. >>> from sympy.combinatorics import Permutation
  151. >>> from sympy.combinatorics.permutations import _af_pow
  152. >>> p = Permutation([2, 0, 3, 1])
  153. >>> p.order()
  154. 4
  155. >>> _af_pow(p._array_form, 4)
  156. [0, 1, 2, 3]
  157. """
  158. if n == 0:
  159. return list(range(len(a)))
  160. if n < 0:
  161. return _af_pow(_af_invert(a), -n)
  162. if n == 1:
  163. return a[:]
  164. elif n == 2:
  165. b = [a[i] for i in a]
  166. elif n == 3:
  167. b = [a[a[i]] for i in a]
  168. elif n == 4:
  169. b = [a[a[a[i]]] for i in a]
  170. else:
  171. # use binary multiplication
  172. b = list(range(len(a)))
  173. while 1:
  174. if n & 1:
  175. b = [b[i] for i in a]
  176. n -= 1
  177. if not n:
  178. break
  179. if n % 4 == 0:
  180. a = [a[a[a[i]]] for i in a]
  181. n = n // 4
  182. elif n % 2 == 0:
  183. a = [a[i] for i in a]
  184. n = n // 2
  185. return b
  186. def _af_commutes_with(a, b):
  187. """
  188. Checks if the two permutations with array forms
  189. given by ``a`` and ``b`` commute.
  190. Examples
  191. ========
  192. >>> from sympy.combinatorics.permutations import _af_commutes_with
  193. >>> _af_commutes_with([1, 2, 0], [0, 2, 1])
  194. False
  195. See Also
  196. ========
  197. Permutation, commutes_with
  198. """
  199. return not any(a[b[i]] != b[a[i]] for i in range(len(a) - 1))
  200. class Cycle(dict):
  201. """
  202. Wrapper around dict which provides the functionality of a disjoint cycle.
  203. Explanation
  204. ===========
  205. A cycle shows the rule to use to move subsets of elements to obtain
  206. a permutation. The Cycle class is more flexible than Permutation in
  207. that 1) all elements need not be present in order to investigate how
  208. multiple cycles act in sequence and 2) it can contain singletons:
  209. >>> from sympy.combinatorics.permutations import Perm, Cycle
  210. A Cycle will automatically parse a cycle given as a tuple on the rhs:
  211. >>> Cycle(1, 2)(2, 3)
  212. (1 3 2)
  213. The identity cycle, Cycle(), can be used to start a product:
  214. >>> Cycle()(1, 2)(2, 3)
  215. (1 3 2)
  216. The array form of a Cycle can be obtained by calling the list
  217. method (or passing it to the list function) and all elements from
  218. 0 will be shown:
  219. >>> a = Cycle(1, 2)
  220. >>> a.list()
  221. [0, 2, 1]
  222. >>> list(a)
  223. [0, 2, 1]
  224. If a larger (or smaller) range is desired use the list method and
  225. provide the desired size -- but the Cycle cannot be truncated to
  226. a size smaller than the largest element that is out of place:
  227. >>> b = Cycle(2, 4)(1, 2)(3, 1, 4)(1, 3)
  228. >>> b.list()
  229. [0, 2, 1, 3, 4]
  230. >>> b.list(b.size + 1)
  231. [0, 2, 1, 3, 4, 5]
  232. >>> b.list(-1)
  233. [0, 2, 1]
  234. Singletons are not shown when printing with one exception: the largest
  235. element is always shown -- as a singleton if necessary:
  236. >>> Cycle(1, 4, 10)(4, 5)
  237. (1 5 4 10)
  238. >>> Cycle(1, 2)(4)(5)(10)
  239. (1 2)(10)
  240. The array form can be used to instantiate a Permutation so other
  241. properties of the permutation can be investigated:
  242. >>> Perm(Cycle(1, 2)(3, 4).list()).transpositions()
  243. [(1, 2), (3, 4)]
  244. Notes
  245. =====
  246. The underlying structure of the Cycle is a dictionary and although
  247. the __iter__ method has been redefined to give the array form of the
  248. cycle, the underlying dictionary items are still available with the
  249. such methods as items():
  250. >>> list(Cycle(1, 2).items())
  251. [(1, 2), (2, 1)]
  252. See Also
  253. ========
  254. Permutation
  255. """
  256. def __missing__(self, arg):
  257. """Enter arg into dictionary and return arg."""
  258. return as_int(arg)
  259. def __iter__(self):
  260. yield from self.list()
  261. def __call__(self, *other):
  262. """Return product of cycles processed from R to L.
  263. Examples
  264. ========
  265. >>> from sympy.combinatorics import Cycle
  266. >>> Cycle(1, 2)(2, 3)
  267. (1 3 2)
  268. An instance of a Cycle will automatically parse list-like
  269. objects and Permutations that are on the right. It is more
  270. flexible than the Permutation in that all elements need not
  271. be present:
  272. >>> a = Cycle(1, 2)
  273. >>> a(2, 3)
  274. (1 3 2)
  275. >>> a(2, 3)(4, 5)
  276. (1 3 2)(4 5)
  277. """
  278. rv = Cycle(*other)
  279. for k, v in zip(list(self.keys()), [rv[self[k]] for k in self.keys()]):
  280. rv[k] = v
  281. return rv
  282. def list(self, size=None):
  283. """Return the cycles as an explicit list starting from 0 up
  284. to the greater of the largest value in the cycles and size.
  285. Truncation of trailing unmoved items will occur when size
  286. is less than the maximum element in the cycle; if this is
  287. desired, setting ``size=-1`` will guarantee such trimming.
  288. Examples
  289. ========
  290. >>> from sympy.combinatorics import Cycle
  291. >>> p = Cycle(2, 3)(4, 5)
  292. >>> p.list()
  293. [0, 1, 3, 2, 5, 4]
  294. >>> p.list(10)
  295. [0, 1, 3, 2, 5, 4, 6, 7, 8, 9]
  296. Passing a length too small will trim trailing, unchanged elements
  297. in the permutation:
  298. >>> Cycle(2, 4)(1, 2, 4).list(-1)
  299. [0, 2, 1]
  300. """
  301. if not self and size is None:
  302. raise ValueError('must give size for empty Cycle')
  303. if size is not None:
  304. big = max([i for i in self.keys() if self[i] != i] + [0])
  305. size = max(size, big + 1)
  306. else:
  307. size = self.size
  308. return [self[i] for i in range(size)]
  309. def __repr__(self):
  310. """We want it to print as a Cycle, not as a dict.
  311. Examples
  312. ========
  313. >>> from sympy.combinatorics import Cycle
  314. >>> Cycle(1, 2)
  315. (1 2)
  316. >>> print(_)
  317. (1 2)
  318. >>> list(Cycle(1, 2).items())
  319. [(1, 2), (2, 1)]
  320. """
  321. if not self:
  322. return 'Cycle()'
  323. cycles = Permutation(self).cyclic_form
  324. s = ''.join(str(tuple(c)) for c in cycles)
  325. big = self.size - 1
  326. if not any(i == big for c in cycles for i in c):
  327. s += '(%s)' % big
  328. return 'Cycle%s' % s
  329. def __str__(self):
  330. """We want it to be printed in a Cycle notation with no
  331. comma in-between.
  332. Examples
  333. ========
  334. >>> from sympy.combinatorics import Cycle
  335. >>> Cycle(1, 2)
  336. (1 2)
  337. >>> Cycle(1, 2, 4)(5, 6)
  338. (1 2 4)(5 6)
  339. """
  340. if not self:
  341. return '()'
  342. cycles = Permutation(self).cyclic_form
  343. s = ''.join(str(tuple(c)) for c in cycles)
  344. big = self.size - 1
  345. if not any(i == big for c in cycles for i in c):
  346. s += '(%s)' % big
  347. s = s.replace(',', '')
  348. return s
  349. def __init__(self, *args):
  350. """Load up a Cycle instance with the values for the cycle.
  351. Examples
  352. ========
  353. >>> from sympy.combinatorics import Cycle
  354. >>> Cycle(1, 2, 6)
  355. (1 2 6)
  356. """
  357. if not args:
  358. return
  359. if len(args) == 1:
  360. if isinstance(args[0], Permutation):
  361. for c in args[0].cyclic_form:
  362. self.update(self(*c))
  363. return
  364. elif isinstance(args[0], Cycle):
  365. for k, v in args[0].items():
  366. self[k] = v
  367. return
  368. args = [as_int(a) for a in args]
  369. if any(i < 0 for i in args):
  370. raise ValueError('negative integers are not allowed in a cycle.')
  371. if has_dups(args):
  372. raise ValueError('All elements must be unique in a cycle.')
  373. for i in range(-len(args), 0):
  374. self[args[i]] = args[i + 1]
  375. @property
  376. def size(self):
  377. if not self:
  378. return 0
  379. return max(self.keys()) + 1
  380. def copy(self):
  381. return Cycle(self)
  382. class Permutation(Atom):
  383. r"""
  384. A permutation, alternatively known as an 'arrangement number' or 'ordering'
  385. is an arrangement of the elements of an ordered list into a one-to-one
  386. mapping with itself. The permutation of a given arrangement is given by
  387. indicating the positions of the elements after re-arrangement [2]_. For
  388. example, if one started with elements ``[x, y, a, b]`` (in that order) and
  389. they were reordered as ``[x, y, b, a]`` then the permutation would be
  390. ``[0, 1, 3, 2]``. Notice that (in SymPy) the first element is always referred
  391. to as 0 and the permutation uses the indices of the elements in the
  392. original ordering, not the elements ``(a, b, ...)`` themselves.
  393. >>> from sympy.combinatorics import Permutation
  394. >>> from sympy import init_printing
  395. >>> init_printing(perm_cyclic=False, pretty_print=False)
  396. Permutations Notation
  397. =====================
  398. Permutations are commonly represented in disjoint cycle or array forms.
  399. Array Notation and 2-line Form
  400. ------------------------------------
  401. In the 2-line form, the elements and their final positions are shown
  402. as a matrix with 2 rows:
  403. [0 1 2 ... n-1]
  404. [p(0) p(1) p(2) ... p(n-1)]
  405. Since the first line is always ``range(n)``, where n is the size of p,
  406. it is sufficient to represent the permutation by the second line,
  407. referred to as the "array form" of the permutation. This is entered
  408. in brackets as the argument to the Permutation class:
  409. >>> p = Permutation([0, 2, 1]); p
  410. Permutation([0, 2, 1])
  411. Given i in range(p.size), the permutation maps i to i^p
  412. >>> [i^p for i in range(p.size)]
  413. [0, 2, 1]
  414. The composite of two permutations p*q means first apply p, then q, so
  415. i^(p*q) = (i^p)^q which is i^p^q according to Python precedence rules:
  416. >>> q = Permutation([2, 1, 0])
  417. >>> [i^p^q for i in range(3)]
  418. [2, 0, 1]
  419. >>> [i^(p*q) for i in range(3)]
  420. [2, 0, 1]
  421. One can use also the notation p(i) = i^p, but then the composition
  422. rule is (p*q)(i) = q(p(i)), not p(q(i)):
  423. >>> [(p*q)(i) for i in range(p.size)]
  424. [2, 0, 1]
  425. >>> [q(p(i)) for i in range(p.size)]
  426. [2, 0, 1]
  427. >>> [p(q(i)) for i in range(p.size)]
  428. [1, 2, 0]
  429. Disjoint Cycle Notation
  430. -----------------------
  431. In disjoint cycle notation, only the elements that have shifted are
  432. indicated.
  433. For example, [1, 3, 2, 0] can be represented as (0, 1, 3)(2).
  434. This can be understood from the 2 line format of the given permutation.
  435. In the 2-line form,
  436. [0 1 2 3]
  437. [1 3 2 0]
  438. The element in the 0th position is 1, so 0 -> 1. The element in the 1st
  439. position is three, so 1 -> 3. And the element in the third position is again
  440. 0, so 3 -> 0. Thus, 0 -> 1 -> 3 -> 0, and 2 -> 2. Thus, this can be represented
  441. as 2 cycles: (0, 1, 3)(2).
  442. In common notation, singular cycles are not explicitly written as they can be
  443. inferred implicitly.
  444. Only the relative ordering of elements in a cycle matter:
  445. >>> Permutation(1,2,3) == Permutation(2,3,1) == Permutation(3,1,2)
  446. True
  447. The disjoint cycle notation is convenient when representing
  448. permutations that have several cycles in them:
  449. >>> Permutation(1, 2)(3, 5) == Permutation([[1, 2], [3, 5]])
  450. True
  451. It also provides some economy in entry when computing products of
  452. permutations that are written in disjoint cycle notation:
  453. >>> Permutation(1, 2)(1, 3)(2, 3)
  454. Permutation([0, 3, 2, 1])
  455. >>> _ == Permutation([[1, 2]])*Permutation([[1, 3]])*Permutation([[2, 3]])
  456. True
  457. Caution: when the cycles have common elements between them then the order
  458. in which the permutations are applied matters. This module applies
  459. the permutations from *left to right*.
  460. >>> Permutation(1, 2)(2, 3) == Permutation([(1, 2), (2, 3)])
  461. True
  462. >>> Permutation(1, 2)(2, 3).list()
  463. [0, 3, 1, 2]
  464. In the above case, (1,2) is computed before (2,3).
  465. As 0 -> 0, 0 -> 0, element in position 0 is 0.
  466. As 1 -> 2, 2 -> 3, element in position 1 is 3.
  467. As 2 -> 1, 1 -> 1, element in position 2 is 1.
  468. As 3 -> 3, 3 -> 2, element in position 3 is 2.
  469. If the first and second elements had been
  470. swapped first, followed by the swapping of the second
  471. and third, the result would have been [0, 2, 3, 1].
  472. If, you want to apply the cycles in the conventional
  473. right to left order, call the function with arguments in reverse order
  474. as demonstrated below:
  475. >>> Permutation([(1, 2), (2, 3)][::-1]).list()
  476. [0, 2, 3, 1]
  477. Entering a singleton in a permutation is a way to indicate the size of the
  478. permutation. The ``size`` keyword can also be used.
  479. Array-form entry:
  480. >>> Permutation([[1, 2], [9]])
  481. Permutation([0, 2, 1], size=10)
  482. >>> Permutation([[1, 2]], size=10)
  483. Permutation([0, 2, 1], size=10)
  484. Cyclic-form entry:
  485. >>> Permutation(1, 2, size=10)
  486. Permutation([0, 2, 1], size=10)
  487. >>> Permutation(9)(1, 2)
  488. Permutation([0, 2, 1], size=10)
  489. Caution: no singleton containing an element larger than the largest
  490. in any previous cycle can be entered. This is an important difference
  491. in how Permutation and Cycle handle the ``__call__`` syntax. A singleton
  492. argument at the start of a Permutation performs instantiation of the
  493. Permutation and is permitted:
  494. >>> Permutation(5)
  495. Permutation([], size=6)
  496. A singleton entered after instantiation is a call to the permutation
  497. -- a function call -- and if the argument is out of range it will
  498. trigger an error. For this reason, it is better to start the cycle
  499. with the singleton:
  500. The following fails because there is no element 3:
  501. >>> Permutation(1, 2)(3)
  502. Traceback (most recent call last):
  503. ...
  504. IndexError: list index out of range
  505. This is ok: only the call to an out of range singleton is prohibited;
  506. otherwise the permutation autosizes:
  507. >>> Permutation(3)(1, 2)
  508. Permutation([0, 2, 1, 3])
  509. >>> Permutation(1, 2)(3, 4) == Permutation(3, 4)(1, 2)
  510. True
  511. Equality testing
  512. ----------------
  513. The array forms must be the same in order for permutations to be equal:
  514. >>> Permutation([1, 0, 2, 3]) == Permutation([1, 0])
  515. False
  516. Identity Permutation
  517. --------------------
  518. The identity permutation is a permutation in which no element is out of
  519. place. It can be entered in a variety of ways. All the following create
  520. an identity permutation of size 4:
  521. >>> I = Permutation([0, 1, 2, 3])
  522. >>> all(p == I for p in [
  523. ... Permutation(3),
  524. ... Permutation(range(4)),
  525. ... Permutation([], size=4),
  526. ... Permutation(size=4)])
  527. True
  528. Watch out for entering the range *inside* a set of brackets (which is
  529. cycle notation):
  530. >>> I == Permutation([range(4)])
  531. False
  532. Permutation Printing
  533. ====================
  534. There are a few things to note about how Permutations are printed.
  535. .. deprecated:: 1.6
  536. Configuring Permutation printing by setting
  537. ``Permutation.print_cyclic`` is deprecated. Users should use the
  538. ``perm_cyclic`` flag to the printers, as described below.
  539. 1) If you prefer one form (array or cycle) over another, you can set
  540. ``init_printing`` with the ``perm_cyclic`` flag.
  541. >>> from sympy import init_printing
  542. >>> p = Permutation(1, 2)(4, 5)(3, 4)
  543. >>> p
  544. Permutation([0, 2, 1, 4, 5, 3])
  545. >>> init_printing(perm_cyclic=True, pretty_print=False)
  546. >>> p
  547. (1 2)(3 4 5)
  548. 2) Regardless of the setting, a list of elements in the array for cyclic
  549. form can be obtained and either of those can be copied and supplied as
  550. the argument to Permutation:
  551. >>> p.array_form
  552. [0, 2, 1, 4, 5, 3]
  553. >>> p.cyclic_form
  554. [[1, 2], [3, 4, 5]]
  555. >>> Permutation(_) == p
  556. True
  557. 3) Printing is economical in that as little as possible is printed while
  558. retaining all information about the size of the permutation:
  559. >>> init_printing(perm_cyclic=False, pretty_print=False)
  560. >>> Permutation([1, 0, 2, 3])
  561. Permutation([1, 0, 2, 3])
  562. >>> Permutation([1, 0, 2, 3], size=20)
  563. Permutation([1, 0], size=20)
  564. >>> Permutation([1, 0, 2, 4, 3, 5, 6], size=20)
  565. Permutation([1, 0, 2, 4, 3], size=20)
  566. >>> p = Permutation([1, 0, 2, 3])
  567. >>> init_printing(perm_cyclic=True, pretty_print=False)
  568. >>> p
  569. (3)(0 1)
  570. >>> init_printing(perm_cyclic=False, pretty_print=False)
  571. The 2 was not printed but it is still there as can be seen with the
  572. array_form and size methods:
  573. >>> p.array_form
  574. [1, 0, 2, 3]
  575. >>> p.size
  576. 4
  577. Short introduction to other methods
  578. ===================================
  579. The permutation can act as a bijective function, telling what element is
  580. located at a given position
  581. >>> q = Permutation([5, 2, 3, 4, 1, 0])
  582. >>> q.array_form[1] # the hard way
  583. 2
  584. >>> q(1) # the easy way
  585. 2
  586. >>> {i: q(i) for i in range(q.size)} # showing the bijection
  587. {0: 5, 1: 2, 2: 3, 3: 4, 4: 1, 5: 0}
  588. The full cyclic form (including singletons) can be obtained:
  589. >>> p.full_cyclic_form
  590. [[0, 1], [2], [3]]
  591. Any permutation can be factored into transpositions of pairs of elements:
  592. >>> Permutation([[1, 2], [3, 4, 5]]).transpositions()
  593. [(1, 2), (3, 5), (3, 4)]
  594. >>> Permutation.rmul(*[Permutation([ti], size=6) for ti in _]).cyclic_form
  595. [[1, 2], [3, 4, 5]]
  596. The number of permutations on a set of n elements is given by n! and is
  597. called the cardinality.
  598. >>> p.size
  599. 4
  600. >>> p.cardinality
  601. 24
  602. A given permutation has a rank among all the possible permutations of the
  603. same elements, but what that rank is depends on how the permutations are
  604. enumerated. (There are a number of different methods of doing so.) The
  605. lexicographic rank is given by the rank method and this rank is used to
  606. increment a permutation with addition/subtraction:
  607. >>> p.rank()
  608. 6
  609. >>> p + 1
  610. Permutation([1, 0, 3, 2])
  611. >>> p.next_lex()
  612. Permutation([1, 0, 3, 2])
  613. >>> _.rank()
  614. 7
  615. >>> p.unrank_lex(p.size, rank=7)
  616. Permutation([1, 0, 3, 2])
  617. The product of two permutations p and q is defined as their composition as
  618. functions, (p*q)(i) = q(p(i)) [6]_.
  619. >>> p = Permutation([1, 0, 2, 3])
  620. >>> q = Permutation([2, 3, 1, 0])
  621. >>> list(q*p)
  622. [2, 3, 0, 1]
  623. >>> list(p*q)
  624. [3, 2, 1, 0]
  625. >>> [q(p(i)) for i in range(p.size)]
  626. [3, 2, 1, 0]
  627. The permutation can be 'applied' to any list-like object, not only
  628. Permutations:
  629. >>> p(['zero', 'one', 'four', 'two'])
  630. ['one', 'zero', 'four', 'two']
  631. >>> p('zo42')
  632. ['o', 'z', '4', '2']
  633. If you have a list of arbitrary elements, the corresponding permutation
  634. can be found with the from_sequence method:
  635. >>> Permutation.from_sequence('SymPy')
  636. Permutation([1, 3, 2, 0, 4])
  637. Checking if a Permutation is contained in a Group
  638. =================================================
  639. Generally if you have a group of permutations G on n symbols, and
  640. you're checking if a permutation on less than n symbols is part
  641. of that group, the check will fail.
  642. Here is an example for n=5 and we check if the cycle
  643. (1,2,3) is in G:
  644. >>> from sympy import init_printing
  645. >>> init_printing(perm_cyclic=True, pretty_print=False)
  646. >>> from sympy.combinatorics import Cycle, Permutation
  647. >>> from sympy.combinatorics.perm_groups import PermutationGroup
  648. >>> G = PermutationGroup(Cycle(2, 3)(4, 5), Cycle(1, 2, 3, 4, 5))
  649. >>> p1 = Permutation(Cycle(2, 5, 3))
  650. >>> p2 = Permutation(Cycle(1, 2, 3))
  651. >>> a1 = Permutation(Cycle(1, 2, 3).list(6))
  652. >>> a2 = Permutation(Cycle(1, 2, 3)(5))
  653. >>> a3 = Permutation(Cycle(1, 2, 3),size=6)
  654. >>> for p in [p1,p2,a1,a2,a3]: p, G.contains(p)
  655. ((2 5 3), True)
  656. ((1 2 3), False)
  657. ((5)(1 2 3), True)
  658. ((5)(1 2 3), True)
  659. ((5)(1 2 3), True)
  660. The check for p2 above will fail.
  661. Checking if p1 is in G works because SymPy knows
  662. G is a group on 5 symbols, and p1 is also on 5 symbols
  663. (its largest element is 5).
  664. For ``a1``, the ``.list(6)`` call will extend the permutation to 5
  665. symbols, so the test will work as well. In the case of ``a2`` the
  666. permutation is being extended to 5 symbols by using a singleton,
  667. and in the case of ``a3`` it's extended through the constructor
  668. argument ``size=6``.
  669. There is another way to do this, which is to tell the ``contains``
  670. method that the number of symbols the group is on does not need to
  671. match perfectly the number of symbols for the permutation:
  672. >>> G.contains(p2,strict=False)
  673. True
  674. This can be via the ``strict`` argument to the ``contains`` method,
  675. and SymPy will try to extend the permutation on its own and then
  676. perform the containment check.
  677. See Also
  678. ========
  679. Cycle
  680. References
  681. ==========
  682. .. [1] Skiena, S. 'Permutations.' 1.1 in Implementing Discrete Mathematics
  683. Combinatorics and Graph Theory with Mathematica. Reading, MA:
  684. Addison-Wesley, pp. 3-16, 1990.
  685. .. [2] Knuth, D. E. The Art of Computer Programming, Vol. 4: Combinatorial
  686. Algorithms, 1st ed. Reading, MA: Addison-Wesley, 2011.
  687. .. [3] Wendy Myrvold and Frank Ruskey. 2001. Ranking and unranking
  688. permutations in linear time. Inf. Process. Lett. 79, 6 (September 2001),
  689. 281-284. DOI=10.1016/S0020-0190(01)00141-7
  690. .. [4] D. L. Kreher, D. R. Stinson 'Combinatorial Algorithms'
  691. CRC Press, 1999
  692. .. [5] Graham, R. L.; Knuth, D. E.; and Patashnik, O.
  693. Concrete Mathematics: A Foundation for Computer Science, 2nd ed.
  694. Reading, MA: Addison-Wesley, 1994.
  695. .. [6] https://en.wikipedia.org/w/index.php?oldid=499948155#Product_and_inverse
  696. .. [7] https://en.wikipedia.org/wiki/Lehmer_code
  697. """
  698. is_Permutation = True
  699. _array_form = None
  700. _cyclic_form = None
  701. _cycle_structure = None
  702. _size = None
  703. _rank = None
  704. def __new__(cls, *args, size=None, **kwargs):
  705. """
  706. Constructor for the Permutation object from a list or a
  707. list of lists in which all elements of the permutation may
  708. appear only once.
  709. Examples
  710. ========
  711. >>> from sympy.combinatorics import Permutation
  712. >>> from sympy import init_printing
  713. >>> init_printing(perm_cyclic=False, pretty_print=False)
  714. Permutations entered in array-form are left unaltered:
  715. >>> Permutation([0, 2, 1])
  716. Permutation([0, 2, 1])
  717. Permutations entered in cyclic form are converted to array form;
  718. singletons need not be entered, but can be entered to indicate the
  719. largest element:
  720. >>> Permutation([[4, 5, 6], [0, 1]])
  721. Permutation([1, 0, 2, 3, 5, 6, 4])
  722. >>> Permutation([[4, 5, 6], [0, 1], [19]])
  723. Permutation([1, 0, 2, 3, 5, 6, 4], size=20)
  724. All manipulation of permutations assumes that the smallest element
  725. is 0 (in keeping with 0-based indexing in Python) so if the 0 is
  726. missing when entering a permutation in array form, an error will be
  727. raised:
  728. >>> Permutation([2, 1])
  729. Traceback (most recent call last):
  730. ...
  731. ValueError: Integers 0 through 2 must be present.
  732. If a permutation is entered in cyclic form, it can be entered without
  733. singletons and the ``size`` specified so those values can be filled
  734. in, otherwise the array form will only extend to the maximum value
  735. in the cycles:
  736. >>> Permutation([[1, 4], [3, 5, 2]], size=10)
  737. Permutation([0, 4, 3, 5, 1, 2], size=10)
  738. >>> _.array_form
  739. [0, 4, 3, 5, 1, 2, 6, 7, 8, 9]
  740. """
  741. if size is not None:
  742. size = int(size)
  743. #a) ()
  744. #b) (1) = identity
  745. #c) (1, 2) = cycle
  746. #d) ([1, 2, 3]) = array form
  747. #e) ([[1, 2]]) = cyclic form
  748. #f) (Cycle) = conversion to permutation
  749. #g) (Permutation) = adjust size or return copy
  750. ok = True
  751. if not args: # a
  752. return cls._af_new(list(range(size or 0)))
  753. elif len(args) > 1: # c
  754. return cls._af_new(Cycle(*args).list(size))
  755. if len(args) == 1:
  756. a = args[0]
  757. if isinstance(a, cls): # g
  758. if size is None or size == a.size:
  759. return a
  760. return cls(a.array_form, size=size)
  761. if isinstance(a, Cycle): # f
  762. return cls._af_new(a.list(size))
  763. if not is_sequence(a): # b
  764. if size is not None and a + 1 > size:
  765. raise ValueError('size is too small when max is %s' % a)
  766. return cls._af_new(list(range(a + 1)))
  767. if has_variety(is_sequence(ai) for ai in a):
  768. ok = False
  769. else:
  770. ok = False
  771. if not ok:
  772. raise ValueError("Permutation argument must be a list of ints, "
  773. "a list of lists, Permutation or Cycle.")
  774. # safe to assume args are valid; this also makes a copy
  775. # of the args
  776. args = list(args[0])
  777. is_cycle = args and is_sequence(args[0])
  778. if is_cycle: # e
  779. args = [[int(i) for i in c] for c in args]
  780. else: # d
  781. args = [int(i) for i in args]
  782. # if there are n elements present, 0, 1, ..., n-1 should be present
  783. # unless a cycle notation has been provided. A 0 will be added
  784. # for convenience in case one wants to enter permutations where
  785. # counting starts from 1.
  786. temp = flatten(args)
  787. if has_dups(temp) and not is_cycle:
  788. raise ValueError('there were repeated elements.')
  789. temp = set(temp)
  790. if not is_cycle:
  791. if temp != set(range(len(temp))):
  792. raise ValueError('Integers 0 through %s must be present.' %
  793. max(temp))
  794. if size is not None and temp and max(temp) + 1 > size:
  795. raise ValueError('max element should not exceed %s' % (size - 1))
  796. if is_cycle:
  797. # it's not necessarily canonical so we won't store
  798. # it -- use the array form instead
  799. c = Cycle()
  800. for ci in args:
  801. c = c(*ci)
  802. aform = c.list()
  803. else:
  804. aform = list(args)
  805. if size and size > len(aform):
  806. # don't allow for truncation of permutation which
  807. # might split a cycle and lead to an invalid aform
  808. # but do allow the permutation size to be increased
  809. aform.extend(list(range(len(aform), size)))
  810. return cls._af_new(aform)
  811. @classmethod
  812. def _af_new(cls, perm):
  813. """A method to produce a Permutation object from a list;
  814. the list is bound to the _array_form attribute, so it must
  815. not be modified; this method is meant for internal use only;
  816. the list ``a`` is supposed to be generated as a temporary value
  817. in a method, so p = Perm._af_new(a) is the only object
  818. to hold a reference to ``a``::
  819. Examples
  820. ========
  821. >>> from sympy.combinatorics.permutations import Perm
  822. >>> from sympy import init_printing
  823. >>> init_printing(perm_cyclic=False, pretty_print=False)
  824. >>> a = [2, 1, 3, 0]
  825. >>> p = Perm._af_new(a)
  826. >>> p
  827. Permutation([2, 1, 3, 0])
  828. """
  829. p = super().__new__(cls)
  830. p._array_form = perm
  831. p._size = len(perm)
  832. return p
  833. def copy(self):
  834. return self.__class__(self.array_form)
  835. def __getnewargs__(self):
  836. return (self.array_form,)
  837. def _hashable_content(self):
  838. # the array_form (a list) is the Permutation arg, so we need to
  839. # return a tuple, instead
  840. return tuple(self.array_form)
  841. @property
  842. def array_form(self):
  843. """
  844. Return a copy of the attribute _array_form
  845. Examples
  846. ========
  847. >>> from sympy.combinatorics import Permutation
  848. >>> p = Permutation([[2, 0], [3, 1]])
  849. >>> p.array_form
  850. [2, 3, 0, 1]
  851. >>> Permutation([[2, 0, 3, 1]]).array_form
  852. [3, 2, 0, 1]
  853. >>> Permutation([2, 0, 3, 1]).array_form
  854. [2, 0, 3, 1]
  855. >>> Permutation([[1, 2], [4, 5]]).array_form
  856. [0, 2, 1, 3, 5, 4]
  857. """
  858. return self._array_form[:]
  859. def list(self, size=None):
  860. """Return the permutation as an explicit list, possibly
  861. trimming unmoved elements if size is less than the maximum
  862. element in the permutation; if this is desired, setting
  863. ``size=-1`` will guarantee such trimming.
  864. Examples
  865. ========
  866. >>> from sympy.combinatorics import Permutation
  867. >>> p = Permutation(2, 3)(4, 5)
  868. >>> p.list()
  869. [0, 1, 3, 2, 5, 4]
  870. >>> p.list(10)
  871. [0, 1, 3, 2, 5, 4, 6, 7, 8, 9]
  872. Passing a length too small will trim trailing, unchanged elements
  873. in the permutation:
  874. >>> Permutation(2, 4)(1, 2, 4).list(-1)
  875. [0, 2, 1]
  876. >>> Permutation(3).list(-1)
  877. []
  878. """
  879. if not self and size is None:
  880. raise ValueError('must give size for empty Cycle')
  881. rv = self.array_form
  882. if size is not None:
  883. if size > self.size:
  884. rv.extend(list(range(self.size, size)))
  885. else:
  886. # find first value from rhs where rv[i] != i
  887. i = self.size - 1
  888. while rv:
  889. if rv[-1] != i:
  890. break
  891. rv.pop()
  892. i -= 1
  893. return rv
  894. @property
  895. def cyclic_form(self):
  896. """
  897. This is used to convert to the cyclic notation
  898. from the canonical notation. Singletons are omitted.
  899. Examples
  900. ========
  901. >>> from sympy.combinatorics import Permutation
  902. >>> p = Permutation([0, 3, 1, 2])
  903. >>> p.cyclic_form
  904. [[1, 3, 2]]
  905. >>> Permutation([1, 0, 2, 4, 3, 5]).cyclic_form
  906. [[0, 1], [3, 4]]
  907. See Also
  908. ========
  909. array_form, full_cyclic_form
  910. """
  911. if self._cyclic_form is not None:
  912. return list(self._cyclic_form)
  913. array_form = self.array_form
  914. unchecked = [True] * len(array_form)
  915. cyclic_form = []
  916. for i in range(len(array_form)):
  917. if unchecked[i]:
  918. cycle = []
  919. cycle.append(i)
  920. unchecked[i] = False
  921. j = i
  922. while unchecked[array_form[j]]:
  923. j = array_form[j]
  924. cycle.append(j)
  925. unchecked[j] = False
  926. if len(cycle) > 1:
  927. cyclic_form.append(cycle)
  928. assert cycle == list(minlex(cycle))
  929. cyclic_form.sort()
  930. self._cyclic_form = cyclic_form.copy()
  931. return cyclic_form
  932. @property
  933. def full_cyclic_form(self):
  934. """Return permutation in cyclic form including singletons.
  935. Examples
  936. ========
  937. >>> from sympy.combinatorics import Permutation
  938. >>> Permutation([0, 2, 1]).full_cyclic_form
  939. [[0], [1, 2]]
  940. """
  941. need = set(range(self.size)) - set(flatten(self.cyclic_form))
  942. rv = self.cyclic_form + [[i] for i in need]
  943. rv.sort()
  944. return rv
  945. @property
  946. def size(self):
  947. """
  948. Returns the number of elements in the permutation.
  949. Examples
  950. ========
  951. >>> from sympy.combinatorics import Permutation
  952. >>> Permutation([[3, 2], [0, 1]]).size
  953. 4
  954. See Also
  955. ========
  956. cardinality, length, order, rank
  957. """
  958. return self._size
  959. def support(self):
  960. """Return the elements in permutation, P, for which P[i] != i.
  961. Examples
  962. ========
  963. >>> from sympy.combinatorics import Permutation
  964. >>> p = Permutation([[3, 2], [0, 1], [4]])
  965. >>> p.array_form
  966. [1, 0, 3, 2, 4]
  967. >>> p.support()
  968. [0, 1, 2, 3]
  969. """
  970. a = self.array_form
  971. return [i for i, e in enumerate(a) if e != i]
  972. def __add__(self, other):
  973. """Return permutation that is other higher in rank than self.
  974. The rank is the lexicographical rank, with the identity permutation
  975. having rank of 0.
  976. Examples
  977. ========
  978. >>> from sympy.combinatorics import Permutation
  979. >>> I = Permutation([0, 1, 2, 3])
  980. >>> a = Permutation([2, 1, 3, 0])
  981. >>> I + a.rank() == a
  982. True
  983. See Also
  984. ========
  985. __sub__, inversion_vector
  986. """
  987. rank = (self.rank() + other) % self.cardinality
  988. rv = self.unrank_lex(self.size, rank)
  989. rv._rank = rank
  990. return rv
  991. def __sub__(self, other):
  992. """Return the permutation that is other lower in rank than self.
  993. See Also
  994. ========
  995. __add__
  996. """
  997. return self.__add__(-other)
  998. @staticmethod
  999. def rmul(*args):
  1000. """
  1001. Return product of Permutations [a, b, c, ...] as the Permutation whose
  1002. ith value is a(b(c(i))).
  1003. a, b, c, ... can be Permutation objects or tuples.
  1004. Examples
  1005. ========
  1006. >>> from sympy.combinatorics import Permutation
  1007. >>> a, b = [1, 0, 2], [0, 2, 1]
  1008. >>> a = Permutation(a); b = Permutation(b)
  1009. >>> list(Permutation.rmul(a, b))
  1010. [1, 2, 0]
  1011. >>> [a(b(i)) for i in range(3)]
  1012. [1, 2, 0]
  1013. This handles the operands in reverse order compared to the ``*`` operator:
  1014. >>> a = Permutation(a); b = Permutation(b)
  1015. >>> list(a*b)
  1016. [2, 0, 1]
  1017. >>> [b(a(i)) for i in range(3)]
  1018. [2, 0, 1]
  1019. Notes
  1020. =====
  1021. All items in the sequence will be parsed by Permutation as
  1022. necessary as long as the first item is a Permutation:
  1023. >>> Permutation.rmul(a, [0, 2, 1]) == Permutation.rmul(a, b)
  1024. True
  1025. The reverse order of arguments will raise a TypeError.
  1026. """
  1027. rv = args[0]
  1028. for i in range(1, len(args)):
  1029. rv = args[i]*rv
  1030. return rv
  1031. @classmethod
  1032. def rmul_with_af(cls, *args):
  1033. """
  1034. same as rmul, but the elements of args are Permutation objects
  1035. which have _array_form
  1036. """
  1037. a = [x._array_form for x in args]
  1038. rv = cls._af_new(_af_rmuln(*a))
  1039. return rv
  1040. def mul_inv(self, other):
  1041. """
  1042. other*~self, self and other have _array_form
  1043. """
  1044. a = _af_invert(self._array_form)
  1045. b = other._array_form
  1046. return self._af_new(_af_rmul(a, b))
  1047. def __rmul__(self, other):
  1048. """This is needed to coerce other to Permutation in rmul."""
  1049. cls = type(self)
  1050. return cls(other)*self
  1051. def __mul__(self, other):
  1052. """
  1053. Return the product a*b as a Permutation; the ith value is b(a(i)).
  1054. Examples
  1055. ========
  1056. >>> from sympy.combinatorics.permutations import _af_rmul, Permutation
  1057. >>> a, b = [1, 0, 2], [0, 2, 1]
  1058. >>> a = Permutation(a); b = Permutation(b)
  1059. >>> list(a*b)
  1060. [2, 0, 1]
  1061. >>> [b(a(i)) for i in range(3)]
  1062. [2, 0, 1]
  1063. This handles operands in reverse order compared to _af_rmul and rmul:
  1064. >>> al = list(a); bl = list(b)
  1065. >>> _af_rmul(al, bl)
  1066. [1, 2, 0]
  1067. >>> [al[bl[i]] for i in range(3)]
  1068. [1, 2, 0]
  1069. It is acceptable for the arrays to have different lengths; the shorter
  1070. one will be padded to match the longer one:
  1071. >>> from sympy import init_printing
  1072. >>> init_printing(perm_cyclic=False, pretty_print=False)
  1073. >>> b*Permutation([1, 0])
  1074. Permutation([1, 2, 0])
  1075. >>> Permutation([1, 0])*b
  1076. Permutation([2, 0, 1])
  1077. It is also acceptable to allow coercion to handle conversion of a
  1078. single list to the left of a Permutation:
  1079. >>> [0, 1]*a # no change: 2-element identity
  1080. Permutation([1, 0, 2])
  1081. >>> [[0, 1]]*a # exchange first two elements
  1082. Permutation([0, 1, 2])
  1083. You cannot use more than 1 cycle notation in a product of cycles
  1084. since coercion can only handle one argument to the left. To handle
  1085. multiple cycles it is convenient to use Cycle instead of Permutation:
  1086. >>> [[1, 2]]*[[2, 3]]*Permutation([]) # doctest: +SKIP
  1087. >>> from sympy.combinatorics.permutations import Cycle
  1088. >>> Cycle(1, 2)(2, 3)
  1089. (1 3 2)
  1090. """
  1091. from sympy.combinatorics.perm_groups import PermutationGroup, Coset
  1092. if isinstance(other, PermutationGroup):
  1093. return Coset(self, other, dir='-')
  1094. a = self.array_form
  1095. # __rmul__ makes sure the other is a Permutation
  1096. b = other.array_form
  1097. if not b:
  1098. perm = a
  1099. else:
  1100. b.extend(list(range(len(b), len(a))))
  1101. perm = [b[i] for i in a] + b[len(a):]
  1102. return self._af_new(perm)
  1103. def commutes_with(self, other):
  1104. """
  1105. Checks if the elements are commuting.
  1106. Examples
  1107. ========
  1108. >>> from sympy.combinatorics import Permutation
  1109. >>> a = Permutation([1, 4, 3, 0, 2, 5])
  1110. >>> b = Permutation([0, 1, 2, 3, 4, 5])
  1111. >>> a.commutes_with(b)
  1112. True
  1113. >>> b = Permutation([2, 3, 5, 4, 1, 0])
  1114. >>> a.commutes_with(b)
  1115. False
  1116. """
  1117. a = self.array_form
  1118. b = other.array_form
  1119. return _af_commutes_with(a, b)
  1120. def __pow__(self, n):
  1121. """
  1122. Routine for finding powers of a permutation.
  1123. Examples
  1124. ========
  1125. >>> from sympy.combinatorics import Permutation
  1126. >>> from sympy import init_printing
  1127. >>> init_printing(perm_cyclic=False, pretty_print=False)
  1128. >>> p = Permutation([2, 0, 3, 1])
  1129. >>> p.order()
  1130. 4
  1131. >>> p**4
  1132. Permutation([0, 1, 2, 3])
  1133. """
  1134. if isinstance(n, Permutation):
  1135. raise NotImplementedError(
  1136. 'p**p is not defined; do you mean p^p (conjugate)?')
  1137. n = int(n)
  1138. return self._af_new(_af_pow(self.array_form, n))
  1139. def __rxor__(self, i):
  1140. """Return self(i) when ``i`` is an int.
  1141. Examples
  1142. ========
  1143. >>> from sympy.combinatorics import Permutation
  1144. >>> p = Permutation(1, 2, 9)
  1145. >>> 2^p == p(2) == 9
  1146. True
  1147. """
  1148. if int_valued(i):
  1149. return self(i)
  1150. else:
  1151. raise NotImplementedError(
  1152. "i^p = p(i) when i is an integer, not %s." % i)
  1153. def __xor__(self, h):
  1154. """Return the conjugate permutation ``~h*self*h` `.
  1155. Explanation
  1156. ===========
  1157. If ``a`` and ``b`` are conjugates, ``a = h*b*~h`` and
  1158. ``b = ~h*a*h`` and both have the same cycle structure.
  1159. Examples
  1160. ========
  1161. >>> from sympy.combinatorics import Permutation
  1162. >>> p = Permutation(1, 2, 9)
  1163. >>> q = Permutation(6, 9, 8)
  1164. >>> p*q != q*p
  1165. True
  1166. Calculate and check properties of the conjugate:
  1167. >>> c = p^q
  1168. >>> c == ~q*p*q and p == q*c*~q
  1169. True
  1170. The expression q^p^r is equivalent to q^(p*r):
  1171. >>> r = Permutation(9)(4, 6, 8)
  1172. >>> q^p^r == q^(p*r)
  1173. True
  1174. If the term to the left of the conjugate operator, i, is an integer
  1175. then this is interpreted as selecting the ith element from the
  1176. permutation to the right:
  1177. >>> all(i^p == p(i) for i in range(p.size))
  1178. True
  1179. Note that the * operator as higher precedence than the ^ operator:
  1180. >>> q^r*p^r == q^(r*p)^r == Permutation(9)(1, 6, 4)
  1181. True
  1182. Notes
  1183. =====
  1184. In Python the precedence rule is p^q^r = (p^q)^r which differs
  1185. in general from p^(q^r)
  1186. >>> q^p^r
  1187. (9)(1 4 8)
  1188. >>> q^(p^r)
  1189. (9)(1 8 6)
  1190. For a given r and p, both of the following are conjugates of p:
  1191. ~r*p*r and r*p*~r. But these are not necessarily the same:
  1192. >>> ~r*p*r == r*p*~r
  1193. True
  1194. >>> p = Permutation(1, 2, 9)(5, 6)
  1195. >>> ~r*p*r == r*p*~r
  1196. False
  1197. The conjugate ~r*p*r was chosen so that ``p^q^r`` would be equivalent
  1198. to ``p^(q*r)`` rather than ``p^(r*q)``. To obtain r*p*~r, pass ~r to
  1199. this method:
  1200. >>> p^~r == r*p*~r
  1201. True
  1202. """
  1203. if self.size != h.size:
  1204. raise ValueError("The permutations must be of equal size.")
  1205. a = [None]*self.size
  1206. h = h._array_form
  1207. p = self._array_form
  1208. for i in range(self.size):
  1209. a[h[i]] = h[p[i]]
  1210. return self._af_new(a)
  1211. def transpositions(self):
  1212. """
  1213. Return the permutation decomposed into a list of transpositions.
  1214. Explanation
  1215. ===========
  1216. It is always possible to express a permutation as the product of
  1217. transpositions, see [1]
  1218. Examples
  1219. ========
  1220. >>> from sympy.combinatorics import Permutation
  1221. >>> p = Permutation([[1, 2, 3], [0, 4, 5, 6, 7]])
  1222. >>> t = p.transpositions()
  1223. >>> t
  1224. [(0, 7), (0, 6), (0, 5), (0, 4), (1, 3), (1, 2)]
  1225. >>> print(''.join(str(c) for c in t))
  1226. (0, 7)(0, 6)(0, 5)(0, 4)(1, 3)(1, 2)
  1227. >>> Permutation.rmul(*[Permutation([ti], size=p.size) for ti in t]) == p
  1228. True
  1229. References
  1230. ==========
  1231. .. [1] https://en.wikipedia.org/wiki/Transposition_%28mathematics%29#Properties
  1232. """
  1233. a = self.cyclic_form
  1234. res = []
  1235. for x in a:
  1236. nx = len(x)
  1237. if nx == 2:
  1238. res.append(tuple(x))
  1239. elif nx > 2:
  1240. first = x[0]
  1241. res.extend((first, y) for y in x[nx - 1:0:-1])
  1242. return res
  1243. @classmethod
  1244. def from_sequence(self, i, key=None):
  1245. """Return the permutation needed to obtain ``i`` from the sorted
  1246. elements of ``i``. If custom sorting is desired, a key can be given.
  1247. Examples
  1248. ========
  1249. >>> from sympy.combinatorics import Permutation
  1250. >>> Permutation.from_sequence('SymPy')
  1251. (4)(0 1 3)
  1252. >>> _(sorted("SymPy"))
  1253. ['S', 'y', 'm', 'P', 'y']
  1254. >>> Permutation.from_sequence('SymPy', key=lambda x: x.lower())
  1255. (4)(0 2)(1 3)
  1256. """
  1257. ic = list(zip(i, list(range(len(i)))))
  1258. if key:
  1259. ic.sort(key=lambda x: key(x[0]))
  1260. else:
  1261. ic.sort()
  1262. return ~Permutation([i[1] for i in ic])
  1263. def __invert__(self):
  1264. """
  1265. Return the inverse of the permutation.
  1266. A permutation multiplied by its inverse is the identity permutation.
  1267. Examples
  1268. ========
  1269. >>> from sympy.combinatorics import Permutation
  1270. >>> from sympy import init_printing
  1271. >>> init_printing(perm_cyclic=False, pretty_print=False)
  1272. >>> p = Permutation([[2, 0], [3, 1]])
  1273. >>> ~p
  1274. Permutation([2, 3, 0, 1])
  1275. >>> _ == p**-1
  1276. True
  1277. >>> p*~p == ~p*p == Permutation([0, 1, 2, 3])
  1278. True
  1279. """
  1280. return self._af_new(_af_invert(self._array_form))
  1281. def __iter__(self):
  1282. """Yield elements from array form.
  1283. Examples
  1284. ========
  1285. >>> from sympy.combinatorics import Permutation
  1286. >>> list(Permutation(range(3)))
  1287. [0, 1, 2]
  1288. """
  1289. yield from self.array_form
  1290. def __repr__(self):
  1291. return srepr(self)
  1292. def __call__(self, *i):
  1293. """
  1294. Allows applying a permutation instance as a bijective function.
  1295. Examples
  1296. ========
  1297. >>> from sympy.combinatorics import Permutation
  1298. >>> p = Permutation([[2, 0], [3, 1]])
  1299. >>> p.array_form
  1300. [2, 3, 0, 1]
  1301. >>> [p(i) for i in range(4)]
  1302. [2, 3, 0, 1]
  1303. If an array is given then the permutation selects the items
  1304. from the array (i.e. the permutation is applied to the array):
  1305. >>> from sympy.abc import x
  1306. >>> p([x, 1, 0, x**2])
  1307. [0, x**2, x, 1]
  1308. """
  1309. # list indices can be Integer or int; leave this
  1310. # as it is (don't test or convert it) because this
  1311. # gets called a lot and should be fast
  1312. if len(i) == 1:
  1313. i = i[0]
  1314. if not isinstance(i, Iterable):
  1315. i = as_int(i)
  1316. if i < 0 or i > self.size:
  1317. raise TypeError(
  1318. "{} should be an integer between 0 and {}"
  1319. .format(i, self.size-1))
  1320. return self._array_form[i]
  1321. # P([a, b, c])
  1322. if len(i) != self.size:
  1323. raise TypeError(
  1324. "{} should have the length {}.".format(i, self.size))
  1325. return [i[j] for j in self._array_form]
  1326. # P(1, 2, 3)
  1327. return self*Permutation(Cycle(*i), size=self.size)
  1328. def atoms(self):
  1329. """
  1330. Returns all the elements of a permutation
  1331. Examples
  1332. ========
  1333. >>> from sympy.combinatorics import Permutation
  1334. >>> Permutation([0, 1, 2, 3, 4, 5]).atoms()
  1335. {0, 1, 2, 3, 4, 5}
  1336. >>> Permutation([[0, 1], [2, 3], [4, 5]]).atoms()
  1337. {0, 1, 2, 3, 4, 5}
  1338. """
  1339. return set(self.array_form)
  1340. def apply(self, i):
  1341. r"""Apply the permutation to an expression.
  1342. Parameters
  1343. ==========
  1344. i : Expr
  1345. It should be an integer between $0$ and $n-1$ where $n$
  1346. is the size of the permutation.
  1347. If it is a symbol or a symbolic expression that can
  1348. have integer values, an ``AppliedPermutation`` object
  1349. will be returned which can represent an unevaluated
  1350. function.
  1351. Notes
  1352. =====
  1353. Any permutation can be defined as a bijective function
  1354. $\sigma : \{ 0, 1, \dots, n-1 \} \rightarrow \{ 0, 1, \dots, n-1 \}$
  1355. where $n$ denotes the size of the permutation.
  1356. The definition may even be extended for any set with distinctive
  1357. elements, such that the permutation can even be applied for
  1358. real numbers or such, however, it is not implemented for now for
  1359. computational reasons and the integrity with the group theory
  1360. module.
  1361. This function is similar to the ``__call__`` magic, however,
  1362. ``__call__`` magic already has some other applications like
  1363. permuting an array or attaching new cycles, which would
  1364. not always be mathematically consistent.
  1365. This also guarantees that the return type is a SymPy integer,
  1366. which guarantees the safety to use assumptions.
  1367. """
  1368. i = _sympify(i)
  1369. if i.is_integer is False:
  1370. raise NotImplementedError("{} should be an integer.".format(i))
  1371. n = self.size
  1372. if (i < 0) == True or (i >= n) == True:
  1373. raise NotImplementedError(
  1374. "{} should be an integer between 0 and {}".format(i, n-1))
  1375. if i.is_Integer:
  1376. return Integer(self._array_form[i])
  1377. return AppliedPermutation(self, i)
  1378. def next_lex(self):
  1379. """
  1380. Returns the next permutation in lexicographical order.
  1381. If self is the last permutation in lexicographical order
  1382. it returns None.
  1383. See [4] section 2.4.
  1384. Examples
  1385. ========
  1386. >>> from sympy.combinatorics import Permutation
  1387. >>> p = Permutation([2, 3, 1, 0])
  1388. >>> p = Permutation([2, 3, 1, 0]); p.rank()
  1389. 17
  1390. >>> p = p.next_lex(); p.rank()
  1391. 18
  1392. See Also
  1393. ========
  1394. rank, unrank_lex
  1395. """
  1396. perm = self.array_form[:]
  1397. n = len(perm)
  1398. i = n - 2
  1399. while perm[i + 1] < perm[i]:
  1400. i -= 1
  1401. if i == -1:
  1402. return None
  1403. else:
  1404. j = n - 1
  1405. while perm[j] < perm[i]:
  1406. j -= 1
  1407. perm[j], perm[i] = perm[i], perm[j]
  1408. i += 1
  1409. j = n - 1
  1410. while i < j:
  1411. perm[j], perm[i] = perm[i], perm[j]
  1412. i += 1
  1413. j -= 1
  1414. return self._af_new(perm)
  1415. @classmethod
  1416. def unrank_nonlex(self, n, r):
  1417. """
  1418. This is a linear time unranking algorithm that does not
  1419. respect lexicographic order [3].
  1420. Examples
  1421. ========
  1422. >>> from sympy.combinatorics import Permutation
  1423. >>> from sympy import init_printing
  1424. >>> init_printing(perm_cyclic=False, pretty_print=False)
  1425. >>> Permutation.unrank_nonlex(4, 5)
  1426. Permutation([2, 0, 3, 1])
  1427. >>> Permutation.unrank_nonlex(4, -1)
  1428. Permutation([0, 1, 2, 3])
  1429. See Also
  1430. ========
  1431. next_nonlex, rank_nonlex
  1432. """
  1433. def _unrank1(n, r, a):
  1434. if n > 0:
  1435. a[n - 1], a[r % n] = a[r % n], a[n - 1]
  1436. _unrank1(n - 1, r//n, a)
  1437. id_perm = list(range(n))
  1438. n = int(n)
  1439. r = r % ifac(n)
  1440. _unrank1(n, r, id_perm)
  1441. return self._af_new(id_perm)
  1442. def rank_nonlex(self, inv_perm=None):
  1443. """
  1444. This is a linear time ranking algorithm that does not
  1445. enforce lexicographic order [3].
  1446. Examples
  1447. ========
  1448. >>> from sympy.combinatorics import Permutation
  1449. >>> p = Permutation([0, 1, 2, 3])
  1450. >>> p.rank_nonlex()
  1451. 23
  1452. See Also
  1453. ========
  1454. next_nonlex, unrank_nonlex
  1455. """
  1456. def _rank1(n, perm, inv_perm):
  1457. if n == 1:
  1458. return 0
  1459. s = perm[n - 1]
  1460. t = inv_perm[n - 1]
  1461. perm[n - 1], perm[t] = perm[t], s
  1462. inv_perm[n - 1], inv_perm[s] = inv_perm[s], t
  1463. return s + n*_rank1(n - 1, perm, inv_perm)
  1464. if inv_perm is None:
  1465. inv_perm = (~self).array_form
  1466. if not inv_perm:
  1467. return 0
  1468. perm = self.array_form[:]
  1469. r = _rank1(len(perm), perm, inv_perm)
  1470. return r
  1471. def next_nonlex(self):
  1472. """
  1473. Returns the next permutation in nonlex order [3].
  1474. If self is the last permutation in this order it returns None.
  1475. Examples
  1476. ========
  1477. >>> from sympy.combinatorics import Permutation
  1478. >>> from sympy import init_printing
  1479. >>> init_printing(perm_cyclic=False, pretty_print=False)
  1480. >>> p = Permutation([2, 0, 3, 1]); p.rank_nonlex()
  1481. 5
  1482. >>> p = p.next_nonlex(); p
  1483. Permutation([3, 0, 1, 2])
  1484. >>> p.rank_nonlex()
  1485. 6
  1486. See Also
  1487. ========
  1488. rank_nonlex, unrank_nonlex
  1489. """
  1490. r = self.rank_nonlex()
  1491. if r == ifac(self.size) - 1:
  1492. return None
  1493. return self.unrank_nonlex(self.size, r + 1)
  1494. def rank(self):
  1495. """
  1496. Returns the lexicographic rank of the permutation.
  1497. Examples
  1498. ========
  1499. >>> from sympy.combinatorics import Permutation
  1500. >>> p = Permutation([0, 1, 2, 3])
  1501. >>> p.rank()
  1502. 0
  1503. >>> p = Permutation([3, 2, 1, 0])
  1504. >>> p.rank()
  1505. 23
  1506. See Also
  1507. ========
  1508. next_lex, unrank_lex, cardinality, length, order, size
  1509. """
  1510. if self._rank is not None:
  1511. return self._rank
  1512. rank = 0
  1513. rho = self.array_form[:]
  1514. n = self.size - 1
  1515. size = n + 1
  1516. psize = int(ifac(n))
  1517. for j in range(size - 1):
  1518. rank += rho[j]*psize
  1519. for i in range(j + 1, size):
  1520. if rho[i] > rho[j]:
  1521. rho[i] -= 1
  1522. psize //= n
  1523. n -= 1
  1524. self._rank = rank
  1525. return rank
  1526. @property
  1527. def cardinality(self):
  1528. """
  1529. Returns the number of all possible permutations.
  1530. Examples
  1531. ========
  1532. >>> from sympy.combinatorics import Permutation
  1533. >>> p = Permutation([0, 1, 2, 3])
  1534. >>> p.cardinality
  1535. 24
  1536. See Also
  1537. ========
  1538. length, order, rank, size
  1539. """
  1540. return int(ifac(self.size))
  1541. def parity(self):
  1542. """
  1543. Computes the parity of a permutation.
  1544. Explanation
  1545. ===========
  1546. The parity of a permutation reflects the parity of the
  1547. number of inversions in the permutation, i.e., the
  1548. number of pairs of x and y such that ``x > y`` but ``p[x] < p[y]``.
  1549. Examples
  1550. ========
  1551. >>> from sympy.combinatorics import Permutation
  1552. >>> p = Permutation([0, 1, 2, 3])
  1553. >>> p.parity()
  1554. 0
  1555. >>> p = Permutation([3, 2, 0, 1])
  1556. >>> p.parity()
  1557. 1
  1558. See Also
  1559. ========
  1560. _af_parity
  1561. """
  1562. if self._cyclic_form is not None:
  1563. return (self.size - self.cycles) % 2
  1564. return _af_parity(self.array_form)
  1565. @property
  1566. def is_even(self):
  1567. """
  1568. Checks if a permutation is even.
  1569. Examples
  1570. ========
  1571. >>> from sympy.combinatorics import Permutation
  1572. >>> p = Permutation([0, 1, 2, 3])
  1573. >>> p.is_even
  1574. True
  1575. >>> p = Permutation([3, 2, 1, 0])
  1576. >>> p.is_even
  1577. True
  1578. See Also
  1579. ========
  1580. is_odd
  1581. """
  1582. return not self.is_odd
  1583. @property
  1584. def is_odd(self):
  1585. """
  1586. Checks if a permutation is odd.
  1587. Examples
  1588. ========
  1589. >>> from sympy.combinatorics import Permutation
  1590. >>> p = Permutation([0, 1, 2, 3])
  1591. >>> p.is_odd
  1592. False
  1593. >>> p = Permutation([3, 2, 0, 1])
  1594. >>> p.is_odd
  1595. True
  1596. See Also
  1597. ========
  1598. is_even
  1599. """
  1600. return bool(self.parity() % 2)
  1601. @property
  1602. def is_Singleton(self):
  1603. """
  1604. Checks to see if the permutation contains only one number and is
  1605. thus the only possible permutation of this set of numbers
  1606. Examples
  1607. ========
  1608. >>> from sympy.combinatorics import Permutation
  1609. >>> Permutation([0]).is_Singleton
  1610. True
  1611. >>> Permutation([0, 1]).is_Singleton
  1612. False
  1613. See Also
  1614. ========
  1615. is_Empty
  1616. """
  1617. return self.size == 1
  1618. @property
  1619. def is_Empty(self):
  1620. """
  1621. Checks to see if the permutation is a set with zero elements
  1622. Examples
  1623. ========
  1624. >>> from sympy.combinatorics import Permutation
  1625. >>> Permutation([]).is_Empty
  1626. True
  1627. >>> Permutation([0]).is_Empty
  1628. False
  1629. See Also
  1630. ========
  1631. is_Singleton
  1632. """
  1633. return self.size == 0
  1634. @property
  1635. def is_identity(self):
  1636. return self.is_Identity
  1637. @property
  1638. def is_Identity(self):
  1639. """
  1640. Returns True if the Permutation is an identity permutation.
  1641. Examples
  1642. ========
  1643. >>> from sympy.combinatorics import Permutation
  1644. >>> p = Permutation([])
  1645. >>> p.is_Identity
  1646. True
  1647. >>> p = Permutation([[0], [1], [2]])
  1648. >>> p.is_Identity
  1649. True
  1650. >>> p = Permutation([0, 1, 2])
  1651. >>> p.is_Identity
  1652. True
  1653. >>> p = Permutation([0, 2, 1])
  1654. >>> p.is_Identity
  1655. False
  1656. See Also
  1657. ========
  1658. order
  1659. """
  1660. af = self.array_form
  1661. return not af or all(i == af[i] for i in range(self.size))
  1662. def ascents(self):
  1663. """
  1664. Returns the positions of ascents in a permutation, ie, the location
  1665. where p[i] < p[i+1]
  1666. Examples
  1667. ========
  1668. >>> from sympy.combinatorics import Permutation
  1669. >>> p = Permutation([4, 0, 1, 3, 2])
  1670. >>> p.ascents()
  1671. [1, 2]
  1672. See Also
  1673. ========
  1674. descents, inversions, min, max
  1675. """
  1676. a = self.array_form
  1677. pos = [i for i in range(len(a) - 1) if a[i] < a[i + 1]]
  1678. return pos
  1679. def descents(self):
  1680. """
  1681. Returns the positions of descents in a permutation, ie, the location
  1682. where p[i] > p[i+1]
  1683. Examples
  1684. ========
  1685. >>> from sympy.combinatorics import Permutation
  1686. >>> p = Permutation([4, 0, 1, 3, 2])
  1687. >>> p.descents()
  1688. [0, 3]
  1689. See Also
  1690. ========
  1691. ascents, inversions, min, max
  1692. """
  1693. a = self.array_form
  1694. pos = [i for i in range(len(a) - 1) if a[i] > a[i + 1]]
  1695. return pos
  1696. def max(self) -> int:
  1697. """
  1698. The maximum element moved by the permutation.
  1699. Examples
  1700. ========
  1701. >>> from sympy.combinatorics import Permutation
  1702. >>> p = Permutation([1, 0, 2, 3, 4])
  1703. >>> p.max()
  1704. 1
  1705. See Also
  1706. ========
  1707. min, descents, ascents, inversions
  1708. """
  1709. a = self.array_form
  1710. if not a:
  1711. return 0
  1712. return max(_a for i, _a in enumerate(a) if _a != i)
  1713. def min(self) -> int:
  1714. """
  1715. The minimum element moved by the permutation.
  1716. Examples
  1717. ========
  1718. >>> from sympy.combinatorics import Permutation
  1719. >>> p = Permutation([0, 1, 4, 3, 2])
  1720. >>> p.min()
  1721. 2
  1722. See Also
  1723. ========
  1724. max, descents, ascents, inversions
  1725. """
  1726. a = self.array_form
  1727. if not a:
  1728. return 0
  1729. return min(_a for i, _a in enumerate(a) if _a != i)
  1730. def inversions(self):
  1731. """
  1732. Computes the number of inversions of a permutation.
  1733. Explanation
  1734. ===========
  1735. An inversion is where i > j but p[i] < p[j].
  1736. For small length of p, it iterates over all i and j
  1737. values and calculates the number of inversions.
  1738. For large length of p, it uses a variation of merge
  1739. sort to calculate the number of inversions.
  1740. Examples
  1741. ========
  1742. >>> from sympy.combinatorics import Permutation
  1743. >>> p = Permutation([0, 1, 2, 3, 4, 5])
  1744. >>> p.inversions()
  1745. 0
  1746. >>> Permutation([3, 2, 1, 0]).inversions()
  1747. 6
  1748. See Also
  1749. ========
  1750. descents, ascents, min, max
  1751. References
  1752. ==========
  1753. .. [1] https://www.cp.eng.chula.ac.th/~prabhas//teaching/algo/algo2008/count-inv.htm
  1754. """
  1755. inversions = 0
  1756. a = self.array_form
  1757. n = len(a)
  1758. if n < 130:
  1759. for i in range(n - 1):
  1760. b = a[i]
  1761. for c in a[i + 1:]:
  1762. if b > c:
  1763. inversions += 1
  1764. else:
  1765. k = 1
  1766. right = 0
  1767. arr = a[:]
  1768. temp = a[:]
  1769. while k < n:
  1770. i = 0
  1771. while i + k < n:
  1772. right = i + k * 2 - 1
  1773. if right >= n:
  1774. right = n - 1
  1775. inversions += _merge(arr, temp, i, i + k, right)
  1776. i = i + k * 2
  1777. k = k * 2
  1778. return inversions
  1779. def commutator(self, x):
  1780. """Return the commutator of ``self`` and ``x``: ``~x*~self*x*self``
  1781. If f and g are part of a group, G, then the commutator of f and g
  1782. is the group identity iff f and g commute, i.e. fg == gf.
  1783. Examples
  1784. ========
  1785. >>> from sympy.combinatorics import Permutation
  1786. >>> from sympy import init_printing
  1787. >>> init_printing(perm_cyclic=False, pretty_print=False)
  1788. >>> p = Permutation([0, 2, 3, 1])
  1789. >>> x = Permutation([2, 0, 3, 1])
  1790. >>> c = p.commutator(x); c
  1791. Permutation([2, 1, 3, 0])
  1792. >>> c == ~x*~p*x*p
  1793. True
  1794. >>> I = Permutation(3)
  1795. >>> p = [I + i for i in range(6)]
  1796. >>> for i in range(len(p)):
  1797. ... for j in range(len(p)):
  1798. ... c = p[i].commutator(p[j])
  1799. ... if p[i]*p[j] == p[j]*p[i]:
  1800. ... assert c == I
  1801. ... else:
  1802. ... assert c != I
  1803. ...
  1804. References
  1805. ==========
  1806. .. [1] https://en.wikipedia.org/wiki/Commutator
  1807. """
  1808. a = self.array_form
  1809. b = x.array_form
  1810. n = len(a)
  1811. if len(b) != n:
  1812. raise ValueError("The permutations must be of equal size.")
  1813. inva = [None]*n
  1814. for i in range(n):
  1815. inva[a[i]] = i
  1816. invb = [None]*n
  1817. for i in range(n):
  1818. invb[b[i]] = i
  1819. return self._af_new([a[b[inva[i]]] for i in invb])
  1820. def signature(self):
  1821. """
  1822. Gives the signature of the permutation needed to place the
  1823. elements of the permutation in canonical order.
  1824. The signature is calculated as (-1)^<number of inversions>
  1825. Examples
  1826. ========
  1827. >>> from sympy.combinatorics import Permutation
  1828. >>> p = Permutation([0, 1, 2])
  1829. >>> p.inversions()
  1830. 0
  1831. >>> p.signature()
  1832. 1
  1833. >>> q = Permutation([0,2,1])
  1834. >>> q.inversions()
  1835. 1
  1836. >>> q.signature()
  1837. -1
  1838. See Also
  1839. ========
  1840. inversions
  1841. """
  1842. if self.is_even:
  1843. return 1
  1844. return -1
  1845. def order(self):
  1846. """
  1847. Computes the order of a permutation.
  1848. When the permutation is raised to the power of its
  1849. order it equals the identity permutation.
  1850. Examples
  1851. ========
  1852. >>> from sympy.combinatorics import Permutation
  1853. >>> from sympy import init_printing
  1854. >>> init_printing(perm_cyclic=False, pretty_print=False)
  1855. >>> p = Permutation([3, 1, 5, 2, 4, 0])
  1856. >>> p.order()
  1857. 4
  1858. >>> (p**(p.order()))
  1859. Permutation([], size=6)
  1860. See Also
  1861. ========
  1862. identity, cardinality, length, rank, size
  1863. """
  1864. return reduce(lcm, [len(cycle) for cycle in self.cyclic_form], 1)
  1865. def length(self):
  1866. """
  1867. Returns the number of integers moved by a permutation.
  1868. Examples
  1869. ========
  1870. >>> from sympy.combinatorics import Permutation
  1871. >>> Permutation([0, 3, 2, 1]).length()
  1872. 2
  1873. >>> Permutation([[0, 1], [2, 3]]).length()
  1874. 4
  1875. See Also
  1876. ========
  1877. min, max, support, cardinality, order, rank, size
  1878. """
  1879. return len(self.support())
  1880. @property
  1881. def cycle_structure(self):
  1882. """Return the cycle structure of the permutation as a dictionary
  1883. indicating the multiplicity of each cycle length.
  1884. Examples
  1885. ========
  1886. >>> from sympy.combinatorics import Permutation
  1887. >>> Permutation(3).cycle_structure
  1888. {1: 4}
  1889. >>> Permutation(0, 4, 3)(1, 2)(5, 6).cycle_structure
  1890. {2: 2, 3: 1}
  1891. """
  1892. if self._cycle_structure:
  1893. rv = self._cycle_structure
  1894. else:
  1895. rv = defaultdict(int)
  1896. singletons = self.size
  1897. for c in self.cyclic_form:
  1898. rv[len(c)] += 1
  1899. singletons -= len(c)
  1900. if singletons:
  1901. rv[1] = singletons
  1902. self._cycle_structure = rv
  1903. return dict(rv) # make a copy
  1904. @property
  1905. def cycles(self):
  1906. """
  1907. Returns the number of cycles contained in the permutation
  1908. (including singletons).
  1909. Examples
  1910. ========
  1911. >>> from sympy.combinatorics import Permutation
  1912. >>> Permutation([0, 1, 2]).cycles
  1913. 3
  1914. >>> Permutation([0, 1, 2]).full_cyclic_form
  1915. [[0], [1], [2]]
  1916. >>> Permutation(0, 1)(2, 3).cycles
  1917. 2
  1918. See Also
  1919. ========
  1920. sympy.functions.combinatorial.numbers.stirling
  1921. """
  1922. return len(self.full_cyclic_form)
  1923. def index(self):
  1924. """
  1925. Returns the index of a permutation.
  1926. The index of a permutation is the sum of all subscripts j such
  1927. that p[j] is greater than p[j+1].
  1928. Examples
  1929. ========
  1930. >>> from sympy.combinatorics import Permutation
  1931. >>> p = Permutation([3, 0, 2, 1, 4])
  1932. >>> p.index()
  1933. 2
  1934. """
  1935. a = self.array_form
  1936. return sum(j for j in range(len(a) - 1) if a[j] > a[j + 1])
  1937. def runs(self):
  1938. """
  1939. Returns the runs of a permutation.
  1940. An ascending sequence in a permutation is called a run [5].
  1941. Examples
  1942. ========
  1943. >>> from sympy.combinatorics import Permutation
  1944. >>> p = Permutation([2, 5, 7, 3, 6, 0, 1, 4, 8])
  1945. >>> p.runs()
  1946. [[2, 5, 7], [3, 6], [0, 1, 4, 8]]
  1947. >>> q = Permutation([1,3,2,0])
  1948. >>> q.runs()
  1949. [[1, 3], [2], [0]]
  1950. """
  1951. return runs(self.array_form)
  1952. def inversion_vector(self):
  1953. """Return the inversion vector of the permutation.
  1954. The inversion vector consists of elements whose value
  1955. indicates the number of elements in the permutation
  1956. that are lesser than it and lie on its right hand side.
  1957. The inversion vector is the same as the Lehmer encoding of a
  1958. permutation.
  1959. Examples
  1960. ========
  1961. >>> from sympy.combinatorics import Permutation
  1962. >>> p = Permutation([4, 8, 0, 7, 1, 5, 3, 6, 2])
  1963. >>> p.inversion_vector()
  1964. [4, 7, 0, 5, 0, 2, 1, 1]
  1965. >>> p = Permutation([3, 2, 1, 0])
  1966. >>> p.inversion_vector()
  1967. [3, 2, 1]
  1968. The inversion vector increases lexicographically with the rank
  1969. of the permutation, the -ith element cycling through 0..i.
  1970. >>> p = Permutation(2)
  1971. >>> while p:
  1972. ... print('%s %s %s' % (p, p.inversion_vector(), p.rank()))
  1973. ... p = p.next_lex()
  1974. (2) [0, 0] 0
  1975. (1 2) [0, 1] 1
  1976. (2)(0 1) [1, 0] 2
  1977. (0 1 2) [1, 1] 3
  1978. (0 2 1) [2, 0] 4
  1979. (0 2) [2, 1] 5
  1980. See Also
  1981. ========
  1982. from_inversion_vector
  1983. """
  1984. self_array_form = self.array_form
  1985. n = len(self_array_form)
  1986. inversion_vector = [0] * (n - 1)
  1987. for i in range(n - 1):
  1988. val = 0
  1989. for j in range(i + 1, n):
  1990. if self_array_form[j] < self_array_form[i]:
  1991. val += 1
  1992. inversion_vector[i] = val
  1993. return inversion_vector
  1994. def rank_trotterjohnson(self):
  1995. """
  1996. Returns the Trotter Johnson rank, which we get from the minimal
  1997. change algorithm. See [4] section 2.4.
  1998. Examples
  1999. ========
  2000. >>> from sympy.combinatorics import Permutation
  2001. >>> p = Permutation([0, 1, 2, 3])
  2002. >>> p.rank_trotterjohnson()
  2003. 0
  2004. >>> p = Permutation([0, 2, 1, 3])
  2005. >>> p.rank_trotterjohnson()
  2006. 7
  2007. See Also
  2008. ========
  2009. unrank_trotterjohnson, next_trotterjohnson
  2010. """
  2011. if self.array_form == [] or self.is_Identity:
  2012. return 0
  2013. if self.array_form == [1, 0]:
  2014. return 1
  2015. perm = self.array_form
  2016. n = self.size
  2017. rank = 0
  2018. for j in range(1, n):
  2019. k = 1
  2020. i = 0
  2021. while perm[i] != j:
  2022. if perm[i] < j:
  2023. k += 1
  2024. i += 1
  2025. j1 = j + 1
  2026. if rank % 2 == 0:
  2027. rank = j1*rank + j1 - k
  2028. else:
  2029. rank = j1*rank + k - 1
  2030. return rank
  2031. @classmethod
  2032. def unrank_trotterjohnson(cls, size, rank):
  2033. """
  2034. Trotter Johnson permutation unranking. See [4] section 2.4.
  2035. Examples
  2036. ========
  2037. >>> from sympy.combinatorics import Permutation
  2038. >>> from sympy import init_printing
  2039. >>> init_printing(perm_cyclic=False, pretty_print=False)
  2040. >>> Permutation.unrank_trotterjohnson(5, 10)
  2041. Permutation([0, 3, 1, 2, 4])
  2042. See Also
  2043. ========
  2044. rank_trotterjohnson, next_trotterjohnson
  2045. """
  2046. perm = [0]*size
  2047. r2 = 0
  2048. n = ifac(size)
  2049. pj = 1
  2050. for j in range(2, size + 1):
  2051. pj *= j
  2052. r1 = (rank * pj) // n
  2053. k = r1 - j*r2
  2054. if r2 % 2 == 0:
  2055. for i in range(j - 1, j - k - 1, -1):
  2056. perm[i] = perm[i - 1]
  2057. perm[j - k - 1] = j - 1
  2058. else:
  2059. for i in range(j - 1, k, -1):
  2060. perm[i] = perm[i - 1]
  2061. perm[k] = j - 1
  2062. r2 = r1
  2063. return cls._af_new(perm)
  2064. def next_trotterjohnson(self):
  2065. """
  2066. Returns the next permutation in Trotter-Johnson order.
  2067. If self is the last permutation it returns None.
  2068. See [4] section 2.4. If it is desired to generate all such
  2069. permutations, they can be generated in order more quickly
  2070. with the ``generate_bell`` function.
  2071. Examples
  2072. ========
  2073. >>> from sympy.combinatorics import Permutation
  2074. >>> from sympy import init_printing
  2075. >>> init_printing(perm_cyclic=False, pretty_print=False)
  2076. >>> p = Permutation([3, 0, 2, 1])
  2077. >>> p.rank_trotterjohnson()
  2078. 4
  2079. >>> p = p.next_trotterjohnson(); p
  2080. Permutation([0, 3, 2, 1])
  2081. >>> p.rank_trotterjohnson()
  2082. 5
  2083. See Also
  2084. ========
  2085. rank_trotterjohnson, unrank_trotterjohnson, sympy.utilities.iterables.generate_bell
  2086. """
  2087. pi = self.array_form[:]
  2088. n = len(pi)
  2089. st = 0
  2090. rho = pi[:]
  2091. done = False
  2092. m = n-1
  2093. while m > 0 and not done:
  2094. d = rho.index(m)
  2095. for i in range(d, m):
  2096. rho[i] = rho[i + 1]
  2097. par = _af_parity(rho[:m])
  2098. if par == 1:
  2099. if d == m:
  2100. m -= 1
  2101. else:
  2102. pi[st + d], pi[st + d + 1] = pi[st + d + 1], pi[st + d]
  2103. done = True
  2104. else:
  2105. if d == 0:
  2106. m -= 1
  2107. st += 1
  2108. else:
  2109. pi[st + d], pi[st + d - 1] = pi[st + d - 1], pi[st + d]
  2110. done = True
  2111. if m == 0:
  2112. return None
  2113. return self._af_new(pi)
  2114. def get_precedence_matrix(self):
  2115. """
  2116. Gets the precedence matrix. This is used for computing the
  2117. distance between two permutations.
  2118. Examples
  2119. ========
  2120. >>> from sympy.combinatorics import Permutation
  2121. >>> from sympy import init_printing
  2122. >>> init_printing(perm_cyclic=False, pretty_print=False)
  2123. >>> p = Permutation.josephus(3, 6, 1)
  2124. >>> p
  2125. Permutation([2, 5, 3, 1, 4, 0])
  2126. >>> p.get_precedence_matrix()
  2127. Matrix([
  2128. [0, 0, 0, 0, 0, 0],
  2129. [1, 0, 0, 0, 1, 0],
  2130. [1, 1, 0, 1, 1, 1],
  2131. [1, 1, 0, 0, 1, 0],
  2132. [1, 0, 0, 0, 0, 0],
  2133. [1, 1, 0, 1, 1, 0]])
  2134. See Also
  2135. ========
  2136. get_precedence_distance, get_adjacency_matrix, get_adjacency_distance
  2137. """
  2138. m = zeros(self.size)
  2139. perm = self.array_form
  2140. for i in range(m.rows):
  2141. for j in range(i + 1, m.cols):
  2142. m[perm[i], perm[j]] = 1
  2143. return m
  2144. def get_precedence_distance(self, other):
  2145. """
  2146. Computes the precedence distance between two permutations.
  2147. Explanation
  2148. ===========
  2149. Suppose p and p' represent n jobs. The precedence metric
  2150. counts the number of times a job j is preceded by job i
  2151. in both p and p'. This metric is commutative.
  2152. Examples
  2153. ========
  2154. >>> from sympy.combinatorics import Permutation
  2155. >>> p = Permutation([2, 0, 4, 3, 1])
  2156. >>> q = Permutation([3, 1, 2, 4, 0])
  2157. >>> p.get_precedence_distance(q)
  2158. 7
  2159. >>> q.get_precedence_distance(p)
  2160. 7
  2161. See Also
  2162. ========
  2163. get_precedence_matrix, get_adjacency_matrix, get_adjacency_distance
  2164. """
  2165. if self.size != other.size:
  2166. raise ValueError("The permutations must be of equal size.")
  2167. self_prec_mat = self.get_precedence_matrix()
  2168. other_prec_mat = other.get_precedence_matrix()
  2169. n_prec = 0
  2170. for i in range(self.size):
  2171. for j in range(self.size):
  2172. if i == j:
  2173. continue
  2174. if self_prec_mat[i, j] * other_prec_mat[i, j] == 1:
  2175. n_prec += 1
  2176. d = self.size * (self.size - 1)//2 - n_prec
  2177. return d
  2178. def get_adjacency_matrix(self):
  2179. """
  2180. Computes the adjacency matrix of a permutation.
  2181. Explanation
  2182. ===========
  2183. If job i is adjacent to job j in a permutation p
  2184. then we set m[i, j] = 1 where m is the adjacency
  2185. matrix of p.
  2186. Examples
  2187. ========
  2188. >>> from sympy.combinatorics import Permutation
  2189. >>> p = Permutation.josephus(3, 6, 1)
  2190. >>> p.get_adjacency_matrix()
  2191. Matrix([
  2192. [0, 0, 0, 0, 0, 0],
  2193. [0, 0, 0, 0, 1, 0],
  2194. [0, 0, 0, 0, 0, 1],
  2195. [0, 1, 0, 0, 0, 0],
  2196. [1, 0, 0, 0, 0, 0],
  2197. [0, 0, 0, 1, 0, 0]])
  2198. >>> q = Permutation([0, 1, 2, 3])
  2199. >>> q.get_adjacency_matrix()
  2200. Matrix([
  2201. [0, 1, 0, 0],
  2202. [0, 0, 1, 0],
  2203. [0, 0, 0, 1],
  2204. [0, 0, 0, 0]])
  2205. See Also
  2206. ========
  2207. get_precedence_matrix, get_precedence_distance, get_adjacency_distance
  2208. """
  2209. m = zeros(self.size)
  2210. perm = self.array_form
  2211. for i in range(self.size - 1):
  2212. m[perm[i], perm[i + 1]] = 1
  2213. return m
  2214. def get_adjacency_distance(self, other):
  2215. """
  2216. Computes the adjacency distance between two permutations.
  2217. Explanation
  2218. ===========
  2219. This metric counts the number of times a pair i,j of jobs is
  2220. adjacent in both p and p'. If n_adj is this quantity then
  2221. the adjacency distance is n - n_adj - 1 [1]
  2222. [1] Reeves, Colin R. Landscapes, Operators and Heuristic search, Annals
  2223. of Operational Research, 86, pp 473-490. (1999)
  2224. Examples
  2225. ========
  2226. >>> from sympy.combinatorics import Permutation
  2227. >>> p = Permutation([0, 3, 1, 2, 4])
  2228. >>> q = Permutation.josephus(4, 5, 2)
  2229. >>> p.get_adjacency_distance(q)
  2230. 3
  2231. >>> r = Permutation([0, 2, 1, 4, 3])
  2232. >>> p.get_adjacency_distance(r)
  2233. 4
  2234. See Also
  2235. ========
  2236. get_precedence_matrix, get_precedence_distance, get_adjacency_matrix
  2237. """
  2238. if self.size != other.size:
  2239. raise ValueError("The permutations must be of the same size.")
  2240. self_adj_mat = self.get_adjacency_matrix()
  2241. other_adj_mat = other.get_adjacency_matrix()
  2242. n_adj = 0
  2243. for i in range(self.size):
  2244. for j in range(self.size):
  2245. if i == j:
  2246. continue
  2247. if self_adj_mat[i, j] * other_adj_mat[i, j] == 1:
  2248. n_adj += 1
  2249. d = self.size - n_adj - 1
  2250. return d
  2251. def get_positional_distance(self, other):
  2252. """
  2253. Computes the positional distance between two permutations.
  2254. Examples
  2255. ========
  2256. >>> from sympy.combinatorics import Permutation
  2257. >>> p = Permutation([0, 3, 1, 2, 4])
  2258. >>> q = Permutation.josephus(4, 5, 2)
  2259. >>> r = Permutation([3, 1, 4, 0, 2])
  2260. >>> p.get_positional_distance(q)
  2261. 12
  2262. >>> p.get_positional_distance(r)
  2263. 12
  2264. See Also
  2265. ========
  2266. get_precedence_distance, get_adjacency_distance
  2267. """
  2268. a = self.array_form
  2269. b = other.array_form
  2270. if len(a) != len(b):
  2271. raise ValueError("The permutations must be of the same size.")
  2272. return sum(abs(a[i] - b[i]) for i in range(len(a)))
  2273. @classmethod
  2274. def josephus(cls, m, n, s=1):
  2275. """Return as a permutation the shuffling of range(n) using the Josephus
  2276. scheme in which every m-th item is selected until all have been chosen.
  2277. The returned permutation has elements listed by the order in which they
  2278. were selected.
  2279. The parameter ``s`` stops the selection process when there are ``s``
  2280. items remaining and these are selected by continuing the selection,
  2281. counting by 1 rather than by ``m``.
  2282. Consider selecting every 3rd item from 6 until only 2 remain::
  2283. choices chosen
  2284. ======== ======
  2285. 012345
  2286. 01 345 2
  2287. 01 34 25
  2288. 01 4 253
  2289. 0 4 2531
  2290. 0 25314
  2291. 253140
  2292. Examples
  2293. ========
  2294. >>> from sympy.combinatorics import Permutation
  2295. >>> Permutation.josephus(3, 6, 2).array_form
  2296. [2, 5, 3, 1, 4, 0]
  2297. References
  2298. ==========
  2299. .. [1] https://en.wikipedia.org/wiki/Flavius_Josephus
  2300. .. [2] https://en.wikipedia.org/wiki/Josephus_problem
  2301. .. [3] https://web.archive.org/web/20171008094331/http://www.wou.edu/~burtonl/josephus.html
  2302. """
  2303. from collections import deque
  2304. m -= 1
  2305. Q = deque(list(range(n)))
  2306. perm = []
  2307. while len(Q) > max(s, 1):
  2308. for dp in range(m):
  2309. Q.append(Q.popleft())
  2310. perm.append(Q.popleft())
  2311. perm.extend(list(Q))
  2312. return cls(perm)
  2313. @classmethod
  2314. def from_inversion_vector(cls, inversion):
  2315. """
  2316. Calculates the permutation from the inversion vector.
  2317. Examples
  2318. ========
  2319. >>> from sympy.combinatorics import Permutation
  2320. >>> from sympy import init_printing
  2321. >>> init_printing(perm_cyclic=False, pretty_print=False)
  2322. >>> Permutation.from_inversion_vector([3, 2, 1, 0, 0])
  2323. Permutation([3, 2, 1, 0, 4, 5])
  2324. """
  2325. size = len(inversion)
  2326. N = list(range(size + 1))
  2327. perm = []
  2328. try:
  2329. for k in range(size):
  2330. val = N[inversion[k]]
  2331. perm.append(val)
  2332. N.remove(val)
  2333. except IndexError:
  2334. raise ValueError("The inversion vector is not valid.")
  2335. perm.extend(N)
  2336. return cls._af_new(perm)
  2337. @classmethod
  2338. def random(cls, n):
  2339. """
  2340. Generates a random permutation of length ``n``.
  2341. Uses the underlying Python pseudo-random number generator.
  2342. Examples
  2343. ========
  2344. >>> from sympy.combinatorics import Permutation
  2345. >>> Permutation.random(2) in (Permutation([1, 0]), Permutation([0, 1]))
  2346. True
  2347. """
  2348. perm_array = list(range(n))
  2349. random.shuffle(perm_array)
  2350. return cls._af_new(perm_array)
  2351. @classmethod
  2352. def unrank_lex(cls, size, rank):
  2353. """
  2354. Lexicographic permutation unranking.
  2355. Examples
  2356. ========
  2357. >>> from sympy.combinatorics import Permutation
  2358. >>> from sympy import init_printing
  2359. >>> init_printing(perm_cyclic=False, pretty_print=False)
  2360. >>> a = Permutation.unrank_lex(5, 10)
  2361. >>> a.rank()
  2362. 10
  2363. >>> a
  2364. Permutation([0, 2, 4, 1, 3])
  2365. See Also
  2366. ========
  2367. rank, next_lex
  2368. """
  2369. perm_array = [0] * size
  2370. psize = 1
  2371. for i in range(size):
  2372. new_psize = psize*(i + 1)
  2373. d = (rank % new_psize) // psize
  2374. rank -= d*psize
  2375. perm_array[size - i - 1] = d
  2376. for j in range(size - i, size):
  2377. if perm_array[j] > d - 1:
  2378. perm_array[j] += 1
  2379. psize = new_psize
  2380. return cls._af_new(perm_array)
  2381. def resize(self, n):
  2382. """Resize the permutation to the new size ``n``.
  2383. Parameters
  2384. ==========
  2385. n : int
  2386. The new size of the permutation.
  2387. Raises
  2388. ======
  2389. ValueError
  2390. If the permutation cannot be resized to the given size.
  2391. This may only happen when resized to a smaller size than
  2392. the original.
  2393. Examples
  2394. ========
  2395. >>> from sympy.combinatorics import Permutation
  2396. Increasing the size of a permutation:
  2397. >>> p = Permutation(0, 1, 2)
  2398. >>> p = p.resize(5)
  2399. >>> p
  2400. (4)(0 1 2)
  2401. Decreasing the size of the permutation:
  2402. >>> p = p.resize(4)
  2403. >>> p
  2404. (3)(0 1 2)
  2405. If resizing to the specific size breaks the cycles:
  2406. >>> p.resize(2)
  2407. Traceback (most recent call last):
  2408. ...
  2409. ValueError: The permutation cannot be resized to 2 because the
  2410. cycle (0, 1, 2) may break.
  2411. """
  2412. aform = self.array_form
  2413. l = len(aform)
  2414. if n > l:
  2415. aform += list(range(l, n))
  2416. return Permutation._af_new(aform)
  2417. elif n < l:
  2418. cyclic_form = self.full_cyclic_form
  2419. new_cyclic_form = []
  2420. for cycle in cyclic_form:
  2421. cycle_min = min(cycle)
  2422. cycle_max = max(cycle)
  2423. if cycle_min <= n-1:
  2424. if cycle_max > n-1:
  2425. raise ValueError(
  2426. "The permutation cannot be resized to {} "
  2427. "because the cycle {} may break."
  2428. .format(n, tuple(cycle)))
  2429. new_cyclic_form.append(cycle)
  2430. return Permutation(new_cyclic_form)
  2431. return self
  2432. # XXX Deprecated flag
  2433. print_cyclic = None
  2434. def _merge(arr, temp, left, mid, right):
  2435. """
  2436. Merges two sorted arrays and calculates the inversion count.
  2437. Helper function for calculating inversions. This method is
  2438. for internal use only.
  2439. """
  2440. i = k = left
  2441. j = mid
  2442. inv_count = 0
  2443. while i < mid and j <= right:
  2444. if arr[i] < arr[j]:
  2445. temp[k] = arr[i]
  2446. k += 1
  2447. i += 1
  2448. else:
  2449. temp[k] = arr[j]
  2450. k += 1
  2451. j += 1
  2452. inv_count += (mid -i)
  2453. while i < mid:
  2454. temp[k] = arr[i]
  2455. k += 1
  2456. i += 1
  2457. if j <= right:
  2458. k += right - j + 1
  2459. j += right - j + 1
  2460. arr[left:k + 1] = temp[left:k + 1]
  2461. else:
  2462. arr[left:right + 1] = temp[left:right + 1]
  2463. return inv_count
  2464. Perm = Permutation
  2465. _af_new = Perm._af_new
  2466. class AppliedPermutation(Expr):
  2467. """A permutation applied to a symbolic variable.
  2468. Parameters
  2469. ==========
  2470. perm : Permutation
  2471. x : Expr
  2472. Examples
  2473. ========
  2474. >>> from sympy import Symbol
  2475. >>> from sympy.combinatorics import Permutation
  2476. Creating a symbolic permutation function application:
  2477. >>> x = Symbol('x')
  2478. >>> p = Permutation(0, 1, 2)
  2479. >>> p.apply(x)
  2480. AppliedPermutation((0 1 2), x)
  2481. >>> _.subs(x, 1)
  2482. 2
  2483. """
  2484. def __new__(cls, perm, x, evaluate=None):
  2485. if evaluate is None:
  2486. evaluate = global_parameters.evaluate
  2487. perm = _sympify(perm)
  2488. x = _sympify(x)
  2489. if not isinstance(perm, Permutation):
  2490. raise ValueError("{} must be a Permutation instance."
  2491. .format(perm))
  2492. if evaluate:
  2493. if x.is_Integer:
  2494. return perm.apply(x)
  2495. obj = super().__new__(cls, perm, x)
  2496. return obj
  2497. @dispatch(Permutation, Permutation)
  2498. def _eval_is_eq(lhs, rhs):
  2499. if lhs._size != rhs._size:
  2500. return None
  2501. return lhs._array_form == rhs._array_form