Ticket #13240: trac_1324O_first_step-fc.patch

File trac_1324O_first_step-fc.patch, 11.0 KB (added by chapoton, 5 years ago)
  • sage/combinat/posets/posets.py

    # HG changeset patch
    # User Frederic Chapoton <chapoton at math.univ-lyon1.fr>
    # Date 1367782639 -7200
    # Node ID 0b85d13c6b96f504d435215c6bd35dfddc65cf4b
    # Parent  87c9fe9f681802dec0e562ce562f21eece327a38
    trac #13240 a few polynomials associated with posets
    
    diff --git a/sage/combinat/posets/posets.py b/sage/combinat/posets/posets.py
    a b This module implements finite partialy o 
    3636    :meth:`~FinitePoset.coxeter_transformation` | Returns the matrix of the Auslander-Reiten translation acting on the Grothendieck group of the derived category of modules
    3737    :meth:`~FinitePoset.dual` | Returns the dual poset of the given poset.
    3838    :meth:`~FinitePoset.evacuation` | Computes evacuation on the linear extension associated to the poset ``self``.
     39    :meth:`~FinitePoset.f_polynomial` | Returns the f-polynomial of a bounded poset.
     40    :meth:`~FinitePoset.flag_f_polynomial` | Returns the flag f-polynomial of a bounded and ranked poset.
     41    :meth:`~FinitePoset.flag_h_polynomial` | Returns the flag h-polynomial of a bounded and ranked poset.
    3942    :meth:`~FinitePoset.frank_network` | Returns Frank's network (a DiGraph along with a cost function on its edges) associated to ``self``.
    4043    :meth:`~FinitePoset.graphviz_string` | Returns a representation in the DOT language, ready to render in graphviz.
    4144    :meth:`~FinitePoset.greene_shape` | Computes the Greene-Kleitman partition aka Greene shape of the poset ``self``.
     45    :meth:`~FinitePoset.h_polynomial` | Returns the h-polynomial of a bounded poset.
    4246    :meth:`~FinitePoset.has_bottom` | Returns True if the poset has a unique minimal element.
    4347    :meth:`~FinitePoset.hasse_diagram` | Returns the Hasse diagram of ``self`` as a Sage :class:`DiGraph`.
    4448    :meth:`~FinitePoset.has_top` | Returns True if the poset contains a unique maximal element, and False otherwise.
    This module implements finite partialy o 
    8892    :meth:`~FinitePoset.relabel` | Returns a copy of this poset with its elements relabelled
    8993    :meth:`~FinitePoset.relations_iterator` | Returns an iterator for all the relations of the poset.
    9094    :meth:`~FinitePoset.relations` | Returns a list of all relations of the poset.
     95    :meth:`~FinitePoset.remove_top_and_bottom` | Removes the extremities of a bounded poset.
    9196    :meth:`~FinitePoset.show` | Shows the Graphics object corresponding the Hasse diagram of the poset.
    9297    :meth:`~FinitePoset.subposet` | Returns the poset containing elements with partial order induced by that of self.
    9398    :meth:`~FinitePoset.top` | Returns the top element of the poset, if it exists.
    This module implements finite partialy o 
    95100    :meth:`~FinitePoset.upper_covers_iterator` | Returns an iterator for the upper covers of the element y. An upper cover of y is an element x such that y x is a cover relation.
    96101    :meth:`~FinitePoset.upper_covers` | Returns a list of upper covers of the element y. An upper cover of y is an element x such that y x is a cover relation.
    97102    :meth:`~FinitePoset.with_linear_extension` | Returns a copy of ``self`` with a different default linear extension
     103    :meth:`~FinitePoset.zeta_polynomial` | Returns the zeta polynomial of the poset.
    98104
    99105Classes and functions
    100106---------------------
    import random 
    119125import copy
    120126from sage.misc.cachefunc import cached_method
    121127from sage.misc.lazy_attribute import lazy_attribute
     128from sage.misc.misc_c import prod
    122129from sage.misc.superseded import deprecated_function_alias
    123130from sage.categories.category import Category
    124131from sage.categories.sets_cat import Sets
    from sage.structure.unique_representatio 
    129136from sage.structure.parent import Parent
    130137from sage.rings.integer import Integer
    131138from sage.rings.integer_ring import ZZ
     139from sage.rings.rational_field import QQ
     140from sage.rings.polynomial.polynomial_ring import polygen
    132141from sage.graphs.digraph import DiGraph
    133142from sage.graphs.digraph_generators import digraphs
    134143from sage.combinat.posets.hasse_diagram import HasseDiagram
    135144from sage.combinat.posets.elements import PosetElement
    136145from sage.combinat.combinatorial_map import combinatorial_map
    137146
     147
    138148def Poset(data=None, element_labels=None, cover_relations=False, linear_extension=False, category = None, facade = None, key = None):
    139149    r"""
    140150    Construct a finite poset from various forms of input data.
    class FinitePoset(UniqueRepresentation,  
    32693279            ineqs+=[[0]+[ZZ(j==i) for j in self]]
    32703280        return Polyhedron(ieqs=ineqs)
    32713281
     3282
     3283    def zeta_polynomial(self):
     3284        r"""
     3285        Return the zeta polynomial of the poset
     3286
     3287        The zeta polynomial of a poset is the unique polynomial `Z(q)`
     3288        such that for every integer `m > 1`, `Z(m)` is the number of
     3289        weakly increasing sequences `x_1 \leq x_2 \leq \dots \leq x_{m-1}`.
     3290
     3291        In particular, `Z(2)` is the number of vertices and `Z(3)` is
     3292        the number of intervals.
     3293
     3294        EXAMPLES::
     3295
     3296            sage: Posets.ChainPoset(2).zeta_polynomial()
     3297            q
     3298            sage: Posets.ChainPoset(3).zeta_polynomial()
     3299            1/2*q^2 + 1/2*q
     3300            sage: P = posets.PentagonPoset()
     3301            sage: P.zeta_polynomial()
     3302            1/6*q^3 + q^2 - 1/6*q
     3303            sage: P = Posets.DiamondPoset(5)
     3304            sage: P.zeta_polynomial()
     3305            3/2*q^2 - 1/2*q
     3306        """
     3307        q = polygen(QQ, 'q')
     3308        g = sum(q**len(ch) for ch in self.chains())
     3309        n = g.degree()
     3310        f = g[max(n, 1)]
     3311        while n > 1:
     3312            f = (q - n)*f
     3313            n = n - 1
     3314            f = g[n] + f/n
     3315        return f
     3316
     3317
     3318    def remove_top_and_bottom(self):
     3319        r"""
     3320        removes the top and bottom of a bounded poset
     3321
     3322        EXAMPLES::
     3323
     3324            sage: Q = Posets.DiamondPoset(5).remove_top_and_bottom()
     3325            sage: Q.is_isomorphic(Posets.AntichainPoset(3))
     3326            True
     3327
     3328        TESTS::
     3329
     3330            sage: P = Poset({1:[2, 3]})
     3331            sage: P.remove_top_and_bottom()
     3332            Traceback (most recent call last):
     3333            ...
     3334            TypeError: the poset is not bounded
     3335        """
     3336        if not(self.is_bounded()):
     3337            raise TypeError('the poset is not bounded')
     3338        return self.subposet([v for v in self
     3339                              if not(v in self.minimal_elements()
     3340                                     or v in self.maximal_elements())])
     3341
     3342
     3343    def f_polynomial(self):
     3344        r"""
     3345        Return the f-polynomial of a bounded poset
     3346
     3347        EXAMPLES::
     3348
     3349            sage: P = Posets.DiamondPoset(5)
     3350            sage: P.f_polynomial()
     3351            3*q^2 + q
     3352            sage: P = Poset({1:[2,3],2:[4],3:[5],4:[6],5:[7],6:[7]})
     3353            sage: P.f_polynomial()
     3354            q^4 + 4*q^3 + 5*q^2 + q
     3355        """
     3356        P = self.remove_top_and_bottom()
     3357        q = polygen(ZZ, 'q')
     3358        if self.cardinality() == 0:
     3359            return q.parent().one()
     3360        else:
     3361            return q*sum(q**len(ch) for ch in P.chains())
     3362
     3363
     3364    def h_polynomial(self):
     3365        r"""
     3366        Return the h-polynomial of a bounded poset
     3367
     3368        EXAMPLES::
     3369
     3370            sage: P = Posets.AntichainPoset(3).order_ideals_lattice()
     3371            sage: P.h_polynomial()
     3372            q^3 + 4*q^2 + q
     3373            sage: P = Posets.DiamondPoset(5)
     3374            sage: P.h_polynomial()
     3375            2*q^2 + q
     3376        """
     3377        P = self.remove_top_and_bottom()
     3378        q = polygen(ZZ, 'q')
     3379        if self.cardinality() == 0:
     3380            return q.parent().one()
     3381        f = sum(q**len(ch) for ch in P.chains())
     3382        d = f.degree()
     3383        f = (1-q)**d * q * f(q=q/(1-q))
     3384        return q.parent(f)
     3385
     3386
     3387    def flag_f_polynomial(self):
     3388        r"""
     3389        Return the flag f-polynomial of a bounded and ranked poset
     3390
     3391        EXAMPLES::
     3392
     3393            sage: P = Posets.DiamondPoset(5)
     3394            sage: P.flag_f_polynomial()
     3395            3*x1*x2 + x2
     3396
     3397            sage: P = Poset({1:[2,3],2:[4],3:[5],4:[6],5:[6]})
     3398            sage: fl = P.flag_f_polynomial(); fl
     3399            2*x1*x2*x3 + 2*x1*x3 + 2*x2*x3 + x3
     3400            sage: q = polygen(ZZ,'q')
     3401            sage: fl(q,q,q,q) == P.f_polynomial()
     3402            True
     3403
     3404            sage: P = Poset({1:[2,3,4],2:[5],3:[5],4:[5],5:[6]})
     3405            sage: P.flag_f_polynomial()
     3406            3*x1*x2*x3 + 3*x1*x3 + x2*x3 + x3
     3407        """
     3408        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
     3409        P = self.remove_top_and_bottom()
     3410        if not(self.is_ranked()):
     3411            raise TypeError('the poset should be ranked')
     3412        rk = P.rank_function()
     3413        n = rk(P.maximal_elements()[0])
     3414        anneau = PolynomialRing(ZZ, 'x', n+3)
     3415        if self.cardinality() == 0:
     3416            return anneau.one()
     3417        else:
     3418            x = anneau.gens()
     3419            return x[n+2]*sum(prod(x[1+rk(i)] for i in ch) for ch in P.chains())
     3420
     3421
     3422    def flag_h_polynomial(self):
     3423        r"""
     3424        Return the flag h-polynomial of a bounded and ranked poset
     3425
     3426        EXAMPLES::
     3427
     3428            sage: P = Posets.DiamondPoset(5)
     3429            sage: P.flag_h_polynomial()
     3430            2*x1*x2 + x2
     3431
     3432            sage: P = Poset({1:[2,3],2:[4],3:[5],4:[6],5:[6]})
     3433            sage: fl = P.flag_h_polynomial(); fl
     3434            -x1*x2*x3 + x1*x3 + x2*x3 + x3
     3435            sage: q = polygen(ZZ,'q')
     3436            sage: fl(q,q,q,q) == P.h_polynomial()
     3437            True
     3438
     3439            sage: P = Poset({1:[2,3,4],2:[5],3:[5],4:[5],5:[6]})
     3440            sage: P.flag_h_polynomial()
     3441            2*x1*x3 + x3
     3442
     3443            sage: P = posets.ChainPoset(4)
     3444            sage: P.flag_h_polynomial()
     3445            x3
     3446        """
     3447        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
     3448        P = self.remove_top_and_bottom()
     3449        if not(self.is_ranked()):
     3450            raise TypeError('the poset should be ranked')
     3451        rk = P.rank_function()
     3452        n = rk(P.maximal_elements()[0])
     3453        anneau = PolynomialRing(QQ, 'x', n+3)
     3454        if self.cardinality() == 0:
     3455            return anneau.one()
     3456        else:
     3457            x = anneau.gens()
     3458            return prod(1-x[k] for k in range(1, n+2))*x[n+2]*sum(prod(x[1+rk(i)]/(1-x[1+rk(i)]) for i in ch) for ch in P.chains())
     3459
     3460
     3461    def characteristic_polynomial(self):
     3462        r"""
     3463        Return the characteristic-polynomial of a graded poset
     3464
     3465        EXAMPLES::
     3466
     3467            sage: P = Posets.DiamondPoset(5)
     3468            sage: P.characteristic_polynomial()
     3469            q^2 - 3*q + 2
     3470            sage: P = Poset({1:[2,3],2:[4],3:[5],4:[6],5:[6],6:[7]})
     3471            sage: P.characteristic_polynomial()
     3472            q^4 - 2*q^3 + q
     3473        """
     3474        if not(self.is_ranked()):
     3475            raise TypeError('the poset should be ranked')
     3476        rk = self.rank_function()
     3477        n = rk(self.maximal_elements()[0])
     3478        x0 = self.minimal_elements()[0]
     3479        q = polygen(ZZ, 'q')
     3480        return sum(self.mobius_function(x0, x)*q**(n - rk(x)) for x in self)
     3481
     3482
    32723483    def promotion(self, i=1):
    32733484        r"""
    32743485        Computes the (extended) promotion on the linear extension of the poset ``self``