示例#1
0
    def random_element(self):
        r"""
        Return a uniformly random element of ``self``.

        ALGORITHM:

        This uses the
        :meth:`~sage.combinat.posets.posets.FinitePoset.random_order_ideal`
        method and the natural bijection with plane partitions.

        EXAMPLES::

            sage: P = PlanePartitions((4,3,5))
            sage: P.random_element()
            Plane partition [[4, 3, 3], [4, 0, 0], [2, 0, 0], [0, 0, 0]]
        """
        def leq(thing1, thing2):
            return all(thing1[i] <= thing2[i] for i in range(len(thing1)))
        elem = [(i,j,k) for i in range(self._box[0]) for j in range(self._box[1])
                for k in range(self._box[2])]
        myposet = Poset((elem, leq))
        R = myposet.random_order_ideal()
        Z = [[0 for i in range(self._box[1])] for j in range(self._box[0])]
        for C in R:
            Z[C[0]][C[1]] += 1
        return self.element_class(self, Z, check=False)
示例#2
0
def LatticePoset(data, *args, **options):
    r"""
    Construct a lattice from various forms of input data.

    INPUT:

    - ``data``, ``*args``, ``**options`` -- data and options that will
      be passed down to :func:`Poset` to construct a poset that is
      also a lattice.

    OUTPUT:

        FiniteLatticePoset -- an instance of :class:`FiniteLatticePoset`

    .. seealso:: :class:`Posets`, :class:`FiniteLatticePosets`, :func:`JoinSemiLattice`, :func:`MeetSemiLattice`

    EXAMPLES:

    Using data that defines a poset::

        sage: LatticePoset([[1,2],[3],[3]])
        Finite lattice containing 4 elements

        sage: LatticePoset([[1,2],[3],[3]], cover_relations = True)
        Finite lattice containing 4 elements

    Using a previously constructed poset::

        sage: P = Poset([[1,2],[3],[3]])
        sage: L = LatticePoset(P); L
        Finite lattice containing 4 elements
        sage: type(L)
        <class 'sage.combinat.posets.lattices.FiniteLatticePoset_with_category'>

    If the data is not a lattice, then an error is raised::

        sage: elms = [1,2,3,4,5,6,7]
        sage: rels = [[1,2],[3,4],[4,5],[2,5]]
        sage: LatticePoset((elms, rels))
        Traceback (most recent call last):
        ...
        ValueError: Not a lattice.

    Creating a facade lattice::

        sage: L = LatticePoset([[1,2],[3],[3]], facade = True)
        sage: L.category()
        Category of facade finite lattice posets
        sage: parent(L[0])
        Integer Ring
        sage: TestSuite(L).run(skip = ['_test_an_element']) # is_parent_of is not yet implemented

    """
    if isinstance(data,FiniteLatticePoset) and len(args) == 0 and len(options) == 0:
        return data
    P = Poset(data, *args, **options)
    if not P.is_lattice():
        raise ValueError, "Not a lattice."

    return FiniteLatticePoset(P, category = FiniteLatticePosets(), facade = P._is_facade)
        def green_classes(self, side = "twosided"):
            r"""
            INPUT:

             - ``side`` -- "left", "right", or "twosided"

            Depending on the value of ``side``, returns respectively
            the `L`-classes, `R`-classes, or `J`-classes of ``self``,
            sorted decreasingly along a linear extension of
            respectively `L`, `R` or `J`-order.

            EXAMPLES::

                sage: M = Semigroups().Finite().example(('a','b')); M
                An example of a finite semigroup: the left regular band generated by ('a', 'b')
                sage: M.green_classes()
                [{'a'}, {'b'}, {'ab', 'ba'}]
                sage: M.green_classes(side="left")
                [{'a'}, {'b'}, {'ab', 'ba'}]
                sage: M.green_classes(side="right")
                [{'b'}, {'a'}, {'ab'}, {'ba'}]
            """
            G = self.cayley_graph_cached(side=side, simple=True).strongly_connected_components_digraph()
            from sage.combinat.posets.posets import Poset
            P = Poset(G, facade = True)
            return P.linear_extension()
        def composition_series_poset(self, side = 'right'):
            """
            Experimental, and apparently broken ...

            EXAMPLES::

                sage: S = Monoids().Aperiodic().Finite().example(5); S
                The finite H-trivial monoid of order preserving maps on {1, 2, 3, 4, 5}
                sage: P = S.composition_series_poset(side = 'right')
                sage: list(P)
                [4, 3, 2, 1, 0]
                sage: P.cover_relations()
                []
                sage: P = S.composition_series_poset(side = 'left')
                sage: list(P)
                [4, 3, 2, 1, 0]
                sage: P.cover_relations()
            """
            from sage.combinat.posets.posets import Poset
            Js = self.regular_j_classes_keys()
            principal_order_filters = {}
            for J in Js:
                R = self.lr_regular_class_module(J, side=side)
                principal_order_filters[J] = R.composition_series()
                import time
                print "%s  %s: %s %s %s"%(time.strftime("%H:%M:%S"), J, self.simple_module_dimension(J), R.dimension(), principal_order_filters[J])
            P = Poset( ( Js, lambda J1, J2: J2 in principal_order_filters[J1] ), facade = True )
            from sage.sets.set import Set
            assert all( Set( P.principal_order_filter(J) ) == principal_order_filters[J]
                        for J in Js )
            return P
