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
r""" Tensor Algebras
AUTHORS:
- Travis Scrimshaw (2014-01-24): Initial version
.. TODO::
- Coerce to/from free algebra. """
#***************************************************************************** # Copyright (C) 2014 Travis Scrimshaw <tscrim at ucdavis.edu> # # Distributed under the terms of the GNU General Public License (GPL) # http://www.gnu.org/licenses/ #*****************************************************************************
r""" The tensor algebra `T(M)` of a module `M`.
Let `\{ b_i \}_{i \in I}` be a basis of the `R`-module `M`. Then the tensor algebra `T(M)` of `M` is an associative `R`-algebra, with a basis consisting of all tensors of the form `b_{i_1} \otimes b_{i_2} \otimes \cdots \otimes b_{i_n}` for nonnegative integers `n` and `n`-tuples `(i_1, i_2, \ldots, i_n) \in I^n`. The product of `T(M)` is given by
.. MATH::
(b_{i_1} \otimes \cdots \otimes b_{i_m}) \cdot (b_{j_1} \otimes \cdots \otimes b_{j_n}) = b_{i_1} \otimes \cdots \otimes b_{i_m} \otimes b_{j_1} \otimes \cdots \otimes b_{j_n}.
As an algebra, it is generated by the basis vectors `b_i` of `M`. It is an `\NN`-graded `R`-algebra, with the degree of each `b_i` being `1`.
It also has a Hopf algebra structure: The comultiplication is the unique algebra morphism `\delta : T(M) \to T(M) \otimes T(M)` defined by:
.. MATH::
\delta(b_i) = b_i \otimes 1 + 1 \otimes b_i
(where the `\otimes` symbol here forms tensors in `T(M) \otimes T(M)`, not inside `T(M)` itself). The counit is the unique algebra morphism `T(M) \to R` sending each `b_i` to `0`. Its antipode `S` satisfies
.. MATH::
S(b_{i_1} \otimes \cdots \otimes b_{i_m}) = (-1)^m (b_{i_m} \otimes \cdots \otimes b_{i_1}).
This is a connected graded cocommutative Hopf algebra.
REFERENCES:
- :wikipedia:`Tensor_algebra`
.. SEEALSO::
:class:`TensorAlgebra`
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: TA.dimension() +Infinity sage: TA.base_ring() Rational Field sage: TA.algebra_generators() Finite family {'a': B['a'], 'c': B['c'], 'b': B['b']} """ r""" Initialize ``self``.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: TestSuite(TA).run() sage: m = SymmetricFunctions(QQ).m() sage: Tm = TensorAlgebra(m) sage: TestSuite(Tm).run() """
prefix=prefix, category=category, **options)
# the following is not the best option, but it's better than nothing.
r""" Return a string representation of ``self``.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TensorAlgebra(C) Tensor Algebra of Free module generated by {'a', 'b', 'c'} over Rational Field """
""" Return a string of representation of the term indexed by ``m``.
TESTS::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: s = TA(['a','b','c']).leading_support() sage: TA._repr_term(s) "B['a'] # B['b'] # B['c']" sage: s = TA(['a']*3 + ['b']*2 + ['a','c','b']).leading_support() sage: TA._repr_term(s) "B['a'] # B['a'] # B['a'] # B['b'] # B['b'] # B['a'] # B['c'] # B['b']"
sage: I = TA.indices() sage: TA._repr_term(I.one()) '1' """ symb = tensor.symbol
r""" Return a latex representation of the term indexed by ``m``.
TESTS::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: s = TA(['a','b','c']).leading_support() sage: TA._latex_term(s) 'B_{a} \\otimes B_{b} \\otimes B_{c}'
sage: I = TA.indices() sage: TA._latex_term(I.one()) '1' """
""" Return an ascii art representation of the term indexed by ``m``.
TESTS::
sage: C = CombinatorialFreeModule(QQ, Partitions()) sage: TA = TensorAlgebra(C) sage: s = TA([Partition([3,2,2,1]), Partition([3])]).leading_support() sage: TA._ascii_art_term(s) B # B *** *** ** ** * sage: s = TA([Partition([3,2,2,1])]*2 + [Partition([3])]*3 + [Partition([1])]*2).leading_support() sage: TA._ascii_art_term(s) B # B # B # B # B # B # B *** *** *** *** *** * * ** ** ** ** * *
sage: I = TA.indices() sage: TA._ascii_art_term(I.one()) '1' """ symb = tensor.symbol
""" Construct an element of ``self``.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: TA(['a','b','c']) B['a'] # B['b'] # B['c'] sage: TA(['a','b','b']) B['a'] # B['b'] # B['b'] sage: TA(['a','b','c']) + TA(['a']) B['a'] + B['a'] # B['b'] # B['c'] sage: TA(['a','b','c']) + TA(['a','b','a']) B['a'] # B['b'] # B['a'] + B['a'] # B['b'] # B['c'] sage: TA(['a','b','c']) + TA(['a','b','c']) 2*B['a'] # B['b'] # B['c'] sage: TA(C.an_element()) 2*B['a'] + 2*B['b'] + 3*B['c'] """ return self.monomial(FM.gen(x)) return CombinatorialFreeModule._element_constructor_(self, x)
""" Construct an element of ``self`` that is the tensor product of the list of base module elements ``elts``.
TESTS::
sage: C = CombinatorialFreeModule(ZZ, ['a','b']) sage: TA = TensorAlgebra(C) sage: x = C.an_element(); x 2*B['a'] + 2*B['b'] sage: TA._tensor_constructor_([x, x]) 4*B['a'] # B['a'] + 4*B['a'] # B['b'] + 4*B['b'] # B['a'] + 4*B['b'] # B['b'] sage: y = C.monomial('b') + 3*C.monomial('a') sage: TA._tensor_constructor_([x, y]) 6*B['a'] # B['a'] + 2*B['a'] # B['b'] + 6*B['b'] # B['a'] + 2*B['b'] # B['b'] sage: TA._tensor_constructor_([y]) == y True sage: TA._tensor_constructor_([x]) == x True sage: TA._tensor_constructor_([]) == TA.one() True """
""" Return ``True`` if there is a coercion from ``R`` into ``self`` and ``False`` otherwise. The things that coerce into ``self`` are:
- Anything with a coercion into ``self.base_ring()``.
- Anything with a coercion into the base module of ``self``.
- A tensor algebra whose base module has a coercion into the base module of ``self``.
- A tensor module whose factors have a coercion into the base module of ``self``.
TESTS::
sage: C = CombinatorialFreeModule(ZZ, Set([1,2])) sage: TAC = TensorAlgebra(C) sage: TAC.has_coerce_map_from(ZZ) True sage: TAC(1) == TAC.one() True sage: TAC.has_coerce_map_from(C) True sage: c = C.monomial(2) sage: TAC(c) B[2] sage: d = C.monomial(1) sage: TAC(c) * TAC(d) B[2] # B[1] sage: TAC(c-d) * TAC(c+d) -B[1] # B[1] - B[1] # B[2] + B[2] # B[1] + B[2] # B[2]
sage: TCC = tensor((C,C)) sage: TAC.has_coerce_map_from(TCC) True sage: TAC(tensor([c, d])) B[2] # B[1]
::
sage: D = CombinatorialFreeModule(ZZ, Set([2,4])) sage: TAD = TensorAlgebra(D) sage: f = C.module_morphism(on_basis=lambda x: D.monomial(2*x), codomain=D) sage: f.register_as_coercion()
sage: TCD = tensor((C,D)) sage: TAD.has_coerce_map_from(TCC) True sage: TAD.has_coerce_map_from(TCD) True sage: TAC.has_coerce_map_from(TCD) False sage: TAD.has_coerce_map_from(TAC) True sage: TAD(3 * TAC([1, 2, 2, 1, 1])) 3*B[2] # B[4] # B[4] # B[2] # B[2] """ # Base ring coercions return BaseRingLift(Hom(self_base_ring, self))
# Base module coercions phi = M.coerce_map_from(R) return self.coerce_map_from(M) * phi
# Tensor algebra coercions [phi(RM.monomial(k)) for k in m.to_word_list()]), codomain=self)
# Coercions from tensor products and isinstance(R, CombinatorialFreeModule_Tensor) and all(M.has_coerce_map_from(RM) for RM in R._sets)): [vector_map[i](M.monomial(x[i])) for i,M in enumerate(modules)]), codomain=self)
""" Return the functorial construction of ``self``.
EXAMPLES::
sage: C = CombinatorialFreeModule(ZZ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: f, M = TA.construction() sage: M == C True sage: f(M) == TA True """
""" Return the degree of the simple tensor ``m``, which is its length (thought of as an element in the free monoid).
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: s = TA(['a','b','c']).leading_support(); s F['a']*F['b']*F['c'] sage: TA.degree_on_basis(s) 3 """
""" Return the base module of ``self``.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: TA.base_module() is C True """
def one_basis(self): r""" Return the empty word, which indexes of `1` of this algebra.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: TA.one_basis() 1 sage: TA.one_basis().parent() Free monoid indexed by {'a', 'b', 'c'} sage: m = SymmetricFunctions(QQ).m() sage: Tm = TensorAlgebra(m) sage: Tm.one_basis() 1 sage: Tm.one_basis().parent() Free monoid indexed by Partitions """
def algebra_generators(self): r""" Return the generators of this algebra.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: TA.algebra_generators() Finite family {'a': B['a'], 'c': B['c'], 'b': B['b']} sage: m = SymmetricFunctions(QQ).m() sage: Tm = TensorAlgebra(m) sage: Tm.algebra_generators() Lazy family (generator(i))_{i in Partitions} """ lambda i: self.monomial(self._indices.gen(i)), name='generator')
r""" Return the product of the basis elements indexed by ``a`` and ``b``, as per :meth:`AlgebrasWithBasis.ParentMethods.product_on_basis()`.
INPUT:
- ``a``, ``b`` -- basis indices
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: I = TA.indices() sage: g = I.gens() sage: TA.product_on_basis(g['a']*g['b'], g['a']*g['c']) B['a'] # B['b'] # B['a'] # B['c'] """
""" Return the counit of ``x``.
INPUT:
- ``x`` -- an element of ``self``
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: x = TA(['a','b','c']) sage: TA.counit(x) 0 sage: TA.counit(x + 3) 3 """
""" Return the antipode of the simple tensor indexed by ``m``.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C) sage: s = TA(['a','b','c']).leading_support() sage: TA.antipode_on_basis(s) -B['c'] # B['b'] # B['a'] sage: t = TA(['a', 'b', 'b', 'b']).leading_support() sage: TA.antipode_on_basis(t) B['b'] # B['b'] # B['b'] # B['a'] """ else:
""" Return the coproduct of the simple tensor indexed by ``m``.
EXAMPLES::
sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: TA = TensorAlgebra(C, tensor_symbol="(X)") sage: TA.coproduct_on_basis(TA.one_basis()) 1 # 1 sage: I = TA.indices() sage: ca = TA.coproduct_on_basis(I.gen('a')); ca 1 # B['a'] + B['a'] # 1 sage: s = TA(['a','b','c']).leading_support() sage: cp = TA.coproduct_on_basis(s); cp 1 # B['a'](X)B['b'](X)B['c'] + B['a'] # B['b'](X)B['c'] + B['a'](X)B['b'] # B['c'] + B['a'](X)B['b'](X)B['c'] # 1 + B['a'](X)B['c'] # B['b'] + B['b'] # B['a'](X)B['c'] + B['b'](X)B['c'] # B['a'] + B['c'] # B['a'](X)B['b']
We check that `\Delta(a \otimes b \otimes c) = \Delta(a) \Delta(b) \Delta(c)`::
sage: cb = TA.coproduct_on_basis(I.gen('b')) sage: cc = TA.coproduct_on_basis(I.gen('c')) sage: cp == ca * cb * cc True """
for x in m_word)
# TODO: Implement a coproduct using shuffles. # This isn't quite right: #from sage.combinat.words.word import Word #k = len(m) #return S.sum_of_monomials( (I.prod(I.gen(m_word[i]) for i in w[:p]), # I.prod(I.gen(m_word[i]) for i in w[p:])) # for p in range(k+1) # for w in Word(range(p)).shuffle(range(p, k)) )
##################################################################### ## TensorAlgebra functor
r""" The tensor algebra functor.
Let `R` be a unital ring. Let `V_R` and `A_R` be the categories of `R`-modules and `R`-algebras respectively. The functor `T : V_R \to A_R` sends an `R`-module `M` to the tensor algebra `T(M)`. The functor `T` is left-adjoint to the forgetful functor `F : A_R \to V_R`.
INPUT:
- ``base`` -- the base `R` """ # We choose a larger (functor) rank than most ConstructionFunctors # since this should be applied after all of the module functors
""" Initialize ``self``.
EXAMPLES::
sage: from sage.algebras.tensor_algebra import TensorAlgebraFunctor sage: F = TensorAlgebraFunctor(Rings()) sage: TestSuite(F).run() """
""" Return a string representation of ``self``.
EXAMPLES::
sage: from sage.algebras.tensor_algebra import TensorAlgebraFunctor sage: TensorAlgebraFunctor(Rings()) Tensor algebra functor on modules over rings sage: TensorAlgebraFunctor(QQ) Tensor algebra functor on vector spaces over Rational Field """
""" Construct the tensor algebra `T(M)`.
EXAMPLES::
sage: from sage.algebras.tensor_algebra import TensorAlgebraFunctor sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: F = TensorAlgebraFunctor(QQ) sage: F._apply_functor(C) Tensor Algebra of Free module generated by {'a', 'b', 'c'} over Rational Field """ raise NotImplementedError("currently only for modules with basis")
""" Apply ``self`` to a morphism ``f`` in the domain of ``self``.
EXAMPLES::
sage: from sage.algebras.tensor_algebra import TensorAlgebraFunctor sage: C = CombinatorialFreeModule(QQ, ['a','b','c']) sage: D = CombinatorialFreeModule(QQ, ['x','y']) sage: on_basis = lambda m: C.term('a', 2) + C.monomial('b') if m == 'x' else sum(C.basis()) sage: phi = D.module_morphism(on_basis, codomain=C); phi Generic morphism: From: Free module generated by {'x', 'y'} over Rational Field To: Free module generated by {'a', 'b', 'c'} over Rational Field sage: list(map(phi, D.basis())) [2*B['a'] + B['b'], B['a'] + B['b'] + B['c']] sage: F = TensorAlgebraFunctor(QQ) sage: Tphi = F._apply_functor_to_morphism(phi); Tphi Generic morphism: From: Tensor Algebra of Free module generated by {'x', 'y'} over Rational Field To: Tensor Algebra of Free module generated by {'a', 'b', 'c'} over Rational Field sage: G = F(D).algebra_generators() sage: list(map(Tphi, G)) [2*B['a'] + B['b'], B['a'] + B['b'] + B['c']] sage: Tphi(sum(G)) 3*B['a'] + 2*B['b'] + B['c'] sage: Tphi(G['x'] * G['y']) 2*B['a'] # B['a'] + 2*B['a'] # B['b'] + 2*B['a'] # B['c'] + B['b'] # B['a'] + B['b'] # B['b'] + B['b'] # B['c'] """ for k in m.to_word_list()])
##################################################################### ## Lift map from the base ring
r""" Morphism `R \to T(M)` which identifies the base ring `R` of a tensor algebra `T(M)` with the `0`-th graded part of `T(M)`. """ """ Construct the image of ``x``.
TESTS::
sage: C = CombinatorialFreeModule(QQ, Set([1,2])) sage: TA = TensorAlgebra(C) sage: TA(ZZ(2)) 2 """
|