def __init__(self, p, n): """ TESTS:: sage: from yacop.modules.dickson import PetersonPolynomials sage: P=PetersonPolynomials(3,2) ; P Peterson element factory for prime 3, index 2 sage: for idx in range(20): ....: print("%-3d : %s" % (idx,P.omega(idx))) 0 : 1 1 : x1^2 + x2^2 2 : x1^4 + x1^2*x2^2 + x2^4 3 : x1^6 + x1^4*x2^2 + x1^2*x2^4 + x2^6 4 : x1^6*x2^2 + x1^4*x2^4 + x1^2*x2^6 5 : -x1^10 + x1^6*x2^4 + x1^4*x2^6 - x2^10 6 : x1^12 - x1^10*x2^2 + x1^6*x2^6 - x1^2*x2^10 + x2^12 7 : x1^12*x2^2 - x1^10*x2^4 - x1^4*x2^10 + x1^2*x2^12 8 : x1^12*x2^4 - x1^10*x2^6 - x1^6*x2^10 + x1^4*x2^12 9 : x1^18 + x1^12*x2^6 + x1^6*x2^12 + x2^18 10 : x1^18*x2^2 + x1^10*x2^10 + x1^2*x2^18 11 : x1^18*x2^4 - x1^12*x2^10 - x1^10*x2^12 + x1^4*x2^18 12 : x1^18*x2^6 + x1^12*x2^12 + x1^6*x2^18 13 : 0 14 : x1^28 - x1^18*x2^10 - x1^10*x2^18 + x2^28 15 : -x1^30 + x1^28*x2^2 + x1^18*x2^12 + x1^12*x2^18 + x1^2*x2^28 - x2^30 16 : -x1^30*x2^2 + x1^28*x2^4 + x1^4*x2^28 - x1^2*x2^30 17 : -x1^30*x2^4 + x1^28*x2^6 + x1^6*x2^28 - x1^4*x2^30 18 : x1^36 - x1^30*x2^6 + x1^18*x2^18 - x1^6*x2^30 + x2^36 19 : x1^36*x2^2 - x1^28*x2^10 - x1^10*x2^28 + x1^2*x2^36 """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from yacop.modules.classifying_spaces import BZpGeneric from sage.categories.tensor import tensor self.p = p self.n = n self.B = BZpGeneric(p) factors = tuple([ self.B, ] * n) self.BT = tensor(factors) self.tc = self.BT.tensor_constructor(factors) deg = -1 fac = 2 # if p>2 else 1 self.b = self.B.monomial(fac * deg) self.binv = self.B.monomial(-fac * deg) self.bt = tensor([ self.b, ] * n) self.bti = tensor([ self.binv, ] * n) self.P = SteenrodAlgebra(p, generic=True).P self.Q = PolynomialRing( GF(p), ["x%d" % (i + 1) for i in range(n)] + [ "t", ], )
def coproduct_by_coercion(self, elt): r""" Returns the coproduct of the element ``elt`` by coercion to the Schur basis. INPUT: - ``elt`` -- an instance of the ``Qp`` basis OUTPUT: - The coproduct acting on ``elt``, the result is an element of the tensor squared of the ``Qp`` symmetric function basis EXAMPLES:: sage: Sym = SymmetricFunctions(QQ['t'].fraction_field()) sage: JQp = Sym.jack().Qp() sage: JQp[2,2].coproduct() #indirect doctest JackQp[] # JackQp[2, 2] + (2*t/(t+1))*JackQp[1] # JackQp[2, 1] + JackQp[1, 1] # JackQp[1, 1] + ((4*t^3+8*t^2)/(2*t^3+5*t^2+4*t+1))*JackQp[2] # JackQp[2] + (2*t/(t+1))*JackQp[2, 1] # JackQp[1] + JackQp[2, 2] # JackQp[] """ h = elt.parent().realization_of().h() parent = elt.parent() from sage.categories.tensor import tensor cfunc = lambda x, y: tensor([parent(x), parent(y)]) cprod = h(elt).coproduct().apply_multilinear_morphism(cfunc) normalize = lambda c: normalize_coefficients(parent, c) return cprod.parent().sum(normalize(coeff) * tensor([parent(x), parent(y)]) for ((x, y), coeff) in cprod)
def coproduct_by_coercion(self, elt): r""" Returns the coproduct of the element ``elt`` by coercion to the Schur basis. INPUT: - ``self`` -- a Jack symmetric function basis - ``elt`` -- an instance of this basis OUTPUT: - The coproduct acting on ``elt``, the result is an element of the tensor squared of the Jack symmetric function basis EXAMPLES:: sage: Sym = SymmetricFunctions(QQ['t'].fraction_field()) sage: Sym.jack().P()[2,2].coproduct() #indirect doctest JackP[] # JackP[2, 2] + (2/(t+1))*JackP[1] # JackP[2, 1] + ((8*t+4)/(t^3+4*t^2+5*t+2))*JackP[1, 1] # JackP[1, 1] + JackP[2] # JackP[2] + (2/(t+1))*JackP[2, 1] # JackP[1] + JackP[2, 2] # JackP[] """ from sage.categories.tensor import tensor s = self.realization_of().schur() g = self.tensor_square().sum(coeff * tensor([self(s[x]), self(s[y])]) for ((x, y), coeff) in s(elt).coproduct()) normalize = self._normalize_coefficients return self.tensor_square().sum(normalize(coeff) * tensor([self(x), self(y)]) for ((x, y), coeff) in g)
def coproduct_by_coercion(self, x): r""" Returns the coproduct by coercion if coproduct_by_basis is not implemented. EXAMPLES:: sage: Sym = SymmetricFunctions(QQ) sage: m = Sym.monomial() sage: f = m[2,1] sage: f.coproduct.__module__ 'sage.categories.coalgebras' sage: m.coproduct_on_basis NotImplemented sage: m.coproduct == m.coproduct_by_coercion True sage: f.coproduct() m[] # m[2, 1] + m[1] # m[2] + m[2] # m[1] + m[2, 1] # m[] :: sage: N = NonCommutativeSymmetricFunctions(QQ) sage: R = N.ribbon() sage: R.coproduct_by_coercion.__module__ 'sage.categories.coalgebras' sage: R.coproduct_on_basis NotImplemented sage: R.coproduct == R.coproduct_by_coercion True sage: R[1].coproduct() R[] # R[1] + R[1] # R[] """ from sage.categories.tensor import tensor R = self.realization_of().a_realization() return self.tensor_square().sum(coeff * tensor([self(R[I]), self(R[J])]) for ((I, J), coeff) in R(x).coproduct())
def product_on_basis(self, t1, t2): """ The product of the algebra on the basis, as per ``AlgebrasWithBasis.ParentMethods.product_on_basis``. EXAMPLES:: sage: A = AlgebrasWithBasis(QQ).example(); A An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field sage: (a,b,c) = A.algebra_generators() sage: x = tensor( (a, b, c) ); x B[word: a] # B[word: b] # B[word: c] sage: y = tensor( (c, b, a) ); y B[word: c] # B[word: b] # B[word: a] sage: x*y B[word: ac] # B[word: bb] # B[word: ca] sage: x = tensor( ((a+2*b), c) ) ; x B[word: a] # B[word: c] + 2*B[word: b] # B[word: c] sage: y = tensor( (c, a) ) + 1; y B[word: ] # B[word: ] + B[word: c] # B[word: a] sage: x*y B[word: a] # B[word: c] + B[word: ac] # B[word: ca] + 2*B[word: b] # B[word: c] + 2*B[word: bc] # B[word: ca] TODO: optimize this implementation! """ return tensor( (module.monomial(x1)*module.monomial(x2) for (module, x1, x2) in zip(self._sets, t1, t2)) ) #.
def coproduct(self): r""" Returns the coproduct operation on ``self``. The coproduct is first computed on the homogeneous basis if `t=1` and on the Hall-Littlewood ``Qp`` basis otherwise. The result is computed then converted to the tensor squared of ``self.parent()`` EXAMPLES:: sage: Sym = SymmetricFunctions(QQ) sage: ks3 = Sym.kschur(3,1) sage: ks3[2,1].coproduct() ks3[] # ks3[2, 1] + ks3[1] # ks3[1, 1] + ks3[1] # ks3[2] + ks3[1, 1] # ks3[1] + ks3[2] # ks3[1] + ks3[2, 1] # ks3[] sage: h3 = Sym.khomogeneous(3) sage: h3[2,1].coproduct() h3[] # h3[2, 1] + h3[1] # h3[1, 1] + h3[1] # h3[2] + h3[1, 1] # h3[1] + h3[2] # h3[1] + h3[2, 1] # h3[] sage: ks3t = SymmetricFunctions(FractionField(QQ['t'])).kschur(3) sage: ks3t[2,1].coproduct() ks3[] # ks3[2, 1] + ks3[1] # ks3[1, 1] + ks3[1] # ks3[2] + ks3[1, 1] # ks3[1] + ks3[2] # ks3[1] + ks3[2, 1] # ks3[] sage: ks3t[3,1].coproduct() ks3[] # ks3[3, 1] + ks3[1] # ks3[2, 1] + (t+1)*ks3[1] # ks3[3] + ks3[1, 1] # ks3[2] + ks3[2] # ks3[1, 1] + (t+1)*ks3[2] # ks3[2] + ks3[2, 1] # ks3[1] + (t+1)*ks3[3] # ks3[1] + ks3[3, 1] # ks3[] """ lifted = self.lift() target_basis = self.parent() ambient = self.parent().realization_of().ambient() t = self.parent().realization_of().t if t==1: source_basis = ambient.h() else: source_basis = ambient.hall_littlewood(t=t).Qp() cpfunc = lambda x,y: tensor([ target_basis(x), target_basis(y) ]) return source_basis(lifted).coproduct().apply_multilinear_morphism( cpfunc )
def coproduct_on_basis(self, g): r""" Return the coproduct of the element ``g`` of the basis. Each basis element ``g`` is group-like. This method is used to compute the coproduct of any element. EXAMPLES:: sage: PF = NonDecreasingParkingFunctions(4) sage: A = PF.algebra(ZZ); A Algebra of Non-decreasing parking functions of size 4 over Integer Ring sage: g = PF.an_element(); g [1, 1, 1, 1] sage: A.coproduct_on_basis(g) B[[1, 1, 1, 1]] # B[[1, 1, 1, 1]] sage: a = A.an_element(); a 2*B[[1, 1, 1, 1]] + 2*B[[1, 1, 1, 2]] + 3*B[[1, 1, 1, 3]] sage: a.coproduct() 2*B[[1, 1, 1, 1]] # B[[1, 1, 1, 1]] + 2*B[[1, 1, 1, 2]] # B[[1, 1, 1, 2]] + 3*B[[1, 1, 1, 3]] # B[[1, 1, 1, 3]] """ from sage.categories.tensor import tensor g = self.term(g) return tensor([g, g])
def SuspendedObjectsFactory(module, *args, **kwopts): from sage.categories.tensor import tensor l = len(module._sets) last = module._sets[l - 1] newsets = list(module._sets[:l - 1]) + [ suspension(last, *args, **kwopts), ] return tensor(tuple(newsets))
def E_mu(mu, use_antisymmetry=True, row_symmetry="permutation", parallel=False, r=0): """ Given a diagram `mu`, compute the character associated to this diagram. Compute the subspace span by the Vandermonde determinant associated to `mu` and closed by partial derivatives and polarization, and return its bicaracter. If `use_antisymmetry` is `True`, use the optimisation on antisymmetries, and if `row_symmetry` is "permutation", use the optimisation on row permutation. INPUT: - ``mu`` -- a Partition or a Diagram - ``use_antisymmetry`` -- a boolean - ``row_symmetry`` -- only implemented case "permutation" EXAMPLES:: sage: E_mu(Partition([2,1,1])) s[] # s[2, 1, 1] + s[1] # s[1, 1, 1, 1] sage: for mu in Partitions(3): ....: print(E_mu(mu)) s[] # s[3] + s[1] # s[2, 1] + s[1, 1] # s[1, 1, 1] + s[2] # s[2, 1] + s[3] # s[1, 1, 1] s[] # s[2, 1] + s[1] # s[1, 1, 1] s[] # s[1, 1, 1] """ n = Integer(mu.size()) # Determinant computation v = vandermonde(mu) # Span by derivatives generator = {v.multidegree(): [v]} list_op = partial_derivatives(v.parent()) V = Subspace(generators=generator, operators=list_op, add_degrees=add_degree) # Projection on isotypic components V_iso = IsotypicComponent(V, n, use_antisymmetry=use_antisymmetry) # Polarization if r == 0: r = max(n - 1, 1) deg = v.degree() if deg == 0: deg = 1 op_pol = polarization_operators(r, deg, row_symmetry=row_symmetry) if parallel: charac = 0 for (((_, _), _), V_pol) in parallel_character([ (subspace, op_pol) for subspace in V_iso.values() ]): for key, coeff in V_pol.iteritems(): charac += coeff * tensor([s(key[0]), s(key[1])]) return charac else: V_pol = PolarizedSpace(V_iso, op_pol) # character return character(V_pol, row_symmetry=row_symmetry)
def coproduct(self, elt): r""" Return the coproduct of the element ``elt``. INPUT: - ``elt`` -- a symmetric function written in this basis OUTPUT: - The coproduct acting on ``elt``; the result is an element of the tensor squared of the basis ``self`` EXAMPLES:: sage: w = SymmetricFunctions(QQ).w() sage: w[2].coproduct() w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w.coproduct(w[2]) w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w[2,1].coproduct() w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] sage: w.coproduct(w[2,1]) w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] TESTS: The same, but with other settings:: sage: w = SymmetricFunctions(QQ).w(coerce_h=False, coerce_e=True) sage: w[2].coproduct() w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w.coproduct(w[2]) w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w[2,1].coproduct() w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] sage: w.coproduct(w[2,1]) w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] sage: w = SymmetricFunctions(QQ).w(coerce_h=False, coerce_p=True) sage: w[2].coproduct() w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w.coproduct(w[2]) w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w[2,1].coproduct() w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] sage: w.coproduct(w[2,1]) w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] """ from sage.categories.tensor import tensor friendly = self._friendly return self.tensor_square().sum( coeff * tensor([self(friendly[x]), self(friendly[y])]) for ((x, y), coeff) in friendly(elt).coproduct())
def tensor_square(self): """ Returns the tensor square of ``self`` EXAMPLES:: sage: A = HopfAlgebrasWithBasis(QQ).example() sage: A.tensor_square() An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field # An example of Hopf algebra with basis: the group algebra of the Dihedral group of order 6 as a permutation group over Rational Field """ return tensor([self, self])
def antipode_on_basis(self, index): r""" The antipode on the basis element indexed by ``index``. INPUT: - ``index`` -- an element of the index set For a filtered connected Hopf algebra, we can define an antipode recursively by .. MATH:: S(x) := -\sum_{x^L \neq x} S(x^L) \times x^R + \epsilon(x) for all `x`, using the Sweedler notation. Also, `S(x) = x` for all `x` with `|x| = 0`. TESTS:: sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: H.monomial(0).antipode() # indirect doctest P0 sage: H.monomial(1).antipode() # indirect doctest -P1 sage: H.monomial(2).antipode() # indirect doctest P2 sage: H.monomial(3).antipode() # indirect doctest -P3 """ if self.monomial(index) == self.one(): return self.one() S = self.antipode_on_basis x__S_Id = tensor([self, self]).module_morphism( lambda ab: S(ab[0]) * self.monomial(ab[1]), codomain=self) smi = self.monomial(index) return -x__S_Id(smi.coproduct() - tensor([smi, self.one()]) ) + smi.counit()
def coproduct(self, elt): r""" Return the coproduct of the element ``elt``. INPUT: - ``elt`` -- a symmetric function written in this basis OUTPUT: - The coproduct acting on ``elt``; the result is an element of the tensor squared of the basis ``self`` EXAMPLES:: sage: w = SymmetricFunctions(QQ).w() sage: w[2].coproduct() w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w.coproduct(w[2]) w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w[2,1].coproduct() w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] sage: w.coproduct(w[2,1]) w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] TESTS: The same, but with other settings:: sage: w = SymmetricFunctions(QQ).w(coerce_h=False, coerce_e=True) sage: w[2].coproduct() w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w.coproduct(w[2]) w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w[2,1].coproduct() w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] sage: w.coproduct(w[2,1]) w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] sage: w = SymmetricFunctions(QQ).w(coerce_h=False, coerce_p=True) sage: w[2].coproduct() w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w.coproduct(w[2]) w[] # w[2] - w[1] # w[1] + w[2] # w[] sage: w[2,1].coproduct() w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] sage: w.coproduct(w[2,1]) w[] # w[2, 1] - w[1] # w[1, 1] + w[1] # w[2] - w[1, 1] # w[1] + w[2] # w[1] + w[2, 1] # w[] """ from sage.categories.tensor import tensor friendly = self._friendly return self.tensor_square().sum(coeff * tensor([self(friendly[x]), self(friendly[y])]) for ((x,y), coeff) in friendly(elt).coproduct())
def antipode_on_basis(self, index): r""" The antipode on the basis element indexed by ``index``. INPUT: - ``index`` -- an element of the index set For a graded connected Hopf algebra, we can define an antipode recursively by .. MATH:: S(x) := -\sum_{x^L \neq x} S(x^L) \times x^R when `|x| > 0`, and by `S(x) = x` when `|x| = 0`. TESTS:: sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: H.monomial(0).antipode() # indirect doctest P0 sage: H.monomial(1).antipode() # indirect doctest -P1 sage: H.monomial(2).antipode() # indirect doctest P2 sage: H.monomial(3).antipode() # indirect doctest -P3 """ if self.monomial(index) == self.one(): return self.one() S = self.antipode_on_basis x__S_Id = tensor([self, self]).module_morphism( lambda ab: S(ab[0]) * self.monomial(ab[1]), codomain=self) return -x__S_Id( self.monomial(index).coproduct() - tensor([self.monomial(index), self.one()]) )
def antipode_on_basis(self, index): r""" The antipode on the basis element indexed by ``index``. INPUT: - ``index`` -- an element of the index set For a graded connected Hopf algebra, we can define an antipode recursively by .. MATH:: S(x) := -\sum_{x^L \neq x} S(x^L) \times x^R when `|x| > 0`, and by `S(x) = x` when `|x| = 0`. TESTS:: sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: H.monomial(0).antipode() # indirect doctest P0 sage: H.monomial(1).antipode() # indirect doctest -P1 sage: H.monomial(2).antipode() # indirect doctest P2 sage: H.monomial(3).antipode() # indirect doctest -P3 """ if self.monomial(index) == self.one(): return self.one() S = self.antipode_on_basis x__S_Id = tensor([self, self]).module_morphism( lambda ab: S(ab[0]) * self.monomial(ab[1]), codomain=self) return -x__S_Id( self.monomial(index).coproduct() - tensor([self.monomial(index), self.one()]))
def antipode_on_basis(self, index): r""" The antipode on the basis element indexed by ``index``. INPUT: - ``index`` -- an element of the index set .. MATH:: S(x) := -\sum_{x^L\neq x} S(x^L) \times x^R in general or `x` if `|x| = 0`. TESTS:: sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: H.monomial(0).antipode() #indirect doctest P0 sage: H.monomial(1).antipode() #indirect doctest -P1 sage: H.monomial(2).antipode() #indirect doctest P2 sage: H.monomial(3).antipode() #indirect doctest -P3 """ if self.monomial(index) == self.one(): return self.one() else: S = self.antipode_on_basis x__S_Id = tensor([self, self]).module_morphism( lambda (a, b): S(a) * self.monomial(b), codomain=self) return -x__S_Id( self.monomial(index).coproduct() - tensor([self.monomial(index), self.one()]) )
def antipode_on_basis(self, index): r""" The antipode on the basis element indexed by ``index``. INPUT: - ``index`` -- an element of the index set .. MATH:: S(x) := -\sum_{x^L\neq x} S(x^L) \times x^R in general or `x` if `|x| = 0`. TESTS:: sage: H = GradedHopfAlgebrasWithBasis(QQ).Connected().example() sage: H.monomial(0).antipode() #indirect doctest P0 sage: H.monomial(1).antipode() #indirect doctest -P1 sage: H.monomial(2).antipode() #indirect doctest P2 sage: H.monomial(3).antipode() #indirect doctest -P3 """ if self.monomial(index) == self.one(): return self.one() else: S = self.antipode_on_basis x__S_Id = tensor([self, self]).module_morphism( lambda (a, b): S(a) * self.monomial(b), codomain=self) return -x__S_Id( self.monomial(index).coproduct() - tensor([self.monomial(index), self.one()]))
def character_quotient(M, N, n, r, left_basis=s, right_basis=s): """ Compute the difference of bicharacter between the subspaces `M` and `N`. They have to be subspaces of multivariate polynomials projected on isotypic components of `S_n`. INPUT: - ``M``, ``N`` -- subspaces - ``n``, ``r`` -- integers - ``left_basis`` -- a basis of the symmetric functions for the $GL_r$-character - ``right_basis`` -- a basis of the symmetric functions for the $S_n$-character - ``row_symmetry`` -- use "permutation" to compute using the symmetries on rows EXAMPLES:: """ b_tot = M.basis() b_ideal = N.basis() charac = 0 q = PolynomialRing(QQ, 'q', r).gens() for nu in Partitions(n): basis_nu_tot = {} basis_nu_ideal = {} charac_nu = 0 # Get the nu_isotypic part of the bases for key, value in b_tot.iteritems(): if Partition(key[1]) == nu: basis_nu_tot[key[0]] = value for key, value in b_ideal.iteritems(): if Partition(key[1]) == nu: basis_nu_ideal[key[0]] = value # Use the degrees to compute the character for deg, b in basis_nu_tot.iteritems(): charac_nu += sum( prod(q[i]**deg[i] for i in range(0, len(deg))) for p in b) for deg, b in basis_nu_ideal.iteritems(): charac_nu -= sum( prod(q[i]**deg[i] for i in range(0, len(deg))) for p in b) if charac_nu != 0: if left_basis == s: charac_nu = s.from_polynomial( charac_nu).restrict_partition_lengths(r, exact=False) else: charac_nu = left_basis.from_polynomial(charac_nu) # Make the tensor product with s[nu] charac += tensor([charac_nu, right_basis(s(nu))]) return charac
def coproduct_on_basis(self, g): r""" Returns the coproduct of the element of the basis (which are group-like). Used to compute the coproduct of any element. EXAMPLES:: sage: A=CyclicPermutationGroup(6).algebra(ZZ);A Group algebra of Cyclic group of order 6 as a permutation group over Integer Ring sage: g=CyclicPermutationGroup(6).an_element();g (1,2,3,4,5,6) sage: A.coproduct_on_basis(g) B[(1,2,3,4,5,6)] # B[(1,2,3,4,5,6)] sage: a=A.an_element();a B[()] + 3*B[(1,2,3,4,5,6)] + 3*B[(1,3,5)(2,4,6)] sage: a.coproduct() B[()] # B[()] + 3*B[(1,2,3,4,5,6)] # B[(1,2,3,4,5,6)] + 3*B[(1,3,5)(2,4,6)] # B[(1,3,5)(2,4,6)] """ from sage.categories.tensor import tensor g = self.term(g) return tensor([g, g])
def free_module(self, d): """ Return the free module in degree ``d``. EXAMPLES:: sage: SGA = SymmetricGroupAlgebra(QQ, 3) sage: T = SGA.trivial_representation() sage: H = SGA.hochschild_complex(T) sage: H.free_module(0) Trivial representation of Standard permutations of 3 over Rational Field sage: H.free_module(1) Trivial representation of Standard permutations of 3 over Rational Field # Symmetric group algebra of order 3 over Rational Field sage: H.free_module(2) Trivial representation of Standard permutations of 3 over Rational Field # Symmetric group algebra of order 3 over Rational Field # Symmetric group algebra of order 3 over Rational Field """ if d < 0: raise ValueError("only defined for non-negative degree") return tensor([self._M] + [self._A]*d)
def module(self, d): """ Return the module in degree ``d``. EXAMPLES:: sage: SGA = SymmetricGroupAlgebra(QQ, 3) sage: T = SGA.trivial_representation() sage: H = SGA.hochschild_complex(T) sage: H.module(0) Trivial representation of Standard permutations of 3 over Rational Field sage: H.module(1) Trivial representation of Standard permutations of 3 over Rational Field # Symmetric group algebra of order 3 over Rational Field sage: H.module(2) Trivial representation of Standard permutations of 3 over Rational Field # Symmetric group algebra of order 3 over Rational Field # Symmetric group algebra of order 3 over Rational Field """ if d < 0: raise ValueError("only defined for non-negative degree") return tensor([self._M] + [self._A] * d)
def coproduct_on_basis(self, g): r""" Return the coproduct of the element ``g`` of the basis. Each basis element ``g`` is group-like. This method is used to compute the coproduct of any element. EXAMPLES:: sage: A = CyclicPermutationGroup(6).algebra(ZZ); A Algebra of Cyclic group of order 6 as a permutation group over Integer Ring sage: g = CyclicPermutationGroup(6).an_element(); g (1,2,3,4,5,6) sage: A.coproduct_on_basis(g) (1,2,3,4,5,6) # (1,2,3,4,5,6) sage: a = A.an_element(); a () + (1,2,3,4,5,6) + 3*(1,3,5)(2,4,6) + 2*(1,5,3)(2,6,4) sage: a.coproduct() () # () + (1,2,3,4,5,6) # (1,2,3,4,5,6) + 3*(1,3,5)(2,4,6) # (1,3,5)(2,4,6) + 2*(1,5,3)(2,6,4) # (1,5,3)(2,6,4) """ from sage.categories.tensor import tensor g = self.term(g) return tensor([g, g])
def coproduct_on_basis(self, g): r""" Return the coproduct of the element ``g`` of the basis. Each basis element ``g`` is group-like. This method is used to compute the coproduct of any element. EXAMPLES:: sage: A = CyclicPermutationGroup(6).algebra(ZZ); A Algebra of Cyclic group of order 6 as a permutation group over Integer Ring sage: g = CyclicPermutationGroup(6).an_element(); g (1,2,3,4,5,6) sage: A.coproduct_on_basis(g) (1,2,3,4,5,6) # (1,2,3,4,5,6) sage: a = A.an_element(); a () + 3*(1,2,3,4,5,6) + 3*(1,3,5)(2,4,6) sage: a.coproduct() () # () + 3*(1,2,3,4,5,6) # (1,2,3,4,5,6) + 3*(1,3,5)(2,4,6) # (1,3,5)(2,4,6) """ from sage.categories.tensor import tensor g = self.term(g) return tensor([g, g])
def character(S, left_basis=s, right_basis=s, row_symmetry=None): """ Return the bicharacter of the subspace `S` into the given bases. The subspace `S` must be a multivariate polynomial subspace projected on isotypic components of `S_n` or a dictionnary of subspaces projected on isotypic components. INPUT: - ``S`` -- a subspace or a dictionnary of subspaces - ``left_basis`` -- a basis of the symmetric functions for the $GL_r$-character - ``right_basis`` -- a basis of the symmetric functions for the $S_n$-character - ``row_symmetry`` -- use "permutation" to compute using the symmetries on rows EXAMPLES:: sage: v = vandermonde(Partition([2,2])) sage: gen = {v.multidegree(): [v]} sage: op = partial_derivatives(v.parent()) sage: V = Subspace(gen, op) sage: V_iso = IsotypicComponent(V, 4, use_antisymmetry=True) sage: op_pol = polarization_operators(2, max_deg = v.degree()) sage: V_pol = PolarizedSpace(V_iso, op_pol) sage: character(V_pol) s[] # s[2, 2] + s[1] # s[2, 1, 1] + s[2] # s[1, 1, 1, 1] sage: op_pol = polarization_operators(2, max_deg = v.degree(), row_symmetry="permutation") sage: V_pol = PolarizedSpace(V_iso, op_pol) sage: character(V_pol, row_symmetry="permutation") s[] # s[2, 2] + s[1] # s[2, 1, 1] + s[2] # s[1, 1, 1, 1] """ if isinstance(S, dict): return sum( character(V, left_basis=left_basis, right_basis=right_basis, row_symmetry=row_symmetry) for V in S.values()) else: basis = S.basis() basis_element = basis.values().pop()[0] P = basis_element.parent() n = P.ncols() r = P.nrows() charac = 0 if row_symmetry != "permutation": q = PolynomialRing(QQ, 'q', r).gens() for nu in Partitions(n): basis_nu = {} charac_nu = 0 # Get the nu_isotypic part of the basis for key, value in basis.iteritems(): if Partition(key[1]) == nu: basis_nu[key[0]] = value # Use monomials to compute the character if row_symmetry == "permutation": for deg, b in basis_nu.iteritems(): charac_nu += sum(m(Partition(deg)) for p in b) if charac_nu != 0: if left_basis == s: charac_nu = s(charac_nu).restrict_partition_lengths( r, exact=False) elif left_basis != m: charac_nu = left_basis(charac_nu) # Or use directly the degrees else: for deg, b in basis_nu.iteritems(): charac_nu += sum( prod(q[i]**deg[i] for i in range(0, len(deg))) for p in b) if charac_nu != 0: if left_basis == s: charac_nu = s.from_polynomial( charac_nu).restrict_partition_lengths(r, exact=False) else: charac_nu = left_basis.from_polynomial(charac_nu) # Make the tensor product with s[nu] if charac_nu != 0: charac += tensor([charac_nu, right_basis(s(nu))]) return charac
def __init_extra__(self): self._yacop_grading = tensor( [mod._yacop_grading for mod in self._sets]) # hack, because tensor doesn't accept extra arguments self._yacop_grading._domain = self
def convolution_product(self, *maps): r""" Return the image of ``self`` under the convolution product (map) of the maps. Let `A` and `B` be bialgebras over a commutative ring `R`. Given maps `f_i : A \to B` for `1 \leq i < n`, define the convolution product .. MATH:: (f_1 * f_2 * \cdots * f_n) := \mu^{(n-1)} \circ (f_1 \otimes f_2 \otimes \cdots \otimes f_n) \circ \Delta^{(n-1)}, where `\Delta^{(k)} := \bigl(\Delta \otimes \mathrm{Id}^{\otimes(k-1)}\bigr) \circ \Delta^{(k-1)}`, with `\Delta^{(1)} = \Delta` (the ordinary coproduct in `A`) and `\Delta^{(0)} = \mathrm{Id}`; and with `\mu^{(k)} := \mu \circ \bigl(\mu^{(k-1)} \otimes \mathrm{Id})` and `\mu^{(1)} = \mu` (the ordinary product in `B`). See [Sw1969]_. (In the literature, one finds, e.g., `\Delta^{(2)}` for what we denote above as `\Delta^{(1)}`. See [KMN2012]_.) INPUT: - ``maps`` -- any number `n \geq 0` of linear maps `f_1, f_2, \ldots, f_n` on ``self.parent()``; or a single ``list`` or ``tuple`` of such maps OUTPUT: - the convolution product of ``maps`` applied to ``self`` REFERENCES: .. [KMN2012] On the trace of the antipode and higher indicators. Yevgenia Kashina and Susan Montgomery and Richard Ng. Israel J. Math., v.188, 2012. .. [Sw1969] Hopf algebras. Moss Sweedler. W.A. Benjamin, Math Lec Note Ser., 1969. AUTHORS: - Amy Pang - 12 June 2015 - Sage Days 65 .. TODO:: Remove dependency on ``modules_with_basis`` methods. EXAMPLES: We compute convolution products of the identity and antipode maps on Schur functions:: sage: Id = lambda x: x sage: Antipode = lambda x: x.antipode() sage: s = SymmetricFunctions(QQ).schur() sage: s[3].convolution_product(Id, Id) 2*s[2, 1] + 4*s[3] sage: s[3,2].convolution_product(Id) == s[3,2] True The method accepts multiple arguments, or a single argument consisting of a list of maps:: sage: s[3,2].convolution_product(Id, Id) 2*s[2, 1, 1, 1] + 6*s[2, 2, 1] + 6*s[3, 1, 1] + 12*s[3, 2] + 6*s[4, 1] + 2*s[5] sage: s[3,2].convolution_product([Id, Id]) 2*s[2, 1, 1, 1] + 6*s[2, 2, 1] + 6*s[3, 1, 1] + 12*s[3, 2] + 6*s[4, 1] + 2*s[5] We test the defining property of the antipode morphism; namely, that the antipode is the inverse of the identity map in the convolution algebra whose identity element is the composition of the counit and unit:: sage: s[3,2].convolution_product() == s[3,2].convolution_product(Antipode, Id) == s[3,2].convolution_product(Id, Antipode) True :: sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() sage: Psi[2,1].convolution_product(Id, Id, Id) 3*Psi[1, 2] + 6*Psi[2, 1] sage: (Psi[5,1] - Psi[1,5]).convolution_product(Id, Id, Id) -3*Psi[1, 5] + 3*Psi[5, 1] :: sage: G = SymmetricGroup(3) sage: QG = GroupAlgebra(G,QQ) sage: x = QG.sum_of_terms([(p,p.length()) for p in Permutations(3)]); x [1, 3, 2] + [2, 1, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] + 3*[3, 2, 1] sage: x.convolution_product(Id, Id) 5*[1, 2, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] sage: x.convolution_product(Id, Id, Id) 4*[1, 2, 3] + [1, 3, 2] + [2, 1, 3] + 3*[3, 2, 1] sage: x.convolution_product([Id]*6) 9*[1, 2, 3] TESTS:: sage: Id = lambda x: x sage: Antipode = lambda x: x.antipode() :: sage: h = SymmetricFunctions(QQ).h() sage: h[5].convolution_product([Id, Id]) 2*h[3, 2] + 2*h[4, 1] + 2*h[5] sage: h.one().convolution_product([Id, Antipode]) h[] sage: h[3,2].convolution_product([Id, Antipode]) 0 sage: h.one().convolution_product([Id, Antipode]) == h.one().convolution_product() True :: sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S[4].convolution_product([Id]*5) 5*S[1, 1, 1, 1] + 10*S[1, 1, 2] + 10*S[1, 2, 1] + 10*S[1, 3] + 10*S[2, 1, 1] + 10*S[2, 2] + 10*S[3, 1] + 5*S[4] :: sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() sage: m[[1,3],[2]].convolution_product([Antipode, Antipode]) 3*m{{1}, {2, 3}} + 3*m{{1, 2}, {3}} + 6*m{{1, 2, 3}} - 2*m{{1, 3}, {2}} sage: m[[]].convolution_product([]) m{} sage: m[[1,3],[2]].convolution_product([]) 0 :: sage: QS = SymmetricGroupAlgebra(QQ, 5) sage: x = QS.sum_of_terms(zip(Permutations(5)[3:6],[1,2,3])); x [1, 2, 4, 5, 3] + 2*[1, 2, 5, 3, 4] + 3*[1, 2, 5, 4, 3] sage: x.convolution_product([Antipode, Id]) 6*[1, 2, 3, 4, 5] sage: x.convolution_product(Id, Antipode, Antipode, Antipode) 3*[1, 2, 3, 4, 5] + [1, 2, 4, 5, 3] + 2*[1, 2, 5, 3, 4] :: sage: G = SymmetricGroup(3) sage: QG = GroupAlgebra(G,QQ) sage: x = QG.sum_of_terms([(p,p.length()) for p in Permutations(3)]); x [1, 3, 2] + [2, 1, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] + 3*[3, 2, 1] sage: x.convolution_product(Antipode, Id) 9*[1, 2, 3] sage: x.convolution_product([Id, Antipode, Antipode, Antipode]) 5*[1, 2, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] :: sage: s[3,2].counit().parent() == s[3,2].convolution_product().parent() False """ # Be flexible on how the maps are entered: accept a list/tuple of # maps as well as multiple arguments if len(maps) == 1 and isinstance(maps[0], (list, tuple)): T = tuple(maps[0]) else: T = maps H = self.parent() n = len(T) if n == 0: return H.one() * self.counit() if n == 1: return T[0](self) # We apply the maps T_i and products concurrently with coproducts, as this # seems to be faster than applying a composition of maps, e.g., (H.nfold_product) * tensor(T) * (H.nfold_coproduct). out = tensor((H.one(), self)) HH = tensor((H, H)) for mor in T[:-1]: #ALGORITHM: #`split_convolve` moves terms of the form x # y to x*Ti(y1) # y2 in Sweedler notation. split_convolve = lambda (x, y): ( ((xy1, y2), c * d) for ((y1, y2), d) in H.term(y).coproduct() for (xy1, c) in H.term(x) * mor(H.term(y1))) out = HH.module_morphism( on_basis=lambda t: HH.sum_of_terms(split_convolve(t)), codomain=HH)(out) #Apply final map `T_n` to last term, `y`, and multiply. return HH.module_morphism(on_basis=lambda (x, y): H.term(x) * T[-1] (H.term(y)), codomain=H)(out)
def convolution_product(self, *maps): r""" Return the image of ``self`` under the convolution product (map) of the maps. Let `A` and `B` be bialgebras over a commutative ring `R`. Given maps `f_i : A \to B` for `1 \leq i < n`, define the convolution product .. MATH:: (f_1 * f_2 * \cdots * f_n) := \mu^{(n-1)} \circ (f_1 \otimes f_2 \otimes \cdots \otimes f_n) \circ \Delta^{(n-1)}, where `\Delta^{(k)} := \bigl(\Delta \otimes \mathrm{Id}^{\otimes(k-1)}\bigr) \circ \Delta^{(k-1)}`, with `\Delta^{(1)} = \Delta` (the ordinary coproduct in `A`) and `\Delta^{(0)} = \mathrm{Id}`; and with `\mu^{(k)} := \mu \circ \bigl(\mu^{(k-1)} \otimes \mathrm{Id})` and `\mu^{(1)} = \mu` (the ordinary product in `B`). See [Sw1969]_. (In the literature, one finds, e.g., `\Delta^{(2)}` for what we denote above as `\Delta^{(1)}`. See [KMN2012]_.) INPUT: - ``maps`` -- any number `n \geq 0` of linear maps `f_1, f_2, \ldots, f_n` on ``self.parent()``; or a single ``list`` or ``tuple`` of such maps OUTPUT: - the convolution product of ``maps`` applied to ``self`` REFERENCES: .. [KMN2012] On the trace of the antipode and higher indicators. Yevgenia Kashina and Susan Montgomery and Richard Ng. Israel J. Math., v.188, 2012. .. [Sw1969] Hopf algebras. Moss Sweedler. W.A. Benjamin, Math Lec Note Ser., 1969. AUTHORS: - Amy Pang - 12 June 2015 - Sage Days 65 .. TODO:: Remove dependency on ``modules_with_basis`` methods. EXAMPLES: We compute convolution products of the identity and antipode maps on Schur functions:: sage: Id = lambda x: x sage: Antipode = lambda x: x.antipode() sage: s = SymmetricFunctions(QQ).schur() sage: s[3].convolution_product(Id, Id) 2*s[2, 1] + 4*s[3] sage: s[3,2].convolution_product(Id) == s[3,2] True The method accepts multiple arguments, or a single argument consisting of a list of maps:: sage: s[3,2].convolution_product(Id, Id) 2*s[2, 1, 1, 1] + 6*s[2, 2, 1] + 6*s[3, 1, 1] + 12*s[3, 2] + 6*s[4, 1] + 2*s[5] sage: s[3,2].convolution_product([Id, Id]) 2*s[2, 1, 1, 1] + 6*s[2, 2, 1] + 6*s[3, 1, 1] + 12*s[3, 2] + 6*s[4, 1] + 2*s[5] We test the defining property of the antipode morphism; namely, that the antipode is the inverse of the identity map in the convolution algebra whose identity element is the composition of the counit and unit:: sage: s[3,2].convolution_product() == s[3,2].convolution_product(Antipode, Id) == s[3,2].convolution_product(Id, Antipode) True :: sage: Psi = NonCommutativeSymmetricFunctions(QQ).Psi() sage: Psi[2,1].convolution_product(Id, Id, Id) 3*Psi[1, 2] + 6*Psi[2, 1] sage: (Psi[5,1] - Psi[1,5]).convolution_product(Id, Id, Id) -3*Psi[1, 5] + 3*Psi[5, 1] :: sage: G = SymmetricGroup(3) sage: QG = GroupAlgebra(G,QQ) sage: x = QG.sum_of_terms([(p,p.length()) for p in Permutations(3)]); x [1, 3, 2] + [2, 1, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] + 3*[3, 2, 1] sage: x.convolution_product(Id, Id) 5*[1, 2, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] sage: x.convolution_product(Id, Id, Id) 4*[1, 2, 3] + [1, 3, 2] + [2, 1, 3] + 3*[3, 2, 1] sage: x.convolution_product([Id]*6) 9*[1, 2, 3] TESTS:: sage: Id = lambda x: x sage: Antipode = lambda x: x.antipode() :: sage: h = SymmetricFunctions(QQ).h() sage: h[5].convolution_product([Id, Id]) 2*h[3, 2] + 2*h[4, 1] + 2*h[5] sage: h.one().convolution_product([Id, Antipode]) h[] sage: h[3,2].convolution_product([Id, Antipode]) 0 sage: h.one().convolution_product([Id, Antipode]) == h.one().convolution_product() True :: sage: S = NonCommutativeSymmetricFunctions(QQ).S() sage: S[4].convolution_product([Id]*5) 5*S[1, 1, 1, 1] + 10*S[1, 1, 2] + 10*S[1, 2, 1] + 10*S[1, 3] + 10*S[2, 1, 1] + 10*S[2, 2] + 10*S[3, 1] + 5*S[4] :: sage: m = SymmetricFunctionsNonCommutingVariables(QQ).m() sage: m[[1,3],[2]].convolution_product([Antipode, Antipode]) 3*m{{1}, {2, 3}} + 3*m{{1, 2}, {3}} + 6*m{{1, 2, 3}} - 2*m{{1, 3}, {2}} sage: m[[]].convolution_product([]) m{} sage: m[[1,3],[2]].convolution_product([]) 0 :: sage: QS = SymmetricGroupAlgebra(QQ, 5) sage: x = QS.sum_of_terms(zip(Permutations(5)[3:6],[1,2,3])); x [1, 2, 4, 5, 3] + 2*[1, 2, 5, 3, 4] + 3*[1, 2, 5, 4, 3] sage: x.convolution_product([Antipode, Id]) 6*[1, 2, 3, 4, 5] sage: x.convolution_product(Id, Antipode, Antipode, Antipode) 3*[1, 2, 3, 4, 5] + [1, 2, 4, 5, 3] + 2*[1, 2, 5, 3, 4] :: sage: G = SymmetricGroup(3) sage: QG = GroupAlgebra(G,QQ) sage: x = QG.sum_of_terms([(p,p.length()) for p in Permutations(3)]); x [1, 3, 2] + [2, 1, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] + 3*[3, 2, 1] sage: x.convolution_product(Antipode, Id) 9*[1, 2, 3] sage: x.convolution_product([Id, Antipode, Antipode, Antipode]) 5*[1, 2, 3] + 2*[2, 3, 1] + 2*[3, 1, 2] :: sage: s[3,2].counit().parent() == s[3,2].convolution_product().parent() False """ # Be flexible on how the maps are entered: accept a list/tuple of # maps as well as multiple arguments if len(maps) == 1 and isinstance(maps[0], (list, tuple)): T = tuple(maps[0]) else: T = maps H = self.parent() n = len(T) if n == 0: return H.one() * self.counit() if n == 1: return T[0](self) # We apply the maps T_i and products concurrently with coproducts, as this # seems to be faster than applying a composition of maps, e.g., (H.nfold_product) * tensor(T) * (H.nfold_coproduct). out = tensor((H.one(),self)) HH = tensor((H,H)) for mor in T[:-1]: #ALGORITHM: #`split_convolve` moves terms of the form x # y to x*Ti(y1) # y2 in Sweedler notation. def split_convolve(x_y): x, y = x_y return (((xy1,y2),c*d) for ((y1,y2),d) in H.term(y).coproduct() for (xy1,c) in H.term(x)*mor(H.term(y1))) out = HH.module_morphism(on_basis=lambda t: HH.sum_of_terms(split_convolve(t)), codomain=HH)(out) #Apply final map `T_n` to last term, `y`, and multiply. return HH.module_morphism(on_basis=lambda xy: H.term(xy[0])*T[-1](H.term(xy[1])), codomain=H)(out)