示例#5
0
    def to_poset(self, root_to_leaf = False):
        r"""
        Return the poset obtained by interpreting the tree as a hasse
        diagram. The default orientation is from leaves to root but you can
        pass ``root_to_leaf=True`` to obtain the inverse orientation.

        INPUT:

        - ``root_to_leaf`` -- boolean, true if the poset orientation should
          be from root to leaves. It is false by default.

        EXAMPLES::

            sage: t = OrderedTree([])
            sage: t.to_poset()
            Finite poset containing 1 elements
            sage: p = OrderedTree([[[]],[],[]]).to_poset()
            sage: p.cover_relations()
            [[3, 4], [2, 4], [0, 1], [1, 4]]
            sage: p = OrderedTree([[[]],[],[]]).to_poset(root_to_leaf=True)
            sage: p.cover_relations()
            [[0, 1], [0, 2], [0, 3], [3, 4]]

        If the tree is labelled, we use its labelling to label the poset.
        Otherwise, we use the poset canonical labelling::

            sage: t = OrderedTree([[[]],[],[]]).canonical_labelling()
            sage: t
            1[2[3[]], 4[], 5[]]
            sage: t.to_poset().cover_relations()
            [[5, 1], [4, 1], [3, 2], [2, 1]]
        """
        if self in LabelledOrderedTrees():
            relabel = False
        else:
            self = self.canonical_labelling()
            relabel = True
        relations = []
        elements = [self.label()]
        roots = [self]
        while len(roots)!=0:
            node = roots.pop()
            for child in node:
                elements.append(child.label())
                relations.append((node.label(),child.label()) if root_to_leaf else (child.label(),node.label()))
                roots.append(child)
        from sage.combinat.posets.posets import Poset
        p = Poset([elements, relations])
        if relabel:
            p = p.canonical_label()
        return p
示例#6
0
def MeetSemilattice(data, *args, **options):
    r"""
    Construct a meet semi-lattice from various forms of input data.

    INPUT:

    - ``data``, ``*args``, ``**options`` -- data and options that will
      be passed down to :func:`Poset` to construct a poset that is
      also a meet semilattice.

    .. seealso:: :func:`Poset`, :func:`JoinSemilattice`, :func:`LatticePoset`

    EXAMPLES:

    Using data that defines a poset::

          sage: MeetSemilattice([[1,2],[3],[3]])
          Finite meet-semilattice containing 4 elements

          sage: MeetSemilattice([[1,2],[3],[3]], cover_relations = True)
          Finite meet-semilattice containing 4 elements

    Using a previously constructed poset::

          sage: P = Poset([[1,2],[3],[3]])
          sage: L = MeetSemilattice(P); L
          Finite meet-semilattice containing 4 elements
          sage: type(L)
          <class 'sage.combinat.posets.lattices.FiniteMeetSemilattice_with_category'>

    If the data is not a lattice, then an error is raised::

          sage: elms = [1,2,3,4,5,6,7]
          sage: rels = [[1,2],[3,4],[4,5],[2,5]]
          sage: MeetSemilattice((elms, rels))
          Traceback (most recent call last):
          ...
          ValueError: Not a meet semilattice.
    """
    if isinstance(data,FiniteMeetSemilattice) and len(args) == 0 and len(options) == 0:
        return data
    P = Poset(data, *args, **options)
    if not P.is_meet_semilattice():
        raise ValueError, "Not a meet semilattice."
    return FiniteMeetSemilattice(P)
