Ticket #13742: trac_13742.patch
File trac_13742.patch, 19.6 KB (added by , 10 years ago) |
---|
-
sage/combinat/integer_vector_weighted.py
# HG changeset patch # User Nathann Cohen <nathann.cohen@gmail.com> # Date 1353594144 -3600 # Node ID 2687be1a040089cf46ec3290d801c879497c0aac # Parent 23061edf00176562a9d754123cfebbb8e3f631d3 No Permutation should be created that its method cannot handle diff --git a/sage/combinat/integer_vector_weighted.py b/sage/combinat/integer_vector_weighted.py
a b 1 1 """ 2 2 Weighted Integer Vectors 3 4 .. WARNING:: 5 6 This file uses the :class:`Permutation_class` class with the flag 7 ``check_input = False``. It should not. Do not trust the 8 results. See :trac:`13742`. 3 9 """ 4 10 #***************************************************************************** 5 11 # Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>, … … 157 163 158 164 perm = Word(self.weight).standard_permutation() 159 165 l = [x for x in sorted(self.weight)] 160 return [perm._left_to_right_multiply_on_right(Permutation_class(x )) for x in self._recfun(self.n,l)]166 return [perm._left_to_right_multiply_on_right(Permutation_class(x, check_input = False)) for x in self._recfun(self.n,l)] 161 167 -
sage/combinat/permutation.py
diff --git a/sage/combinat/permutation.py b/sage/combinat/permutation.py
a b 5 5 the Permutation class, and Permutations? to get information about 6 6 the combinatorial class of permutations. 7 7 8 .. WARNING:: 9 10 This file defined :class:`Permutation_class` which depends upon 11 :class:`CombinatorialObject` despite it being deprecated (see 12 :trac:`13742`). This is dangerous. In particular, the 13 :meth:`Permutation_class._left_to_right_multiply_on_right` method (which can 14 be called trough multiplication) disables the input checks (see 15 :method:`Permutation`). This should not happen. Do not trust the results. 16 8 17 AUTHORS: 9 18 10 19 - Mike Hansen … … 121 130 else: 122 131 permutation_options['display'] = kwargs['display'] 123 132 124 125 def Permutation(l): 133 def Permutation(l, check_input = True): 126 134 """ 127 Converts l to a permutation.128 135 Converts ``l`` to a permutation on `1...n` 136 129 137 INPUT: 130 131 132 - an instance of Permutation_class, 133 134 - list of integers, viewed as one-line 135 permutation notation, 136 137 - string, expressing the permutation in cycle 138 notation, 139 140 - list of tuples of integers, the permutation 141 in cycle notation. 142 143 - a PermutationGroupElement 144 145 - a pair of two tableaux of the same shape, where the second one is 146 standard. This uses the inverse of Robinson Schensted algorithm. 147 148 138 139 - an instance of :class:`Permutation_class`, 140 141 - list of integers, viewed as one-line permutation notation, 142 143 - string, expressing the permutation in cycle notation, 144 145 - list of tuples of integers, the permutation in cycle notation. 146 147 - a :class:`PermutationGroupElement` 148 149 - a pair of two tableaux of the same shape, where the second one is 150 standard. This uses the inverse of Robinson Schensted algorithm. 151 152 - ``check_input`` (boolean) -- whether to check that input is correct. Slows 153 the function down, but ensures that nothing bad happens. This is set to 154 ``True`` by default. 155 156 .. WARNING:: 157 158 Since :trac:`13742` the input is checked for correctness : it is not 159 accepted unless actually is a permutation on `1...n`. It means that some 160 :meth:`Permutation` objects cannot be created anymore without setting 161 ``check_input = False``, as there is no certainty that its functions can 162 handle them, and this should be fixed in a much better way ASAP (the 163 functions should be rewritten to handle those cases, and new tests be 164 added). 165 149 166 OUTPUT: 150 167 151 168 - :class:`Permutation_class` object. 152 169 153 170 EXAMPLES:: 154 171 155 172 sage: Permutation([2,1]) 156 173 [2, 1] 157 174 sage: Permutation([2, 1, 4, 5, 3]) … … 215 232 216 233 217 234 TESTS:: 218 235 219 236 sage: Permutation([()]) 220 237 [1] 221 238 sage: Permutation('()') … … 245 262 cycle_list = [] 246 263 for c in cycles: 247 264 cycle_list.append(map(int, c.split(","))) 265 248 266 return from_cycles(max([max(c) for c in cycle_list]), cycle_list) 249 267 250 268 #if l is a pair of tableaux or a pair of lists … … 257 275 return robinson_schensted_inverse(P, Q) 258 276 259 277 # if it's a tuple or nonempty list of tuples, also assume cycle 260 # notation 278 # notation 261 279 elif isinstance(l, tuple) or \ 262 280 (isinstance(l, list) and len(l) > 0 and 263 281 all(map(lambda x: isinstance(x, tuple), l))): … … 275 293 raise ValueError, "cannot convert l (= %s) to a Permutation"%l 276 294 277 295 # otherwise, it gets processed by CombinatorialObject's __init__. 278 return Permutation_class(l )296 return Permutation_class(l, check_input = check_input) 279 297 280 298 class Permutation_class(CombinatorialObject): 299 def __init__(self, l, check_input = True): 300 """ 301 Constructor. Checks that INPUT is not a mess, and calls 302 :class:`CombinatorialObject`. It should not, because 303 :class:`CombinatorialObject` is deprecated. 304 305 INPUT: 306 307 - ``l`` -- a list of ``int`` variables. 308 309 - ``check_input`` (boolean) -- whether to check that input is 310 correct. Slows the function down, but ensures that nothing bad 311 happens. 312 313 This is set to ``True`` by default. 314 315 TESTS:: 316 317 sage: from sage.combinat.permutation import Permutation_class 318 sage: Permutation_class([1,2,3]) 319 [1, 2, 3] 320 sage: Permutation_class([1,2,2,4]) 321 Traceback (most recent call last): 322 ... 323 ValueError: An element appears twice in the input. It should not. 324 sage: Permutation_class([1,2,4,-1]) 325 Traceback (most recent call last): 326 ... 327 ValueError: The elements must be strictly positive integers. 328 sage: Permutation_class([1,2,4,5]) 329 Traceback (most recent call last): 330 ... 331 ValueError: The permutation has length 4 but its maximal element is 332 5. Some element may be repeated, or an element is missing, but there 333 is something wrong with its length. 334 """ 335 if check_input: 336 l = list(l) 337 # Is input a list of positive integers ? 338 for i in l: 339 try: 340 i=int(i) 341 except TypeError: 342 raise ValueError("The elements must be integer variables") 343 if i < 1: 344 print i 345 raise ValueError("The elements must be strictly positive integers.") 346 347 348 sorted_copy = list(l) 349 350 # Empty list ? 351 if len(sorted_copy) == 0: 352 CombinatorialObject.__init__(self, l) 353 354 355 else: 356 sorted_copy.sort() 357 # Is the maximum element of the permutation the length of input, 358 # or is some integer missing ? 359 if int(sorted_copy[-1]) != len(l): 360 raise ValueError("The permutation has length "+str(len(l))+ 361 " but its maximal element is "+ 362 str(int(sorted_copy[-1]))+". Some element "+ 363 "may be repeated, or an element is missing"+ 364 ", but there is something wrong with its length.") 365 366 # Do the elements appear only once ? 367 previous = sorted_copy[0]-1 368 369 for i in sorted_copy: 370 if i == previous: 371 raise ValueError("An element appears twice in the input. It should not.") 372 else: 373 previous = i 374 375 CombinatorialObject.__init__(self, l) 376 else: 377 CombinatorialObject.__init__(self, l) 378 281 379 def __hash__(self): 282 380 """ 283 381 TESTS:: … … 517 615 518 616 The algorithm is of complexity `O(n)` where `n` is the size of the 519 617 given permutation. 520 618 521 619 TESTS:: 522 620 523 621 sage: from sage.combinat.permutation import from_cycles 524 sage: all(from_cycles(n, p.to_cycles()) == p 525 ... for n in range(6) for p in Permutations(n)) 526 True 527 622 sage: for n in range(1,6): 623 ... for p in Permutations(n): 624 ... if from_cycles(n, p.to_cycles()) != p: 625 ... print "There is a problem with ",p 626 ... break 528 627 sage: size = 10000 529 628 sage: sample = (Permutations(size).random_element() for i in range(5)) 530 629 sage: all(from_cycles(size, p.to_cycles()) == p for p in sample) … … 854 953 def __rmul__(self, lp): 855 954 """ 856 955 TESTS:: 857 956 858 957 sage: p213 = Permutation([2,1,3]) 859 958 sage: p312 = Permutation([3,1,2]) 860 959 sage: PermutationOptions(mult='l2r') … … 869 968 if permutation_options['mult'] == 'l2r': 870 969 return self._left_to_right_multiply_on_left(lp) 871 970 else: 872 return self._left_to_right_multiply_on_right(lp) 971 return self._left_to_right_multiply_on_right(lp) 873 972 874 973 def _left_to_right_multiply_on_left(self,lp): 875 974 """ 876 975 EXAMPLES:: 877 976 878 977 sage: p = Permutation([2,1,3]) 879 978 sage: q = Permutation([3,1,2]) 880 979 sage: p._left_to_right_multiply_on_left(q) … … 886 985 #different sizes 887 986 new_lp = lp[:] + [i+1 for i in range(len(lp), len(self))] 888 987 new_p1 = self[:] + [i+1 for i in range(len(self), len(lp))] 889 return Permutation([ new_p1[i-1] for i in new_lp ]) 890 988 return Permutation([ new_p1[i-1] for i in new_lp ]) 891 989 892 990 def _left_to_right_multiply_on_right(self, rp): 893 991 """ 894 992 EXAMPLES:: 895 993 896 994 sage: p = Permutation([2,1,3]) 897 995 sage: q = Permutation([3,1,2]) 898 996 sage: p._left_to_right_multiply_on_right(q) … … 904 1002 #different sizes 905 1003 new_rp = rp[:] + [i+1 for i in range(len(rp), len(self))] 906 1004 new_p1 = self[:] + [i+1 for i in range(len(self), len(rp))] 907 return Permutation([ new_rp[i-1] for i in new_p1 ] )1005 return Permutation([ new_rp[i-1] for i in new_p1 ], check_input = False) 908 1006 909 1007 def __call__(self, i): 910 1008 r""" … … 2610 2708 Returns the pair of standard tableaux obtained by running the 2611 2709 Robinson-Schensted Algorithm on self. 2612 2710 2711 .. WARNING:: 2712 2713 The following examples do not check their input. This is wrong. See 2714 :trac:`13742`. 2715 2613 2716 EXAMPLES:: 2614 2717 2615 sage: Permutation([6,2,3,1,7,5,4] ).robinson_schensted()2718 sage: Permutation([6,2,3,1,7,5,4], check_input = False).robinson_schensted() 2616 2719 [[[1, 3, 4], [2, 5], [6, 7]], [[1, 3, 5], [2, 6], [4, 7]]] 2617 2720 2618 2721 It also works in the case of repeated letters. In this case only the 2619 2722 second tableau is standard:: 2620 2723 2621 sage: Permutation([2,3,3,2,1,3,2,3] ).robinson_schensted()2724 sage: Permutation([2,3,3,2,1,3,2,3], check_input = False).robinson_schensted() 2622 2725 [[[1, 2, 2, 3, 3], [2, 3], [3]], [[1, 2, 3, 6, 8], [4, 7], [5]]] 2623 2726 2624 2727 TESTS: … … 3533 3636 def from_cycles(n, cycles): 3534 3637 r""" 3535 3638 Returns the permutation corresponding to cycles. 3536 3639 3640 This function checks that its input is correct (i.e. that the cycles are 3641 disjoint and its elements integers among `1...n`). It raises an exception 3642 otherwise. 3643 3644 .. WARNING:: 3645 3646 It assumes that the elements are of ``int`` type. 3647 3537 3648 EXAMPLES:: 3538 3649 3539 3650 sage: import sage.combinat.permutation as permutation 3540 3651 sage: permutation.from_cycles(4, [[1,2]]) 3541 3652 [2, 1, 3, 4] 3653 3654 Bad input (see :trac:`13742`):: 3655 3656 sage: Permutation("(-12,2)(3,4)") 3657 Traceback (most recent call last): 3658 ... 3659 ValueError: All elements should be strictly positive integers, and I just found a negative one. 3660 sage: Permutation("(1,2)(2,4)") 3661 Traceback (most recent call last): 3662 ... 3663 ValueError: An element appears twice. It should not. 3664 sage: permutation.from_cycles(4, [[1,18]]) 3665 Traceback (most recent call last): 3666 ... 3667 ValueError: You claimed that this was a permutation on 1...4 but it contains 18 3542 3668 """ 3543 3669 3544 3670 p = range(1,n+1) 3671 3672 # Is it really a permutation on 1...n ? 3673 flattened_and_sorted = [] 3674 for c in cycles: 3675 flattened_and_sorted.extend(c) 3676 flattened_and_sorted.sort() 3677 3678 # Empty input 3679 if len(flattened_and_sorted) == 0: 3680 # This is not consistent with Permutaion([]). See #13742 3681 return Permutation([1]) 3682 3683 # Only positive elements 3684 if int(flattened_and_sorted[0]) < 1: 3685 raise ValueError("All elements should be strictly positive " 3686 "integers, and I just found a negative one.") 3687 3688 # Really smaller than n ? 3689 if flattened_and_sorted[-1] > n: 3690 raise ValueError("You claimed that this was a permutation on 1..."+ 3691 str(n)+" but it contains "+str(flattened_and_sorted[-1])) 3692 3693 # Disjoint cycles ? 3694 previous = flattened_and_sorted[0]-1 3695 for i in flattened_and_sorted: 3696 if i == previous: 3697 raise ValueError("An element appears twice. It should not.") 3698 else: 3699 previous = i 3700 3545 3701 for cycle in cycles: 3546 3702 if not cycle: 3547 3703 continue … … 3549 3705 for i in range(len(cycle)-1): 3550 3706 p[cycle[i]-1] = cycle[i+1] 3551 3707 p[cycle[-1]-1] = first 3708 3552 3709 return Permutation(p) 3553 3710 3554 3711 def from_lehmer_code(lehmer): 3555 3712 r""" 3556 3713 Returns the permutation with Lehmer code lehmer. 3557 3714 3558 3715 EXAMPLES:: 3559 3716 3560 3717 sage: import sage.combinat.permutation as permutation 3561 3718 sage: Permutation([2,1,5,4,3]).to_lehmer_code() 3562 3719 [1, 0, 2, 1, 0] 3563 sage: permutation.from_lehmer_code(_) 3720 sage: permutation.from_lehmer_code(_) 3564 3721 [2, 1, 5, 4, 3] 3565 3722 """ 3566 3723 3567 3724 p = [] 3568 3725 open_spots = range(1,len(lehmer)+1) 3569 3726 for ivi in lehmer: … … 3574 3731 def from_reduced_word(rw): 3575 3732 r""" 3576 3733 Returns the permutation corresponding to the reduced word rw. 3577 3734 3578 3735 EXAMPLES:: 3579 3736 3580 3737 sage: import sage.combinat.permutation as permutation 3581 3738 sage: permutation.from_reduced_word([3,2,3,1,2,3,1]) 3582 3739 [3, 4, 2, 1] … … 3599 3756 Returns the permutation corresponding to the pair of tableaux `(p,q)` 3600 3757 using the inverse of Robinson-Schensted algorithm. 3601 3758 3759 .. WARNING:: 3760 3761 This function uses the :class:`Permutation_class` class in a way it is 3762 *NOT MEANT* to be used (i.e. the permutations are not permutations of 3763 integers). Do not trust it. See :trac:`13742`. 3764 3602 3765 INPUT: 3603 3766 3604 3767 - ``p``, ``q``: two tableaux of the same shape and where ``q`` is … … 3678 3841 y = bisect(row,x) - 1 3679 3842 x, row[y] = row[y], x 3680 3843 permutation.append(x) 3681 return Permutation(reversed(permutation) )3844 return Permutation(reversed(permutation), check_input = False) 3682 3845 3683 3846 def bistochastic_as_sum_of_permutations(M, check = True): 3684 3847 r""" … … 4150 4313 def from_major_code(mc, final_descent=False): 4151 4314 r""" 4152 4315 Returns the permutation corresponding to major code mc. 4316 4317 .. WARNING:: 4318 4319 This function creates illegal permutations (i.e. ``Permutation([9])``, 4320 and this is dangerous as the :meth:`Permutation` class is only designed 4321 to handle permutations on `1...n`. This will have to be changed when Sage 4322 permutations will be able to handle anything, but right now this should 4323 be fixed. Be careful with the results. 4153 4324 4154 4325 REFERENCES: 4155 4326 … … 4174 4345 #for i=n-1,..,1 let w^i be the unique word obtained by inserting 4175 4346 #the letter i into the word w^(i+1) in such a way that 4176 4347 #maj(w^i)-maj(w^(i+1)) = mc[i] 4348 4177 4349 for i in reversed(range(1,len(mc))): 4178 4350 #Lemma 2.2 in Skandera 4179 4351 4180 4352 #Get the descents of w and place them in reverse order 4181 d = Permutation(w ).descents(final_descent=final_descent)4353 d = Permutation(w, check_input = False).descents(final_descent=final_descent) 4182 4354 d.reverse() 4183 4355 4184 4356 #a is the list of all positions which are not descents -
sage/combinat/posets/hasse_diagram.py
diff --git a/sage/combinat/posets/hasse_diagram.py b/sage/combinat/posets/hasse_diagram.py
a b 127 127 128 128 :: 129 129 130 sage: P = Posets.SymmetricGroupBruhatIntervalPoset([ 0,1,2,3], [2,3,0,1])130 sage: P = Posets.SymmetricGroupBruhatIntervalPoset([1,2,3,4], [3,4,1,2]) 131 131 sage: P._hasse_diagram.plot() 132 132 """ 133 133 # Set element_labels to default to the vertex set. -
sage/combinat/posets/poset_examples.py
diff --git a/sage/combinat/posets/poset_examples.py b/sage/combinat/posets/poset_examples.py
a b 459 459 Any interval is rank symmetric if and only if it avoids these 460 460 permutations:: 461 461 462 sage: P1 = Posets.SymmetricGroupBruhatIntervalPoset([ 0,1,2,3], [2,3,0,1])463 sage: P2 = Posets.SymmetricGroupBruhatIntervalPoset([ 0,1,2,3], [3,1,2,0])462 sage: P1 = Posets.SymmetricGroupBruhatIntervalPoset([1,2,3,4], [3,4,1,2]) 463 sage: P2 = Posets.SymmetricGroupBruhatIntervalPoset([1,2,3,4], [4,2,3,1]) 464 464 sage: ranks1 = [P1.rank(v) for v in P1] 465 465 sage: ranks2 = [P2.rank(v) for v in P2] 466 466 sage: [ranks1.count(i) for i in uniq(ranks1)] -
sage/combinat/schubert_polynomial.py
diff --git a/sage/combinat/schubert_polynomial.py b/sage/combinat/schubert_polynomial.py
a b 216 216 Traceback (most recent call last): 217 217 ... 218 218 ValueError: The input [1, 2, 1] is not a valid permutation 219 sage: X._element_constructor_(Permutation([1,2,1]))220 Traceback (most recent call last):221 ...222 ValueError: The input [1, 2, 1] is not a valid permutation223 219 """ 224 220 if isinstance(x, list): 225 221 #checking the input to avoid symmetrica crashing Sage, see trac 12924 -
sage/graphs/comparability.pyx
diff --git a/sage/graphs/comparability.pyx b/sage/graphs/comparability.pyx
a b 111 111 112 112 .. MATH:: 113 113 114 \mbox{Maximize : }&\mbox{Nothing}\\ [2mm]114 \mbox{Maximize : }&\mbox{Nothing}\\ 115 115 \mbox{Such that : }&\\ 116 116 &\forall uv\in G\\ 117 &\cdot o_{uv}+o_{vu} = 1\\ [2mm]117 &\cdot o_{uv}+o_{vu} = 1\\ 118 118 &\forall u\in G, \forall v,v'\in N(v)\text{ such that }vv'\not\in G\\ 119 119 &\cdot o_{uv} + o_{v'u} - o_{v'v} \leq 1\\ 120 &\cdot o_{uv'} + o_{vu} - o_{vv'} \leq 1\\ [2mm]120 &\cdot o_{uv'} + o_{vu} - o_{vv'} \leq 1\\ 121 121 &\forall u\in G, \forall v,v'\in N(v)\text{ such that }vv'\in G\\ 122 122 &\cdot o_{uv} + o_{v'u} \leq 1\\ 123 &\cdot o_{uv'} + o_{vu} \leq 1\\ [2mm]123 &\cdot o_{uv'} + o_{vu} \leq 1\\ 124 124 &o_{uv}\text{ is a binary variable}\\ 125 125 126 126 .. NOTE:: … … 607 607 Plotting the realization as an intersection graph of segments:: 608 608 609 609 sage: true, perm = is_permutation(g, certificate = True) 610 sage: p1, p2 = map(Permutation, perm) 610 sage: p1 = Permutation([nn+1 for nn in perm[0]]) 611 sage: p2 = Permutation([nn+1 for nn in perm[1]]) 611 612 sage: p = p2 * p1.inverse() 612 613 sage: p.show(representation = "braid") 613 614