def epsilon_ik(itab, ktab, star=0): """ EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import epsilon_ik sage: epsilon_ik([[1,2],[3]], [[1,3],[2]]) 1/4*[1, 3, 2] - 1/4*[2, 3, 1] + 1/4*[3, 1, 2] - 1/4*[3, 2, 1] sage: epsilon_ik([[1,2],[3]], [[1,3],[2]], star=1) Traceback (most recent call last): ... ValueError: the two tableaux must be of the same shape """ it = Tableau(itab) kt = Tableau(ktab) if star: it = it.restrict(it.size() - star) kt = kt.restrict(kt.size() - star) if it.shape() != kt.shape(): raise ValueError, "the two tableaux must be of the same shape" mult = permutation_options['mult'] permutation_options['mult'] = 'l2r' if kt == it: res = epsilon(itab) elif (it, kt) in epsilon_ik_cache: res = epsilon_ik_cache[(it,kt)] else: epsilon_ik_cache[(it,kt)] = epsilon(it, star+1)*e_ik(it,kt,star)*epsilon(kt, star+1) * (1/kappa(it.shape())) res = epsilon_ik_cache[(it,kt)] permutation_options['mult'] = mult return res
def e_ik(itab, ktab, star=0): """ EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import e_ik sage: e_ik([[1,2,3]], [[1,2,3]]) [1, 2, 3] + [1, 3, 2] + [2, 1, 3] + [2, 3, 1] + [3, 1, 2] + [3, 2, 1] sage: e_ik([[1,2,3]], [[1,2,3]], star=1) [1, 2] + [2, 1] """ it = Tableau(itab) kt = Tableau(ktab) if star: it = it.restrict(it.size() - star) kt = kt.restrict(kt.size() - star) if it.shape() != kt.shape(): raise ValueError, "the two tableaux must be of the same shape" mult = permutation_options['mult'] permutation_options['mult'] = 'l2r' if kt == it: res = e(it) elif (it, kt) in e_ik_cache: res = e_ik_cache[(it,kt)] else: pi = pi_ik(it,kt) e_ik_cache[(it,kt)] = e(it)*pi res = e_ik_cache[(it,kt)] permutation_options['mult'] = mult return res
def e_hat(tab, star=0): """ The Young projection operator, an idempotent in the rational group algebra. EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import e_hat sage: e_hat([[1,2,3]]) 1/6*[1, 2, 3] + 1/6*[1, 3, 2] + 1/6*[2, 1, 3] + 1/6*[2, 3, 1] + 1/6*[3, 1, 2] + 1/6*[3, 2, 1] sage: e_hat([[1],[2]]) 1/2*[1, 2] - 1/2*[2, 1] There are differing conventions for the order of the symmetrizers and antisymmetrizers. This example illustrates our conventions:: sage: e_hat([[1,2],[3]]) 1/3*[1, 2, 3] + 1/3*[2, 1, 3] - 1/3*[3, 1, 2] - 1/3*[3, 2, 1] """ t = Tableau(tab) if star: t = t.restrict(t.size()-star) if t in ehat_cache: res = ehat_cache[t] else: res = (1/kappa(t.shape()))*e(t) return res
def epsilon(tab, star=0): """ EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import epsilon sage: epsilon([[1,2]]) 1/2*[1, 2] + 1/2*[2, 1] sage: epsilon([[1],[2]]) 1/2*[1, 2] - 1/2*[2, 1] """ t = Tableau(tab) if star: t = t.restrict(t.size() - star) mult = permutation_options['mult'] permutation_options['mult'] = 'l2r' if t in epsilon_cache: res = epsilon_cache[t] else: if t.size() == 2: epsilon_cache[t] = e(t)*(1/kappa(t.shape())) res = epsilon_cache[t] elif t == Tableau([[1]]): epsilon_cache[t] = e(t) res = epsilon_cache[t] else: epsilon_cache[t] = epsilon(t, 1)*e(t)*epsilon(t,1)*( 1 / kappa(t.shape())) res = epsilon_cache[t] permutation_options['mult'] = mult return res
def e_hat(tab, star=0): """ The Young projection operator corresponding to the Young tableau ``tab`` (which is supposed to contain every integer from `1` to its size precisely once, but may and may not be standard). This is an idempotent in the rational group algebra. EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import e_hat sage: e_hat([[1,2,3]]) 1/6*[1, 2, 3] + 1/6*[1, 3, 2] + 1/6*[2, 1, 3] + 1/6*[2, 3, 1] + 1/6*[3, 1, 2] + 1/6*[3, 2, 1] sage: e_hat([[1],[2]]) 1/2*[1, 2] - 1/2*[2, 1] There are differing conventions for the order of the symmetrizers and antisymmetrizers. This example illustrates our conventions:: sage: e_hat([[1,2],[3]]) 1/3*[1, 2, 3] + 1/3*[2, 1, 3] - 1/3*[3, 1, 2] - 1/3*[3, 2, 1] """ t = Tableau(tab) if star: t = t.restrict(t.size() - star) if t in ehat_cache: res = ehat_cache[t] else: res = (1 / kappa(t.shape())) * e(t) return res
def b(tableau, star=0): r""" The column projection operator corresponding to the Young tableau ``tableau`` (which is supposed to contain every integer from `1` to its size precisely once, but may and may not be standard). This is the signed sum (in the group algebra of the relevant symmetric group over `\QQ`) of all the permutations which preserve the column of ``tableau`` (where the signs are the usual signs of the permutations). It is called `b_{\text{tableau}}` in [EtRT]_, Section 4.2. EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import b sage: b([[1,2]]) [1, 2] sage: b([[1],[2]]) [1, 2] - [2, 1] sage: b([]) [] sage: b([[1, 2, 4], [5, 3]]) [1, 2, 3, 4, 5] - [1, 3, 2, 4, 5] - [5, 2, 3, 4, 1] + [5, 3, 2, 4, 1] With the `l2r` setting for multiplication, the unnormalized Young symmetrizer ``e(tableau)`` should be the product ``b(tableau) * a(tableau)`` for every ``tableau``. Let us check this on the standard tableaux of size 5:: sage: from sage.combinat.symmetric_group_algebra import a, b, e sage: all( e(t) == b(t) * a(t) for t in StandardTableaux(5) ) True """ t = Tableau(tableau) if star: t = t.restrict(t.size() - star) cs = t.column_stabilizer().list() n = t.size() # This all should be over ZZ, not over QQ, but symmetric group # algebras don't seem to preserve coercion (the one over ZZ # doesn't coerce into the one over QQ even for the same n), # and the QQ version of this method is more important, so let # me stay with QQ. # TODO: Fix this. sgalg = SymmetricGroupAlgebra(QQ, n) one = QQ.one() P = permutation.Permutation # Ugly hack for the case of an empty tableau, due to the # annoyance of Permutation(Tableau([]).row_stabilizer()[0]) # being [1] rather than [] (which seems to have its origins in # permutation group code). # TODO: Fix this. if len(tableau) == 0: return sgalg.one() cd = dict((P(v), v.sign() * one) for v in cs) return sgalg._from_dict(cd)
def e_hat(tab, star=0): """ The Young projection operator corresponding to the Young tableau ``tab`` (which is supposed to contain every integer from `1` to its size precisely once, but may and may not be standard). This is an idempotent in the rational group algebra. EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import e_hat sage: e_hat([[1,2,3]]) 1/6*[1, 2, 3] + 1/6*[1, 3, 2] + 1/6*[2, 1, 3] + 1/6*[2, 3, 1] + 1/6*[3, 1, 2] + 1/6*[3, 2, 1] sage: e_hat([[1],[2]]) 1/2*[1, 2] - 1/2*[2, 1] There are differing conventions for the order of the symmetrizers and antisymmetrizers. This example illustrates our conventions:: sage: e_hat([[1,2],[3]]) 1/3*[1, 2, 3] + 1/3*[2, 1, 3] - 1/3*[3, 1, 2] - 1/3*[3, 2, 1] """ t = Tableau(tab) if star: t = t.restrict(t.size()-star) if t in ehat_cache: res = ehat_cache[t] else: res = (1/kappa(t.shape()))*e(t) return res
def b(tableau, star=0): r""" The column projection operator corresponding to the Young tableau ``tableau`` (which is supposed to contain every integer from `1` to its size precisely once, but may and may not be standard). This is the signed sum (in the group algebra of the relevant symmetric group over `\QQ`) of all the permutations which preserve the column of ``tableau`` (where the signs are the usual signs of the permutations). It is called `b_{\text{tableau}}` in [EtRT]_, Section 4.2. EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import b sage: b([[1,2]]) [1, 2] sage: b([[1],[2]]) [1, 2] - [2, 1] sage: b([]) [] sage: b([[1, 2, 4], [5, 3]]) [1, 2, 3, 4, 5] - [1, 3, 2, 4, 5] - [5, 2, 3, 4, 1] + [5, 3, 2, 4, 1] With the `l2r` setting for multiplication, the unnormalized Young symmetrizer ``e(tableau)`` should be the product ``b(tableau) * a(tableau)`` for every ``tableau``. Let us check this on the standard tableaux of size 5:: sage: from sage.combinat.symmetric_group_algebra import a, b, e sage: all( e(t) == b(t) * a(t) for t in StandardTableaux(5) ) True """ t = Tableau(tableau) if star: t = t.restrict(t.size()-star) cs = t.column_stabilizer().list() n = t.size() # This all should be over ZZ, not over QQ, but symmetric group # algebras don't seem to preserve coercion (the one over ZZ # doesn't coerce into the one over QQ even for the same n), # and the QQ version of this method is more important, so let # me stay with QQ. # TODO: Fix this. sgalg = SymmetricGroupAlgebra(QQ, n) one = QQ.one() P = permutation.Permutation # Ugly hack for the case of an empty tableau, due to the # annoyance of Permutation(Tableau([]).row_stabilizer()[0]) # being [1] rather than [] (which seems to have its origins in # permutation group code). # TODO: Fix this. if len(tableau) == 0: return sgalg.one() cd = dict((P(v), v.sign()*one) for v in cs) return sgalg._from_dict(cd)
def a(tableau, star=0): r""" The row projection operator corresponding to the Young tableau ``tableau`` (which is supposed to contain every integer from `1` to its size precisely once, but may and may not be standard). This is the sum (in the group algebra of the relevant symmetric group over `\QQ`) of all the permutations which preserve the rows of ``tableau``. It is called `a_{\text{tableau}}` in [EtRT]_, Section 4.2. REFERENCES: .. [EtRT] Pavel Etingof, Oleg Golberg, Sebastian Hensel, Tiankai Liu, Alex Schwendner, Dmitry Vaintrob, Elena Yudovina, "Introduction to representation theory", :arXiv:`0901.0827v5`. EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import a sage: a([[1,2]]) [1, 2] + [2, 1] sage: a([[1],[2]]) [1, 2] sage: a([]) [] sage: a([[1, 5], [2, 3], [4]]) [1, 2, 3, 4, 5] + [1, 3, 2, 4, 5] + [5, 2, 3, 4, 1] + [5, 3, 2, 4, 1] """ t = Tableau(tableau) if star: t = t.restrict(t.size() - star) rs = t.row_stabilizer().list() n = t.size() # This all should be over ZZ, not over QQ, but symmetric group # algebras don't seem to preserve coercion (the one over ZZ # doesn't coerce into the one over QQ even for the same n), # and the QQ version of this method is more important, so let # me stay with QQ. # TODO: Fix this. sgalg = SymmetricGroupAlgebra(QQ, n) one = QQ.one() P = permutation.Permutation # Ugly hack for the case of an empty tableau, due to the # annoyance of Permutation(Tableau([]).row_stabilizer()[0]) # being [1] rather than [] (which seems to have its origins in # permutation group code). # TODO: Fix this. if len(tableau) == 0: return sgalg.one() rd = dict((P(h), one) for h in rs) return sgalg._from_dict(rd)
def a(tableau, star=0): r""" The row projection operator corresponding to the Young tableau ``tableau`` (which is supposed to contain every integer from `1` to its size precisely once, but may and may not be standard). This is the sum (in the group algebra of the relevant symmetric group over `\QQ`) of all the permutations which preserve the rows of ``tableau``. It is called `a_{\text{tableau}}` in [EtRT]_, Section 4.2. REFERENCES: .. [EtRT] Pavel Etingof, Oleg Golberg, Sebastian Hensel, Tiankai Liu, Alex Schwendner, Dmitry Vaintrob, Elena Yudovina, "Introduction to representation theory", :arXiv:`0901.0827v5`. EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import a sage: a([[1,2]]) [1, 2] + [2, 1] sage: a([[1],[2]]) [1, 2] sage: a([]) [] sage: a([[1, 5], [2, 3], [4]]) [1, 2, 3, 4, 5] + [1, 3, 2, 4, 5] + [5, 2, 3, 4, 1] + [5, 3, 2, 4, 1] """ t = Tableau(tableau) if star: t = t.restrict(t.size()-star) rs = t.row_stabilizer().list() n = t.size() # This all should be over ZZ, not over QQ, but symmetric group # algebras don't seem to preserve coercion (the one over ZZ # doesn't coerce into the one over QQ even for the same n), # and the QQ version of this method is more important, so let # me stay with QQ. # TODO: Fix this. sgalg = SymmetricGroupAlgebra(QQ, n) one = QQ.one() P = permutation.Permutation # Ugly hack for the case of an empty tableau, due to the # annoyance of Permutation(Tableau([]).row_stabilizer()[0]) # being [1] rather than [] (which seems to have its origins in # permutation group code). # TODO: Fix this. if len(tableau) == 0: return sgalg.one() rd = dict((P(h), one) for h in rs) return sgalg._from_dict(rd)
def e(tableau, star=0): """ The unnormalized Young projection operator. EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import e sage: e([[1,2]]) [1, 2] + [2, 1] sage: e([[1],[2]]) [1, 2] - [2, 1] There are differing conventions for the order of the symmetrizers and antisymmetrizers. This example illustrates our conventions:: sage: e([[1,2],[3]]) [1, 2, 3] + [2, 1, 3] - [3, 1, 2] - [3, 2, 1] """ t = Tableau(tableau) if star: t = t.restrict(t.size()-star) mult = permutation_options['mult'] permutation_options['mult'] = 'l2r' if t in e_cache: res = e_cache[t] else: rs = t.row_stabilizer().list() cs = t.column_stabilizer().list() n = t.size() QSn = SymmetricGroupAlgebra(QQ, n) one = QQ(1) P = permutation.Permutation rd = dict((P(h), one) for h in rs) sym = QSn._from_dict(rd) cd = dict((P(v), v.sign()*one) for v in cs) antisym = QSn._from_dict(cd) res = antisym*sym e_cache[t] = res permutation_options['mult'] = mult return res
def e(tableau, star=0): """ The unnormalized Young projection operator corresponding to the Young tableau ``tableau`` (which is supposed to contain every integer from `1` to its size precisely once, but may and may not be standard). EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import e sage: e([[1,2]]) [1, 2] + [2, 1] sage: e([[1],[2]]) [1, 2] - [2, 1] sage: e([]) [] There are differing conventions for the order of the symmetrizers and antisymmetrizers. This example illustrates our conventions:: sage: e([[1,2],[3]]) [1, 2, 3] + [2, 1, 3] - [3, 1, 2] - [3, 2, 1] """ t = Tableau(tableau) if star: t = t.restrict(t.size() - star) mult = permutation_options['mult'] permutation_options['mult'] = 'l2r' if t in e_cache: res = e_cache[t] else: rs = t.row_stabilizer().list() cs = t.column_stabilizer().list() n = t.size() QSn = SymmetricGroupAlgebra(QQ, n) one = QQ.one() P = permutation.Permutation rd = dict((P(h), one) for h in rs) sym = QSn._from_dict(rd) cd = dict((P(v), v.sign() * one) for v in cs) antisym = QSn._from_dict(cd) res = antisym * sym # Ugly hack for the case of an empty tableau, due to the # annoyance of Permutation(Tableau([]).row_stabilizer()[0]) # being [1] rather than [] (which seems to have its origins in # permutation group code). # TODO: Fix this. if len(tableau) == 0: res = QSn.one() e_cache[t] = res permutation_options['mult'] = mult return res
def e(tableau, star=0): """ The unnormalized Young projection operator corresponding to the Young tableau ``tableau`` (which is supposed to contain every integer from `1` to its size precisely once, but may and may not be standard). EXAMPLES:: sage: from sage.combinat.symmetric_group_algebra import e sage: e([[1,2]]) [1, 2] + [2, 1] sage: e([[1],[2]]) [1, 2] - [2, 1] sage: e([]) [] There are differing conventions for the order of the symmetrizers and antisymmetrizers. This example illustrates our conventions:: sage: e([[1,2],[3]]) [1, 2, 3] + [2, 1, 3] - [3, 1, 2] - [3, 2, 1] """ t = Tableau(tableau) if star: t = t.restrict(t.size()-star) mult = permutation_options['mult'] permutation_options['mult'] = 'l2r' if t in e_cache: res = e_cache[t] else: rs = t.row_stabilizer().list() cs = t.column_stabilizer().list() n = t.size() QSn = SymmetricGroupAlgebra(QQ, n) one = QQ.one() P = permutation.Permutation rd = dict((P(h), one) for h in rs) sym = QSn._from_dict(rd) cd = dict((P(v), v.sign()*one) for v in cs) antisym = QSn._from_dict(cd) res = antisym*sym # Ugly hack for the case of an empty tableau, due to the # annoyance of Permutation(Tableau([]).row_stabilizer()[0]) # being [1] rather than [] (which seems to have its origins in # permutation group code). # TODO: Fix this. if len(tableau) == 0: res = QSn.one() e_cache[t] = res permutation_options['mult'] = mult return res