示例#7
0
    def __init__(self):
        r"""
        Container for all possible analytic types of forms and/or spaces.

        This class is supposed to be used as a Singleton.

        It first creates a ``Poset`` that contains all basic analytic
        properties to be modeled by the AnalyticType. Then the order
        ideals lattice of that Poset is taken as the underlying
        FiniteLatticePoset of ``self``.

        In particular elements of ``self`` describe what basic analytic
        properties are contained/included in that element.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT
            Analytic Type
            sage: isinstance(AT, FiniteLatticePoset)
            True

            sage: AT.is_lattice()
            True
            sage: AT.is_finite()
            True
            sage: AT.cardinality()
            10
            sage: AT.is_modular()
            True
            sage: AT.is_bounded()
            True
            sage: AT.is_distributive()
            True
            sage: AT.list()
            [zero,
             zero,
             cuspidal,
             modular,
             weakly holomorphic modular,
             quasi cuspidal,
             quasi modular,
             quasi weakly holomorphic modular,
             meromorphic modular,
             quasi meromorphic modular]
            sage: len(AT.relations())
            45
            sage: AT.cover_relations()
            [[zero, zero],
             [zero, cuspidal],
             [zero, quasi cuspidal],
             [cuspidal, modular],
             [cuspidal, quasi cuspidal],
             [modular, weakly holomorphic modular],
             [modular, quasi modular],
             [weakly holomorphic modular, quasi weakly holomorphic modular],
             [weakly holomorphic modular, meromorphic modular],
             [quasi cuspidal, quasi modular],
             [quasi modular, quasi weakly holomorphic modular],
             [quasi weakly holomorphic modular, quasi meromorphic modular],
             [meromorphic modular, quasi meromorphic modular]]
            sage: AT.has_top()
            True
            sage: AT.has_bottom()
            True
            sage: AT.top()
            quasi meromorphic modular
            sage: AT.bottom()
            zero
        """

        # We (arbitrarily) choose to model by inclusion instead of restriction
        P_elements = [ "cusp", "holo", "weak", "mero", "quasi"]
        P_relations = [["cusp", "holo"], ["holo", "weak"], ["weak", "mero"]]
        
        self._base_poset = Poset([P_elements, P_relations], cover_relations=True, facade=False)
        L = self._base_poset.order_ideals_lattice()
        L = FiniteLatticePoset(L, facade=False)

        FiniteLatticePoset.__init__(self, hasse_diagram=L._hasse_diagram, elements=L._elements, category=L.category(), facade=L._is_facade, key=None)
