Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Non-symmetric Macdonald Polynomials """ from sage.combinat.combinat import CombinatorialObject, CombinatorialClass from sage.combinat.words.word import Word from sage.combinat.combination import Combinations from sage.combinat.permutation import Permutation from sage.rings.all import QQ, PolynomialRing from sage.misc.all import prod from sage.combinat.backtrack import GenericBacktracker import copy
class LatticeDiagram(CombinatorialObject): def boxes(self): """ EXAMPLES::
sage: a = LatticeDiagram([3,0,2]) sage: a.boxes() [(1, 1), (1, 2), (1, 3), (3, 1), (3, 2)] sage: a = LatticeDiagram([2, 1, 3, 0, 0, 2]) sage: a.boxes() [(1, 1), (1, 2), (2, 1), (3, 1), (3, 2), (3, 3), (6, 1), (6, 2)] """
def __getitem__(self, i): """ Return the `i^{th}` entry of ``self``. Note that the indexing for lattice diagrams starts at `1`.
EXAMPLES::
sage: a = LatticeDiagram([3,0,2]) sage: a[1] 3 sage: a[0] Traceback (most recent call last): ... ValueError: indexing starts at 1 sage: a[-1] 2 """
def leg(self, i, j): """ Return the leg of the box ``(i,j)`` in ``self``.
EXAMPLES::
sage: a = LatticeDiagram([3,1,2,4,3,0,4,2,3]) sage: a.leg(5,2) [(5, 3)] """
def arm_left(self, i, j): """ Return the left arm of the box ``(i,j)`` in ``self``.
EXAMPLES::
sage: a = LatticeDiagram([3,1,2,4,3,0,4,2,3]) sage: a.arm_left(5,2) [(1, 2), (3, 2)] """
def arm_right(self, i, j): """ Return the right arm of the box ``(i,j)`` in ``self``.
EXAMPLES::
sage: a = LatticeDiagram([3,1,2,4,3,0,4,2,3]) sage: a.arm_right(5,2) [(8, 1)] """
def arm(self, i, j): """ Return the arm of the box ``(i,j)`` in ``self``.
EXAMPLES::
sage: a = LatticeDiagram([3,1,2,4,3,0,4,2,3]) sage: a.arm(5,2) [(1, 2), (3, 2), (8, 1)] """
def l(self, i, j): """ Return ``self[i] - j``.
EXAMPLES::
sage: a = LatticeDiagram([3,1,2,4,3,0,4,2,3]) sage: a.l(5,2) 1 """
def a(self, i, j): """ Return the length of the arm of the box ``(i,j)`` in ``self``.
EXAMPLES::
sage: a = LatticeDiagram([3,1,2,4,3,0,4,2,3]) sage: a.a(5,2) 3 """
def size(self): """ Return the number of boxes in ``self``.
EXAMPLES::
sage: a = LatticeDiagram([3,1,2,4,3,0,4,2,3]) sage: a.size() 22 """
def flip(self): """ Return the flip of ``self``, where flip is defined as follows. Let ``r = max(self)``. Then ``self.flip()[i] = r - self[i]``.
EXAMPLES::
sage: a = LatticeDiagram([3,0,2]) sage: a.flip() [0, 3, 1] """
def boxes_same_and_lower_right(self, ii, jj): """ Return a list of the boxes of ``self`` that are in row ``jj`` but not identical with ``(ii, jj)``, or lie in the row ``jj - 1`` (the row directly below ``jj``; this might be the basement) and strictly to the right of ``(ii, jj)``.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a = a.shape() sage: a.boxes_same_and_lower_right(1,1) [(2, 1), (3, 1), (6, 1), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0)] sage: a.boxes_same_and_lower_right(1,2) [(3, 2), (6, 2), (2, 1), (3, 1), (6, 1)] sage: a.boxes_same_and_lower_right(3,3) [(6, 2)] sage: a.boxes_same_and_lower_right(2,3) [(3, 3), (3, 2), (6, 2)] """ #Add all of the boxes in the same row
class AugmentedLatticeDiagramFilling(CombinatorialObject): def __init__(self, l, pi=None): """ EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a == loads(dumps(a)) True sage: pi = Permutation([2,3,1]).to_permutation_group_element() sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]],pi) sage: a == loads(dumps(a)) True """
def __getitem__(self, i): """ EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a[0] Traceback (most recent call last): ... ValueError: indexing starts at 1 sage: a[1,0] 1 sage: a[2,0] 2 sage: a[3,2] 4 sage: a[3][2] 4 """
def shape(self): """ Return the shape of ``self``.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.shape() [2, 1, 3, 0, 0, 2] """
def __contains__(self, ij): """ Return ``True`` if the box ``(i,j) (= ij)`` is in ``self``. Note that this does not include the basement row.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: (1,1) in a True sage: (1,0) in a False """
def are_attacking(self, i,j, ii, jj): """ Return ``True`` if the boxes ``(i,j)`` and ``(ii,jj)`` in ``self`` are attacking.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: all( a.are_attacking(i,j,ii,jj) for (i,j),(ii,jj) in a.attacking_boxes()) True sage: a.are_attacking(1,1,3,2) False """ #If the two boxes are at the same height, #then they are attacking
#Make it so that the lower box is in position i,j
#If the lower box is one row below and #strictly to the right, then they are #attacking.
def boxes(self): """ Return a list of the coordinates of the boxes of ``self``, including the 'basement row'.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.boxes() [(1, 1), (1, 2), (2, 1), (3, 1), (3, 2), (3, 3), (6, 1), (6, 2), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0)] """
def attacking_boxes(self): """ Returns a list of pairs of boxes in ``self`` that are attacking.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.attacking_boxes()[:5] [((1, 1), (2, 1)), ((1, 1), (3, 1)), ((1, 1), (6, 1)), ((1, 1), (2, 0)), ((1, 1), (3, 0))] """
def is_non_attacking(self): """ Return ``True`` if ``self`` is non-attacking.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.is_non_attacking() True sage: a = AugmentedLatticeDiagramFilling([[1, 1, 1], [2, 3], [3]]) sage: a.is_non_attacking() False sage: a = AugmentedLatticeDiagramFilling([[2,2],[1]]) sage: a.is_non_attacking() False sage: pi = Permutation([2,1]).to_permutation_group_element() sage: a = AugmentedLatticeDiagramFilling([[2,2],[1]],pi) sage: a.is_non_attacking() True """
def weight(self): """ Return the weight of ``self``.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.weight() [1, 2, 1, 1, 2, 1] """
def descents(self): """ Return a list of the descents of ``self``.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.descents() [(1, 2), (3, 2)] """
def maj(self): """ Return the major index of ``self``.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.maj() 3 """
def reading_order(self): """ Return a list of coordinates of the boxes in ``self``, starting from the top right, and reading from right to left. Note that this includes the 'basement row' of ``self``.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.reading_order() [(3, 3), (6, 2), (3, 2), (1, 2), (6, 1), (3, 1), (2, 1), (1, 1), (6, 0), (5, 0), (4, 0), (3, 0), (2, 0), (1, 0)] """
def reading_word(self): """ Return the reading word of ``self``, obtained by reading the boxes entries of self from right to left, starting in the upper right.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.reading_word() word: 25465321 """
def inversions(self): """ Return a list of the inversions of ``self``.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.inversions()[:5] [((6, 2), (3, 2)), ((1, 2), (6, 1)), ((1, 2), (3, 1)), ((1, 2), (2, 1)), ((6, 1), (3, 1))] sage: len(a.inversions()) 25 """
def _inv_aux(self): """ EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a._inv_aux() 7 """
def inv(self): """ Return ``self``'s inversion statistic.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.inv() 15 """
def coinv(self): """ Return ``self``'s co-inversion statistic.
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: a.coinv() 2 """
def coeff(self, q, t): """ Return the coefficient in front of ``self`` in the HHL formula for the expansion of the non-symmetric Macdonald polynomial E(self.shape()).
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: q,t = var('q,t') sage: a.coeff(q,t) (t - 1)^4/((q^2*t^3 - 1)^2*(q*t^2 - 1)^2) """
def coeff_integral(self, q, t): """ Return the coefficient in front of ``self`` in the HHL formula for the expansion of the integral non-symmetric Macdonald polynomial E(self.shape())
EXAMPLES::
sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: q,t = var('q,t') sage: a.coeff_integral(q,t) (q^2*t^3 - 1)^2*(q*t^2 - 1)^2*(t - 1)^4 """
def permuted_filling(self, sigma): """ EXAMPLES::
sage: pi=Permutation([2,1,4,3]).to_permutation_group_element() sage: fill=[[2],[1,2,3],[],[3,1]] sage: AugmentedLatticeDiagramFilling(fill).permuted_filling(pi) [[2, 1], [1, 2, 1, 4], [4], [3, 4, 2]] """
def NonattackingFillings(shape, pi=None): """ Returning the combinatorial class of nonattacking fillings of a given shape.
EXAMPLES::
sage: NonattackingFillings([0,1,2]) Nonattacking fillings of [0, 1, 2] sage: NonattackingFillings([0,1,2]).list() [[[1], [2, 1], [3, 2, 1]], [[1], [2, 1], [3, 2, 2]], [[1], [2, 1], [3, 2, 3]], [[1], [2, 1], [3, 3, 1]], [[1], [2, 1], [3, 3, 2]], [[1], [2, 1], [3, 3, 3]], [[1], [2, 2], [3, 1, 1]], [[1], [2, 2], [3, 1, 2]], [[1], [2, 2], [3, 1, 3]], [[1], [2, 2], [3, 3, 1]], [[1], [2, 2], [3, 3, 2]], [[1], [2, 2], [3, 3, 3]]] """
class NonattackingFillings_shape(CombinatorialClass): def __init__(self, shape, pi=None): """ EXAMPLES::
sage: n = NonattackingFillings([0,1,2]) sage: n == loads(dumps(n)) True """
def flip(self): """ Return the nonattacking fillings of the flipped shape.
EXAMPLES::
sage: NonattackingFillings([0,1,2]).flip() Nonattacking fillings of [2, 1, 0] """
def __iter__(self): """ EXAMPLES::
sage: NonattackingFillings([0,1,2]).list() #indirect doctest [[[1], [2, 1], [3, 2, 1]], [[1], [2, 1], [3, 2, 2]], [[1], [2, 1], [3, 2, 3]], [[1], [2, 1], [3, 3, 1]], [[1], [2, 1], [3, 3, 2]], [[1], [2, 1], [3, 3, 3]], [[1], [2, 2], [3, 1, 1]], [[1], [2, 2], [3, 1, 2]], [[1], [2, 2], [3, 1, 3]], [[1], [2, 2], [3, 3, 1]], [[1], [2, 2], [3, 3, 2]], [[1], [2, 2], [3, 3, 3]]] sage: len(_) 12
TESTS::
sage: NonattackingFillings([3,2,1,1]).cardinality() 3 sage: NonattackingFillings([3,2,1,2]).cardinality() 4 sage: NonattackingFillings([1,2,3]).cardinality() 12 sage: NonattackingFillings([2,2,2]).cardinality() 1 sage: NonattackingFillings([1,2,3,2]).cardinality() 24 """
class NonattackingBacktracker(GenericBacktracker): def __init__(self, shape, pi=None): """ EXAMPLES::
sage: from sage.combinat.sf.ns_macdonald import NonattackingBacktracker sage: n = NonattackingBacktracker(LatticeDiagram([0,1,2])) sage: n._ending_position (3, 2) sage: n._initial_state (2, 1) """
#The ending position will be at the highest box #which is farthest right
#Get the lowest box that is farthest left
def _rec(self, obj, state): """ EXAMPLES::
sage: from sage.combinat.sf.ns_macdonald import NonattackingBacktracker sage: n = NonattackingBacktracker(LatticeDiagram([0,1,2])) sage: len(list(n)) 12 sage: obj = [ [], [None], [None, None]] sage: state = 2, 1 sage: list(n._rec(obj, state)) [([[], [1], [None, None]], (3, 1), False), ([[], [2], [None, None]], (3, 1), False)] """ #We need to set the i,j^th entry.
#Get the next state
#We check to make sure that k does not #violate any of the attacking conditions self._shape.boxes_same_and_lower_right(i, j) if jj != 0):
#Fill in the in the i,j box with k+1
#Yield the object
def get_next_pos(self, ii, jj): """ EXAMPLES::
sage: from sage.combinat.sf.ns_macdonald import NonattackingBacktracker sage: a = AugmentedLatticeDiagramFilling([[1,6],[2],[3,4,2],[],[],[5,5]]) sage: n = NonattackingBacktracker(a.shape()) sage: n.get_next_pos(1, 1) (2, 1) sage: n.get_next_pos(6, 1) (1, 2) sage: n = NonattackingBacktracker(LatticeDiagram([2,2,2])) sage: n.get_next_pos(3, 1) (1, 2) """
raise ValueError("we should never be here")
def _check_muqt(mu, q, t, pi=None): """ EXAMPLES::
sage: from sage.combinat.sf.ns_macdonald import _check_muqt sage: P, q, t, n, R, x = _check_muqt([0,0,1],None,None) sage: P Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field sage: q q sage: t t sage: n Nonattacking fillings of [0, 0, 1] sage: R Multivariate Polynomial Ring in x0, x1, x2 over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field sage: x (x0, x1, x2)
::
sage: q,t = var('q,t') sage: P, q, t, n, R, x = _check_muqt([0,0,1],q,None) Traceback (most recent call last): ... ValueError: you must specify either both q and t or neither of them
::
sage: P, q, t, n, R, x = _check_muqt([0,0,1],q,2) Traceback (most recent call last): ... ValueError: the parents of q and t must be the same """ P = q.parent() else:
def E(mu, q=None, t=None, pi=None): """ Returns the non-symmetric Macdonald polynomial in type A corresponding to a shape ``mu``, with basement permuted according to ``pi``.
Note that if both `q` and `t` are specified, then they must have the same parent.
REFERENCE:
- J. Haglund, M. Haiman, N. Loehr. *A combinatorial formula for non-symmetric Macdonald polynomials*. :arXiv:`math/0601693v3`.
.. SEEALSO::
:class:`~sage.combinat.root_system.non_symmetric_macdonald_polynomials.NonSymmetricMacdonaldPolynomials` for a type free implementation where the polynomials are constructed recursively by the application of intertwining operators.
EXAMPLES::
sage: from sage.combinat.sf.ns_macdonald import E sage: E([0,0,0]) 1 sage: E([1,0,0]) x0 sage: E([0,1,0]) ((-t + 1)/(-q*t^2 + 1))*x0 + x1 sage: E([0,0,1]) ((-t + 1)/(-q*t + 1))*x0 + ((-t + 1)/(-q*t + 1))*x1 + x2 sage: E([1,1,0]) x0*x1 sage: E([1,0,1]) ((-t + 1)/(-q*t^2 + 1))*x0*x1 + x0*x2 sage: E([0,1,1]) ((-t + 1)/(-q*t + 1))*x0*x1 + ((-t + 1)/(-q*t + 1))*x0*x2 + x1*x2 sage: E([2,0,0]) x0^2 + ((-q*t + q)/(-q*t + 1))*x0*x1 + ((-q*t + q)/(-q*t + 1))*x0*x2 sage: E([0,2,0]) ((-t + 1)/(-q^2*t^2 + 1))*x0^2 + ((-q^2*t^3 + q^2*t^2 - q*t^2 + 2*q*t - q + t - 1)/(-q^3*t^3 + q^2*t^2 + q*t - 1))*x0*x1 + x1^2 + ((q*t^2 - 2*q*t + q)/(q^3*t^3 - q^2*t^2 - q*t + 1))*x0*x2 + ((-q*t + q)/(-q*t + 1))*x1*x2 """
def E_integral(mu, q=None, t=None, pi=None): """ Returns the integral form for the non-symmetric Macdonald polynomial in type A corresponding to a shape mu.
Note that if both q and t are specified, then they must have the same parent.
REFERENCE:
- J. Haglund, M. Haiman, N. Loehr. *A combinatorial formula for non-symmetric Macdonald polynomials*. :arXiv:`math/0601693v3`.
EXAMPLES::
sage: from sage.combinat.sf.ns_macdonald import E_integral sage: E_integral([0,0,0]) 1 sage: E_integral([1,0,0]) (-t + 1)*x0 sage: E_integral([0,1,0]) (-q*t^2 + 1)*x0 + (-t + 1)*x1 sage: E_integral([0,0,1]) (-q*t + 1)*x0 + (-q*t + 1)*x1 + (-t + 1)*x2 sage: E_integral([1,1,0]) (t^2 - 2*t + 1)*x0*x1 sage: E_integral([1,0,1]) (q*t^3 - q*t^2 - t + 1)*x0*x1 + (t^2 - 2*t + 1)*x0*x2 sage: E_integral([0,1,1]) (q^2*t^3 + q*t^4 - q*t^3 - q*t^2 - q*t - t^2 + t + 1)*x0*x1 + (q*t^2 - q*t - t + 1)*x0*x2 + (t^2 - 2*t + 1)*x1*x2 sage: E_integral([2,0,0]) (t^2 - 2*t + 1)*x0^2 + (q^2*t^2 - q^2*t - q*t + q)*x0*x1 + (q^2*t^2 - q^2*t - q*t + q)*x0*x2 sage: E_integral([0,2,0]) (q^2*t^3 - q^2*t^2 - t + 1)*x0^2 + (q^4*t^3 - q^3*t^2 - q^2*t + q*t^2 - q*t + q - t + 1)*x0*x1 + (t^2 - 2*t + 1)*x1^2 + (q^4*t^3 - q^3*t^2 - q^2*t + q)*x0*x2 + (q^2*t^2 - q^2*t - q*t + q)*x1*x2 """
def Ht(mu, q=None, t=None, pi=None): """ Returns the symmetric Macdonald polynomial using the Haiman, Haglund, and Loehr formula.
Note that if both `q` and `t` are specified, then they must have the same parent.
REFERENCE:
- J. Haglund, M. Haiman, N. Loehr. *A combinatorial formula for non-symmetric Macdonald polynomials*. :arXiv:`math/0601693v3`.
EXAMPLES::
sage: from sage.combinat.sf.ns_macdonald import Ht sage: HHt = SymmetricFunctions(QQ['q','t'].fraction_field()).macdonald().Ht() sage: Ht([0,0,1]) x0 + x1 + x2 sage: HHt([1]).expand(3) x0 + x1 + x2 sage: Ht([0,0,2]) x0^2 + (q + 1)*x0*x1 + x1^2 + (q + 1)*x0*x2 + (q + 1)*x1*x2 + x2^2 sage: HHt([2]).expand(3) x0^2 + (q + 1)*x0*x1 + x1^2 + (q + 1)*x0*x2 + (q + 1)*x1*x2 + x2^2 """ |