def to_skew_partition(self, overlap=1): """ Return the skew partition obtained from ``self``. The parameter overlap indicates the number of cells that are covered by cells of the previous line. EXAMPLES:: sage: Composition([3,4,1]).to_skew_partition() [6, 6, 3] / [5, 2] sage: Composition([3,4,1]).to_skew_partition(overlap=0) [8, 7, 3] / [7, 3] """ from sage.combinat.skew_partition import SkewPartition outer = [] inner = [] sum_outer = -1 * overlap for k in range(len(self) - 1): outer += [self[k] + sum_outer + overlap] sum_outer += self[k] - overlap inner += [sum_outer + overlap] if self != []: outer += [self[-1] + sum_outer + overlap] else: return SkewPartition([[], []]) return SkewPartition([ filter(lambda x: x != 0, [l for l in reversed(outer)]), filter(lambda x: x != 0, [l for l in reversed(inner)]) ])
def spin_polynomial_square(part, weight, length): r""" Returns the spin polynomial associated with ``part``, ``weight``, and ``length``, with the substitution `t \to t^2` made. EXAMPLES:: sage: from sage.combinat.ribbon_tableau import spin_polynomial_square sage: spin_polynomial_square([6,6,6],[4,2],3) t^12 + t^10 + 2*t^8 + t^6 + t^4 sage: spin_polynomial_square([6,6,6],[4,1,1],3) t^12 + 2*t^10 + 3*t^8 + 2*t^6 + t^4 sage: spin_polynomial_square([3,3,3,2,1], [2,2], 3) t^7 + t^5 sage: spin_polynomial_square([3,3,3,2,1], [2,1,1], 3) 2*t^7 + 2*t^5 + t^3 sage: spin_polynomial_square([3,3,3,2,1], [1,1,1,1], 3) 3*t^7 + 5*t^5 + 3*t^3 + t sage: spin_polynomial_square([5,4,3,2,1,1,1], [2,2,1], 3) 2*t^9 + 6*t^7 + 2*t^5 sage: spin_polynomial_square([[6]*6, [3,3]], [4,4,2], 3) 3*t^18 + 5*t^16 + 9*t^14 + 6*t^12 + 3*t^10 """ R = ZZ['t'] if part in _Partitions: part = SkewPartition([part,_Partitions([])]) elif part in SkewPartitions(): part = SkewPartition(part) if part == [[],[]] and weight == []: return R.one() t = R.gen() return R(graph_implementation_rec(part, weight, length, functools.partial(spin_rec,t))[0])
def __classcall_private__(cls, w, factors, excess, shape=False): """ Classcall to mend the input. EXAMPLES:: sage: A = crystals.FullyCommutativeStableGrothendieck([[3, 3], [2, 1]], 4, 1, shape=True); A Fully commutative stable Grothendieck crystal of type A_3 associated to [3, 2, 4] with excess 1 sage: B = crystals.FullyCommutativeStableGrothendieck(SkewPartition([[3, 3], [2, 1]]), 4, 1, shape=True) sage: A is B True sage: C = crystals.FullyCommutativeStableGrothendieck((2, 1), 3, 2, shape=True); C Fully commutative stable Grothendieck crystal of type A_2 associated to [1, 3, 2] with excess 2 sage: D = crystals.FullyCommutativeStableGrothendieck(Partition([2, 1]), 3, 2, shape=True) sage: C is D True """ from sage.monoids.hecke_monoid import HeckeMonoid if shape: from sage.combinat.partition import _Partitions from sage.combinat.skew_partition import SkewPartition cond1 = isinstance(w, (tuple, list)) and len( w) == 2 and w[0] in _Partitions and w[1] in _Partitions cond2 = isinstance(w, SkewPartition) if cond1 or cond2: sh = SkewPartition([w[0], w[1]]) elif w in _Partitions: sh = SkewPartition([w, []]) else: raise ValueError("w needs to be a (skew) partition") word = _to_reduced_word(sh) max_value = max(word) if word else 1 H = HeckeMonoid(SymmetricGroup(max_value + 1)) w = H.from_reduced_word(word) else: if isinstance(w.parent(), SymmetricGroup): H = HeckeMonoid(w.parent()) w = H.from_reduced_word(w.reduced_word()) if (not w.reduced_word()) and excess != 0: raise ValueError("excess must be 0 for the empty word") return super(FullyCommutativeStableGrothendieckCrystal, cls).__classcall__(cls, w, factors, excess)
def __classcall_private__(cls, shape, weight, length): """ Normalize input to ensure a unique representation. EXAMPLES:: sage: R = RibbonTableaux([[2,1],[]],[1,1,1],1) sage: R2 = RibbonTableaux(SkewPartition([[2,1],[]]),(1,1,1),1) sage: R is R2 True """ if shape in _Partitions: shape = _Partitions(shape) shape = SkewPartition([shape, shape.core(length)]) else: shape = SkewPartition(shape) if shape.size() != length*sum(weight): raise ValueError("Incompatible shape and weight") return super(RibbonTableaux, cls).__classcall__(cls, shape, tuple(weight), length)
def __classcall_private__(cls, shape, weight): """ Normalize input to ensure a unique representation. EXAMPLES:: sage: S1 = SemistandardMultiSkewTableaux([ [[2,1],[]], [[2,2],[1]] ], [2,2,2]) sage: shape_alt = ( SkewPartition([[2,1],[]]), SkewPartition([[2,2],[1]]) ) sage: S2 = SemistandardMultiSkewTableaux(shape_alt, (2,2,2)) sage: S1 is S2 True """ shape = tuple(SkewPartition(x) for x in shape) weight = Partition(weight) if sum(weight) != sum(s.size() for s in shape): raise ValueError("the sum of weight must be the sum of the sizes of shape") return super(SemistandardMultiSkewTableaux, cls).__classcall__(cls, shape, weight)
def __classcall_private__(cls, shape, weight, length): """ Normalize input to ensure a unique representation. EXAMPLES:: sage: R = RibbonTableaux([[2,1],[]],[1,1,1],1) sage: R2 = RibbonTableaux(SkewPartition([[2,1],[]]),(1,1,1),1) sage: R is R2 True """ if shape in _Partitions: shape = _Partitions(shape) shape = SkewPartition([shape, shape.core(length)]) else: shape = SkewPartition(shape) if shape.size() != length*sum(weight): raise ValueError("Incompatible shape and weight") return super(RibbonTableaux, cls).__classcall__(cls, shape, tuple(weight), length)
def insertion_tableau(skp, perm, evaluation, tableau, length): """ INPUT: - ``skp`` -- skew partitions - ``perm, evaluation`` -- non-negative integers - ``tableau`` -- skew tableau - ``length`` -- integer TESTS:: sage: from sage.combinat.ribbon_tableau import insertion_tableau sage: insertion_tableau([[1], []], [1], 1, [[], []], 1) [[], [[1]]] sage: insertion_tableau([[2, 1], []], [1, 1], 2, [[], [[1]]], 1) [[], [[2], [1, 2]]] sage: insertion_tableau([[2, 1], []], [0, 0], 3, [[], [[2], [1, 2]]], 1) [[], [[2], [1, 2]]] sage: insertion_tableau([[1, 1], []], [1], 2, [[], [[1]]], 1) [[], [[2], [1]]] sage: insertion_tableau([[2], []], [0, 1], 2, [[], [[1]]], 1) [[], [[1, 2]]] sage: insertion_tableau([[2, 1], []], [0, 1], 3, [[], [[2], [1]]], 1) [[], [[2], [1, 3]]] sage: insertion_tableau([[1, 1], []], [2], 1, [[], []], 2) [[], [[1], [0]]] sage: insertion_tableau([[2], []], [2, 0], 1, [[], []], 2) [[], [[1, 0]]] sage: insertion_tableau([[2, 2], []], [0, 2], 2, [[], [[1], [0]]], 2) [[], [[1, 2], [0, 0]]] sage: insertion_tableau([[2, 2], []], [2, 0], 2, [[], [[1, 0]]], 2) [[], [[2, 0], [1, 0]]] sage: insertion_tableau([[2, 2], [1]], [3, 0], 1, [[], []], 3) [[1], [[1, 0], [0]]] """ psave = Partition(skp[1]) partc = skp[1] + [0] * (len(skp[0]) - len(skp[1])) tableau = SkewTableau(expr=tableau).to_expr()[1] for k in range(len(tableau)): tableau[-(k + 1)] += [0] * (skp[0][k] - partc[k] - len(tableau[-(k + 1)])) ## We construct a tableau from the southwest corner to the northeast one tableau = [[0] * (skp[0][k] - partc[k]) for k in reversed(range(len(tableau), len(skp[0])))] + tableau tableau = SkewTableaux().from_expr([skp[1], tableau]).conjugate() tableau = tableau.to_expr()[1] skp = SkewPartition(skp).conjugate().to_list() skp[1].extend([0] * (len(skp[0]) - len(skp[1]))) if len(perm) > len(skp[0]): return None for k in range(len(perm)): if perm[-(k + 1)] != 0: tableau[len(tableau) - len(perm) + k][skp[0][len(perm) - (k + 1)] - skp[1][len(perm) - (k + 1)] - 1] = evaluation return SkewTableau(expr=[psave.conjugate(), tableau]).conjugate().to_expr()