示例#8
0
class AnalyticType(FiniteLatticePoset):
    r"""
    Container for all possible analytic types of forms and/or spaces

    The ``analytic type`` of forms spaces or rings describes all possible
    occuring basic ``analytic properties`` of elements in the space/ring
    (or more).

    For ambient spaces/rings this means that all elements with those properties
    (and the restrictions of the space/ring) are contained in the space/ring.

    The analytic type of an element is the analytic type of its minimal
    ambient space/ring.

    The basic ``analytic properties`` are:

        - ``quasi``  - Whether the element is quasi modular (and not modular)
                       or modular.
        - ``mero``   - ``meromorphic``: If the element is meromorphic
                       and meromorphic at infinity.
        - ``weak``   - ``weakly holomorphic``: If the element is holomorphic
                       and meromorphic at infinity.
        - ``holo``   - ``holomorphic``: If the element is holomorphic and
                       holomorphic at infinity.
        - ``cusp``   - ``cuspidal``: If the element additionally has a positive
                       order at infinity.

    The ``zero`` elements/property have no analytic properties (or only ``quasi``).

    For ring elements the property describes whether one of its homogeneous
    components satisfies that property and the "union" of those properties
    is returned as the ``analytic type``.

    Similarly for quasi forms the property describes whether one of its
    quasi components satisfies that property.

    There is a (natural) partial order between the basic properties
    (and analytic types) given by "inclusion". We name the analytic type
    according to its maximal analytic properties.

    EXAMPLES::

    For n=3 the quasi form ``el = E6 - E2^3`` has the quasi components ``E6``
    which is ``holomorphic`` and ``E2^3`` which is ``quasi holomorphic``.
    So the analytic type of ``el`` is ``quasi holomorphic`` despite the fact
    that the sum (``el``) describes a function which is zero at infinity.
 
        sage: from space import QModularForms
        sage: x,y,z,d = var("x,y,z,d")
        sage: el = QModularForms(group=3, k=6, ep=-1)(y-z^3)
        sage: el.analytic_type()
        quasi modular

    Similarly the type of the ring element ``el2 = E4/Delta - E6/Delta`` is
    ``weakly holomorphic`` despite the fact that the sum (``el2``) describes
    a function which is holomorphic at infinity.

        sage: from graded_ring import WeakModularFormsRing
        sage: x,y,z,d = var("x,y,z,d")
        sage: el2 = WeakModularFormsRing(group=3)(x/(x^3-y^2)-y/(x^3-y^2))
        sage: el2.analytic_type()
        weakly holomorphic modular
    """

    Element = AnalyticTypeElement

    @staticmethod
    def __classcall__(cls):
        r"""
        Directly return the classcall of UniqueRepresentation
        (skipping the classcalls of the other superclasses).

        That's because ``self`` is supposed to be used as a Singleton.
        It initializes the FinitelatticePoset with the proper arguments
        by itself in ``self.__init__()``.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT2 = AnalyticType()
            sage: AT == AT2
            True
        """

        return super(FinitePoset, cls).__classcall__(cls)
                
    def __init__(self):
        r"""
        Container for all possible analytic types of forms and/or spaces.

        This class is supposed to be used as a Singleton.

        It first creates a ``Poset`` that contains all basic analytic
        properties to be modeled by the AnalyticType. Then the order
        ideals lattice of that Poset is taken as the underlying
        FiniteLatticePoset of ``self``.

        In particular elements of ``self`` describe what basic analytic
        properties are contained/included in that element.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT
            Analytic Type
            sage: isinstance(AT, FiniteLatticePoset)
            True

            sage: AT.is_lattice()
            True
            sage: AT.is_finite()
            True
            sage: AT.cardinality()
            10
            sage: AT.is_modular()
            True
            sage: AT.is_bounded()
            True
            sage: AT.is_distributive()
            True
            sage: AT.list()
            [zero,
             zero,
             cuspidal,
             modular,
             weakly holomorphic modular,
             quasi cuspidal,
             quasi modular,
             quasi weakly holomorphic modular,
             meromorphic modular,
             quasi meromorphic modular]
            sage: len(AT.relations())
            45
            sage: AT.cover_relations()
            [[zero, zero],
             [zero, cuspidal],
             [zero, quasi cuspidal],
             [cuspidal, modular],
             [cuspidal, quasi cuspidal],
             [modular, weakly holomorphic modular],
             [modular, quasi modular],
             [weakly holomorphic modular, quasi weakly holomorphic modular],
             [weakly holomorphic modular, meromorphic modular],
             [quasi cuspidal, quasi modular],
             [quasi modular, quasi weakly holomorphic modular],
             [quasi weakly holomorphic modular, quasi meromorphic modular],
             [meromorphic modular, quasi meromorphic modular]]
            sage: AT.has_top()
            True
            sage: AT.has_bottom()
            True
            sage: AT.top()
            quasi meromorphic modular
            sage: AT.bottom()
            zero
        """

        # We (arbitrarily) choose to model by inclusion instead of restriction
        P_elements = [ "cusp", "holo", "weak", "mero", "quasi"]
        P_relations = [["cusp", "holo"], ["holo", "weak"], ["weak", "mero"]]
        
        self._base_poset = Poset([P_elements, P_relations], cover_relations=True, facade=False)
        L = self._base_poset.order_ideals_lattice()
        L = FiniteLatticePoset(L, facade=False)

        FiniteLatticePoset.__init__(self, hasse_diagram=L._hasse_diagram, elements=L._elements, category=L.category(), facade=L._is_facade, key=None)

    def _repr_(self):
        r"""
        Return the string representation of ``self``.

        EXAMPLES::

            sage: AnalyticType()
            Analytic Type
        """

        return "Analytic Type"

    def __call__(self, *args, **kwargs):
        r"""
        Return the result of the corresponding call function
        of ``FiniteLatticePoset``.

        If more than one argument is given it is called with
        the list of those arguments instead.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT("holo", "quasi") == AT(["holo", "quasi"])
            True
        """

        if len(args)>1:
            return super(AnalyticType,self).__call__([arg for arg in args], **kwargs)
        else:
            return super(AnalyticType,self).__call__(*args, **kwargs)

    def _element_constructor_(self, element):
        r"""
        Return ``element`` coerced into an element of ``self``.

        INPUT:

        - ``element``   - Either something which coerces in the
                          ``FiniteLatticePoset`` of ``self`` or
                          a string or a list of strings of basic
                          properties that should be contained in
                          the new element.
                          

        OUTPUT:

        An element of ``self`` corresponding to ``element``
        (resp. containing all specified basic analytic properties).

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: AT("holo") == AT(["holo"])
            True
            sage: el = AT(["quasi", "holo"])
            sage: el
            quasi modular
            sage: el == AT(("holo", "quasi"))
            True
            sage: el.parent() == AT
            True
            sage: isinstance(el, AnalyticTypeElement)
            True
            sage: el.element
            {holo, cusp, quasi}
        """
        
        if type(element)==str:
            element=[element]
        if isinstance(element,list) or isinstance(element,tuple):
            element = Set(self._base_poset.order_ideal([self._base_poset(s) for s in element]))

        return super(AnalyticType, self)._element_constructor_(element)

        #res = self.first()
        #for element in args:
        #    if type(element)==str:
        #        element=[element]
        #    if isinstance(element,list) or isinstance(element,tuple):
        #        element = Set(self._base_poset.order_ideal([self._base_poset(s) for s in element]))
        #    element = super(AnalyticType,self)._element_constructor_(element)
        #    res += element
        #return res

    def base_poset(self):
        r"""
        Return the base poset from which everything of ``self``
        was constructed. Elements of the base poset correspond
        to the basic ``analytic properties``.

        EXAMPLES::

            sage: AT = AnalyticType()
            sage: P = AT.base_poset()
            sage: P
            Finite poset containing 5 elements
            sage: isinstance(P, FinitePoset)
            True

            sage: P.is_lattice()
            False
            sage: P.is_finite()
            True
            sage: P.cardinality()
            5
            sage: P.is_bounded()
            False
            sage: P.list()
            [quasi, cusp, holo, weak, mero]
            
            sage: len(P.relations())
            11
            sage: P.cover_relations()
            [[cusp, holo], [holo, weak], [weak, mero]]
            sage: P.has_top()
            False
            sage: P.has_bottom()
            False
        """

        return self._base_poset

    def lattice_poset(self):
        r"""
        Return the underlying lattice poset of ``self``.

        EXAMPLES::

            sage: AnalyticType().lattice_poset()
            Finite lattice containing 10 elements
        """

        return FiniteLatticePoset(self._base_poset.order_ideals_lattice(), facade=False)
                        
