Ticket #13742: trac_13742.patch

File trac_13742.patch, 19.6 KB (added by ncohen, 8 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  
    11"""
    22Weighted 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`.
    39"""
    410#*****************************************************************************
    511#       Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
     
    157163
    158164        perm = Word(self.weight).standard_permutation()
    159165        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)]
    161167           
  • sage/combinat/permutation.py

    diff --git a/sage/combinat/permutation.py b/sage/combinat/permutation.py
    a b  
    55the Permutation class, and Permutations? to get information about
    66the combinatorial class of permutations.
    77
     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
    817AUTHORS:
    918
    1019- Mike Hansen
     
    121130        else:
    122131            permutation_options['display'] = kwargs['display']
    123132
    124 
    125 def Permutation(l):
     133def Permutation(l, check_input = True):
    126134    """
    127     Converts l to a permutation.
    128    
     135    Converts ``l`` to a permutation on `1...n`
     136
    129137    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
    149166    OUTPUT:
    150167
    151168    - :class:`Permutation_class` object.
    152    
     169
    153170    EXAMPLES::
    154    
     171
    155172        sage: Permutation([2,1])
    156173        [2, 1]
    157174        sage: Permutation([2, 1, 4, 5, 3])
     
    215232
    216233
    217234    TESTS::
    218    
     235
    219236        sage: Permutation([()])
    220237        [1]
    221238        sage: Permutation('()')
     
    245262        cycle_list = []
    246263        for c in cycles:
    247264            cycle_list.append(map(int, c.split(",")))
     265
    248266        return from_cycles(max([max(c) for c in cycle_list]), cycle_list)
    249267
    250268    #if l is a pair of tableaux or a pair of lists
     
    257275        return robinson_schensted_inverse(P, Q)
    258276
    259277    # if it's a tuple or nonempty list of tuples, also assume cycle
    260     # notation 
     278    # notation
    261279    elif isinstance(l, tuple) or \
    262280         (isinstance(l, list) and len(l) > 0 and
    263281         all(map(lambda x: isinstance(x, tuple), l))):
     
    275293            raise ValueError, "cannot convert l (= %s) to a Permutation"%l
    276294
    277295    # otherwise, it gets processed by CombinatorialObject's __init__.
    278     return Permutation_class(l)
     296    return Permutation_class(l, check_input = check_input)
    279297
    280298class 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
    281379    def __hash__(self):
    282380        """
    283381        TESTS::
     
    517615
    518616        The algorithm is of complexity `O(n)` where `n` is the size of the
    519617        given permutation.
    520            
     618
    521619        TESTS::
    522620
    523621            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
    528627            sage: size = 10000
    529628            sage: sample = (Permutations(size).random_element() for i in range(5))
    530629            sage: all(from_cycles(size, p.to_cycles()) == p for p in sample)
     
    854953    def __rmul__(self, lp):
    855954        """
    856955        TESTS::
    857        
     956
    858957            sage: p213 = Permutation([2,1,3])
    859958            sage: p312 = Permutation([3,1,2])
    860959            sage: PermutationOptions(mult='l2r')
     
    869968        if permutation_options['mult'] == 'l2r':
    870969            return self._left_to_right_multiply_on_left(lp)
    871970        else:
    872             return self._left_to_right_multiply_on_right(lp)     
     971            return self._left_to_right_multiply_on_right(lp)
    873972
    874973    def _left_to_right_multiply_on_left(self,lp):
    875974        """
    876975        EXAMPLES::
    877        
     976
    878977            sage: p = Permutation([2,1,3])
    879978            sage: q = Permutation([3,1,2])
    880979            sage: p._left_to_right_multiply_on_left(q)
     
    886985        #different sizes
    887986        new_lp = lp[:] + [i+1 for i in range(len(lp), len(self))]
    888987        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 ])
    891989
    892990    def _left_to_right_multiply_on_right(self, rp):
    893991        """
    894992        EXAMPLES::
    895        
     993
    896994            sage: p = Permutation([2,1,3])
    897995            sage: q = Permutation([3,1,2])
    898996            sage: p._left_to_right_multiply_on_right(q)
     
    9041002        #different sizes
    9051003        new_rp = rp[:] + [i+1 for i in range(len(rp), len(self))]
    9061004        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)
    9081006
    9091007    def __call__(self, i):
    9101008        r"""
     
    26102708        Returns the pair of standard tableaux obtained by running the
    26112709        Robinson-Schensted Algorithm on self.
    26122710
     2711        .. WARNING::
     2712
     2713            The following examples do not check their input. This is wrong. See
     2714            :trac:`13742`.
     2715
    26132716        EXAMPLES::
    26142717
    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()
    26162719            [[[1, 3, 4], [2, 5], [6, 7]], [[1, 3, 5], [2, 6], [4, 7]]]
    26172720
    26182721        It also works in the case of repeated letters. In this case only the
    26192722        second tableau is standard::
    26202723
    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()
    26222725            [[[1, 2, 2, 3, 3], [2, 3], [3]], [[1, 2, 3, 6, 8], [4, 7], [5]]]
    26232726
    26242727        TESTS:
     
    35333636def from_cycles(n, cycles):
    35343637    r"""
    35353638    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
    35373648    EXAMPLES::
    3538    
     3649
    35393650        sage: import sage.combinat.permutation as permutation
    35403651        sage: permutation.from_cycles(4, [[1,2]])
    35413652        [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
    35423668    """
    3543    
     3669
    35443670    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
    35453701    for cycle in cycles:
    35463702        if not cycle:
    35473703            continue
     
    35493705        for i in range(len(cycle)-1):
    35503706            p[cycle[i]-1] = cycle[i+1]
    35513707        p[cycle[-1]-1] = first
     3708
    35523709    return Permutation(p)
    35533710
    35543711def from_lehmer_code(lehmer):
    35553712    r"""
    35563713    Returns the permutation with Lehmer code lehmer.
    3557    
     3714
    35583715    EXAMPLES::
    3559    
     3716
    35603717        sage: import sage.combinat.permutation as permutation
    35613718        sage: Permutation([2,1,5,4,3]).to_lehmer_code()
    35623719        [1, 0, 2, 1, 0]
    3563         sage: permutation.from_lehmer_code(_) 
     3720        sage: permutation.from_lehmer_code(_)
    35643721        [2, 1, 5, 4, 3]
    35653722    """
    3566    
     3723
    35673724    p = []
    35683725    open_spots = range(1,len(lehmer)+1)
    35693726    for ivi in lehmer:
     
    35743731def from_reduced_word(rw):
    35753732    r"""
    35763733    Returns the permutation corresponding to the reduced word rw.
    3577    
     3734
    35783735    EXAMPLES::
    3579    
     3736
    35803737        sage: import sage.combinat.permutation as permutation
    35813738        sage: permutation.from_reduced_word([3,2,3,1,2,3,1])
    35823739        [3, 4, 2, 1]
     
    35993756    Returns the permutation corresponding to the pair of tableaux `(p,q)`
    36003757    using the inverse of Robinson-Schensted algorithm.
    36013758
     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
    36023765    INPUT:
    36033766
    36043767     - ``p``, ``q``: two tableaux of the same shape and where ``q`` is
     
    36783841            y = bisect(row,x) - 1
    36793842            x, row[y] = row[y], x
    36803843        permutation.append(x)
    3681     return Permutation(reversed(permutation))
     3844    return Permutation(reversed(permutation), check_input = False)
    36823845
    36833846def bistochastic_as_sum_of_permutations(M, check = True):
    36843847    r"""
     
    41504313def from_major_code(mc, final_descent=False):
    41514314    r"""
    41524315    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.
    41534324   
    41544325    REFERENCES:
    41554326
     
    41744345    #for i=n-1,..,1 let w^i be the unique word obtained by inserting
    41754346    #the letter i into the word w^(i+1) in such a way that
    41764347    #maj(w^i)-maj(w^(i+1)) = mc[i]
     4348
    41774349    for i in reversed(range(1,len(mc))):
    41784350        #Lemma 2.2 in Skandera
    41794351
    41804352        #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)
    41824354        d.reverse()
    41834355
    41844356        #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  
    127127       
    128128        ::
    129129       
    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])
    131131            sage: P._hasse_diagram.plot()
    132132        """
    133133        # 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  
    459459        Any interval is rank symmetric if and only if it avoids these
    460460        permutations::
    461461       
    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])
    464464            sage: ranks1 = [P1.rank(v) for v in P1]
    465465            sage: ranks2 = [P2.rank(v) for v in P2]
    466466            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  
    216216            Traceback (most recent call last):
    217217            ...
    218218            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 permutation
    223219        """
    224220        if isinstance(x, list):
    225221            #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  
    111111
    112112.. MATH::
    113113
    114     \mbox{Maximize : }&\mbox{Nothing}\\[2mm]
     114    \mbox{Maximize : }&\mbox{Nothing}\\
    115115    \mbox{Such that : }&\\
    116116    &\forall uv\in G\\
    117     &\cdot o_{uv}+o_{vu} = 1\\[2mm]
     117    &\cdot o_{uv}+o_{vu} = 1\\
    118118    &\forall u\in G, \forall v,v'\in N(v)\text{ such that }vv'\not\in G\\
    119119    &\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\\
    121121    &\forall u\in G, \forall v,v'\in N(v)\text{ such that }vv'\in G\\
    122122    &\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\\
    124124    &o_{uv}\text{ is a binary variable}\\
    125125
    126126.. NOTE::
     
    607607    Plotting the realization as an intersection graph of segments::
    608608
    609609        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]])
    611612        sage: p = p2 * p1.inverse()
    612613        sage: p.show(representation = "braid")
    613614