| 857 | 857 | #g) (Permutation) = adjust size or return copy |
| 858 | 858 | ok = True |
| 859 | 859 | if not args: # a |
| 860 | return _af_new(list(range(size or 0))) | |
| 860 | return cls._af_new(list(range(size or 0))) | |
| 861 | 861 | elif len(args) > 1: # c |
| 862 | return _af_new(Cycle(*args).list(size)) | |
| 862 | return cls._af_new(Cycle(*args).list(size)) | |
| 863 | 863 | if len(args) == 1: |
| 864 | 864 | a = args[0] |
| 865 | 865 | if isinstance(a, Perm): # g |
| 867 | 867 | return a |
| 868 | 868 | return Perm(a.array_form, size=size) |
| 869 | 869 | if isinstance(a, Cycle): # f |
| 870 | return _af_new(a.list(size)) | |
| 870 | return cls._af_new(a.list(size)) | |
| 871 | 871 | if not is_sequence(a): # b |
| 872 | return _af_new(list(range(a + 1))) | |
| 872 | return cls._af_new(list(range(a + 1))) | |
| 873 | 873 | if has_variety(is_sequence(ai) for ai in a): |
| 874 | 874 | ok = False |
| 875 | 875 | else: |
| 924 | 924 | obj._size = size |
| 925 | 925 | return obj |
| 926 | 926 | |
| 927 | @staticmethod | |
| 928 | def _af_new(perm): | |
| 927 | @classmethod | |
| 928 | def _af_new(cls, perm): | |
| 929 | 929 | """A method to produce a Permutation object from a list; |
| 930 | 930 | the list is bound to the _array_form attribute, so it must |
| 931 | 931 | not be modified; this method is meant for internal use only; |
| 944 | 944 | Permutation([2, 1, 3, 0]) |
| 945 | 945 | |
| 946 | 946 | """ |
| 947 | p = Basic.__new__(Perm, perm) | |
| 947 | p = Basic.__new__(cls, perm) | |
| 948 | 948 | p._array_form = perm |
| 949 | 949 | p._size = len(perm) |
| 950 | 950 | return p |
| 1235 | 1235 | """ |
| 1236 | 1236 | a = _af_invert(self._array_form) |
| 1237 | 1237 | b = other._array_form |
| 1238 | return _af_new(_af_rmul(a, b)) | |
| 1238 | return self._af_new(_af_rmul(a, b)) | |
| 1239 | 1239 | |
| 1240 | 1240 | def __rmul__(self, other): |
| 1241 | 1241 | """This is needed to coerse other to Permutation in rmul.""" |
| 1300 | 1300 | else: |
| 1301 | 1301 | b.extend(list(range(len(b), len(a)))) |
| 1302 | 1302 | perm = [b[i] for i in a] + b[len(a):] |
| 1303 | return _af_new(perm) | |
| 1303 | return self._af_new(perm) | |
| 1304 | 1304 | |
| 1305 | 1305 | def commutes_with(self, other): |
| 1306 | 1306 | """ |
| 1341 | 1341 | raise NotImplementedError( |
| 1342 | 1342 | 'p**p is not defined; do you mean p^p (conjugate)?') |
| 1343 | 1343 | n = int(n) |
| 1344 | return _af_new(_af_pow(self.array_form, n)) | |
| 1344 | return self._af_new(_af_pow(self.array_form, n)) | |
| 1345 | 1345 | |
| 1346 | 1346 | def __rxor__(self, i): |
| 1347 | 1347 | """Return self(i) when ``i`` is an int. |
| 1436 | 1436 | p = self._array_form |
| 1437 | 1437 | for i in range(self.size): |
| 1438 | 1438 | a[h[i]] = h[p[i]] |
| 1439 | return _af_new(a) | |
| 1439 | return self._af_new(a) | |
| 1440 | 1440 | |
| 1441 | 1441 | def transpositions(self): |
| 1442 | 1442 | """ |
| 1519 | 1519 | >>> p*~p == ~p*p == Permutation([0, 1, 2, 3]) |
| 1520 | 1520 | True |
| 1521 | 1521 | """ |
| 1522 | return _af_new(_af_invert(self._array_form)) | |
| 1522 | return self._af_new(_af_invert(self._array_form)) | |
| 1523 | 1523 | |
| 1524 | 1524 | def __iter__(self): |
| 1525 | 1525 | """Yield elements from array form. |
| 1629 | 1629 | perm[j], perm[i] = perm[i], perm[j] |
| 1630 | 1630 | i += 1 |
| 1631 | 1631 | j -= 1 |
| 1632 | return _af_new(perm) | |
| 1632 | return self._af_new(perm) | |
| 1633 | 1633 | |
| 1634 | 1634 | @classmethod |
| 1635 | def unrank_nonlex(self, n, r): | |
| 1635 | def unrank_nonlex(cls, n, r): | |
| 1636 | 1636 | """ |
| 1637 | 1637 | This is a linear time unranking algorithm that does not |
| 1638 | 1638 | respect lexicographic order [3]. |
| 1661 | 1661 | n = int(n) |
| 1662 | 1662 | r = r % ifac(n) |
| 1663 | 1663 | _unrank1(n, r, id_perm) |
| 1664 | return _af_new(id_perm) | |
| 1664 | return cls._af_new(id_perm) | |
| 1665 | 1665 | |
| 1666 | 1666 | def rank_nonlex(self, inv_perm=None): |
| 1667 | 1667 | """ |
| 2125 | 2125 | invb = [None]*n |
| 2126 | 2126 | for i in range(n): |
| 2127 | 2127 | invb[b[i]] = i |
| 2128 | return _af_new([a[b[inva[i]]] for i in invb]) | |
| 2128 | return self._af_new([a[b[inva[i]]] for i in invb]) | |
| 2129 | 2129 | |
| 2130 | 2130 | def signature(self): |
| 2131 | 2131 | """ |
| 2390 | 2390 | return rank |
| 2391 | 2391 | |
| 2392 | 2392 | @classmethod |
| 2393 | def unrank_trotterjohnson(self, size, rank): | |
| 2393 | def unrank_trotterjohnson(cls, size, rank): | |
| 2394 | 2394 | """ |
| 2395 | 2395 | Trotter Johnson permutation unranking. See [4] section 2.4. |
| 2396 | 2396 | |
| 2423 | 2423 | perm[i] = perm[i - 1] |
| 2424 | 2424 | perm[k] = j - 1 |
| 2425 | 2425 | r2 = r1 |
| 2426 | return _af_new(perm) | |
| 2426 | return cls._af_new(perm) | |
| 2427 | 2427 | |
| 2428 | 2428 | def next_trotterjohnson(self): |
| 2429 | 2429 | """ |
| 2477 | 2477 | done = True |
| 2478 | 2478 | if m == 0: |
| 2479 | 2479 | return None |
| 2480 | return _af_new(pi) | |
| 2480 | return self._af_new(pi) | |
| 2481 | 2481 | |
| 2482 | 2482 | def get_precedence_matrix(self): |
| 2483 | 2483 | """ |
| 2734 | 2734 | except IndexError: |
| 2735 | 2735 | raise ValueError("The inversion vector is not valid.") |
| 2736 | 2736 | perm.extend(N) |
| 2737 | return _af_new(perm) | |
| 2737 | return self._af_new(perm) | |
| 2738 | 2738 | |
| 2739 | 2739 | @classmethod |
| 2740 | def random(self, n): | |
| 2740 | def random(cls, n): | |
| 2741 | 2741 | """ |
| 2742 | 2742 | Generates a random permutation of length ``n``. |
| 2743 | 2743 | |
| 2753 | 2753 | """ |
| 2754 | 2754 | perm_array = list(range(n)) |
| 2755 | 2755 | random.shuffle(perm_array) |
| 2756 | return _af_new(perm_array) | |
| 2756 | return cls._af_new(perm_array) | |
| 2757 | 2757 | |
| 2758 | 2758 | @classmethod |
| 2759 | def unrank_lex(self, size, rank): | |
| 2759 | def unrank_lex(cls, size, rank): | |
| 2760 | 2760 | """ |
| 2761 | 2761 | Lexicographic permutation unranking. |
| 2762 | 2762 | |
| 2787 | 2787 | if perm_array[j] > d - 1: |
| 2788 | 2788 | perm_array[j] += 1 |
| 2789 | 2789 | psize = new_psize |
| 2790 | return _af_new(perm_array) | |
| 2790 | return cls._af_new(perm_array) | |
| 2791 | 2791 | |
| 2792 | 2792 | # global flag to control how permutations are printed |
| 2793 | 2793 | # when True, Permutation([0, 2, 1, 3]) -> Cycle(1, 2) |
| Test Name | Status |
|---|---|
test_Permutation_subclassing | Fail |
test_josephus | Fail |
test_ranking | Fail |
test_mul | Fail |
test_from_sequence | Fail |
test_Permutation | Pass |
test_args | Pass |
test_Cycle | Pass |
test_printing_cyclic | Pass |
Loading...
Ridges.AI© 2025 Ridges AI. Building the future of decentralized AI development.