示例#9
0
    def RandomPoset(n, p):
        r"""
        Generate a random poset on ``n`` vertices according to a
        probability ``p``.

        INPUT:

        - ``n`` - number of vertices, a non-negative integer

        - ``p`` - a probability, a real number between 0 and 1 (inclusive)

        OUTPUT:

        A poset on ``n`` vertices.  The construction decides to make an
        ordered pair of vertices comparable in the poset with probability
        ``p``, however a pair is not made comparable if it would violate
        the defining properties of a poset, such as transitivity.

        So in practice, once the probability exceeds a small number the
        generated posets may be very similar to a chain.  So to create
        interesting examples, keep the probability small, perhaps on the
        order of `1/n`.

        EXAMPLES::

            sage: Posets.RandomPoset(17,.15)
            Finite poset containing 17 elements

        TESTS::

            sage: Posets.RandomPoset('junk', 0.5)
            Traceback (most recent call last):
            ...
            TypeError: number of elements must be an integer, not junk

            sage: Posets.RandomPoset(-6, 0.5)
            Traceback (most recent call last):
            ...
            ValueError: number of elements must be non-negative, not -6

            sage: Posets.RandomPoset(6, 'garbage')
            Traceback (most recent call last):
            ...
            TypeError: probability must be a real number, not garbage

            sage: Posets.RandomPoset(6, -0.5)
            Traceback (most recent call last):
            ...
            ValueError: probability must be between 0 and 1, not -0.5
        """
        try:
            n = Integer(n)
        except TypeError:
            raise TypeError(
                "number of elements must be an integer, not {0}".format(n))
        if n < 0:
            raise ValueError(
                "number of elements must be non-negative, not {0}".format(n))
        try:
            p = float(p)
        except Exception:
            raise TypeError(
                "probability must be a real number, not {0}".format(p))
        if p < 0 or p > 1:
            raise ValueError(
                "probability must be between 0 and 1, not {0}".format(p))

        D = DiGraph(loops=False, multiedges=False)
        D.add_vertices(range(n))
        for i in range(n):
            for j in range(n):
                if random.random() < p:
                    D.add_edge(i, j)
                    if not D.is_directed_acyclic():
                        D.delete_edge(i, j)
        return Poset(D, cover_relations=False)
示例#10
0
        def weak_poset(self, side="right", facade=False):
            """
            INPUT:

            - ``side`` -- "left", "right", or "twosided" (default: "right")
            - ``facade`` -- a boolean (default: ``False``)

            Returns the left (resp. right) poset for weak order.  In
            this poset, `u` is smaller than `v` if some reduced word
            of `u` is a right (resp. left) factor of some reduced word
            of `v`.

            EXAMPLES::

                sage: W = WeylGroup(["A", 2])
                sage: P = W.weak_poset()
                sage: P
                Finite lattice containing 6 elements
                sage: P.show()

            This poset is in fact a lattice::

                sage: W = WeylGroup(["B", 3])
                sage: P = W.weak_poset(side = "left")
                sage: P.is_lattice()
                True

            so this method has an alias :meth:`weak_lattice`::

                sage: W.weak_lattice(side = "left") is W.weak_poset(side = "left")
                True

            As a bonus feature, one can create the left-right weak
            poset::

                sage: W = WeylGroup(["A",2])
                sage: P = W.weak_poset(side = "twosided")
                sage: P.show()
                sage: len(P.hasse_diagram().edges())
                8

            This is the transitive closure of the union of left and
            right order. In this poset, `u` is smaller than `v` if
            some reduced word of `u` is a factor of some reduced word
            of `v`. Note that this is not a lattice::

                sage: P.is_lattice()
                False

            By default, the elements of `P` are aware of that they
            belong to `P`::

                sage: P.an_element().parent()
                Finite poset containing 6 elements

            If instead one wants the elements to be plain elements of
            the Coxeter group, one can use the ``facade`` option::

                sage: P = W.weak_poset(facade = True)
                sage: P.an_element().parent()
                Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space)

            .. see also:: :func:`Poset` for more on posets and facade posets.

            TESTS::

                sage: [len(WeylGroup(["A", n]).weak_poset(side = "right").cover_relations()) for n in [1,2,3]]
                [1, 6, 36]
                sage: [len(WeylGroup(["A", n]).weak_poset(side = "left" ).cover_relations()) for n in [1,2,3]]
                [1, 6, 36]

            .. todo::

                - Use the symmetric group in the examples (for nicer
                  output), and print the edges for a stronger test.
                - The constructed poset should be lazy, in order to
                  handle large / infinite Coxeter groups.
            """
            from sage.combinat.posets.posets import Poset
            from sage.combinat.posets.lattices import LatticePoset
            if side == "twosided":
                covers = tuple([u, v] for u in self
                               for v in u.upper_covers(side="left") +
                               u.upper_covers(side="right"))
                return Poset((self, covers),
                             cover_relations=True,
                             facade=facade)
            else:
                covers = tuple([u, v] for u in self
                               for v in u.upper_covers(side=side))
                return LatticePoset((self, covers),
                                    cover_relations=True,
                                    facade=facade)