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""" Exterior powers of free modules
Given a free module `M` of finite rank over a commutative ring `R` and a positive integer `p`, the `p`-*th exterior power of* `M` is the set `\Lambda^p(M)` of all alternating contravariant tensors of degree `p` on `M`, i.e. of all multilinear maps
.. MATH::
\underbrace{M^*\times\cdots\times M^*}_{p\ \; \mbox{times}} \longrightarrow R
that vanish whenever any of two of their arguments are equal (`M^*` stands for the dual of `M`). Note that `\Lambda^1(M) = M`. The exterior power `\Lambda^p(M)` is a free module of rank `\binom{n}{p}` over `R`, where `n` is the rank of `M`.
Similarly, the `p`-*th exterior power of the dual of* `M` is the set `\Lambda^p(M^*)` of all alternating forms of degree `p` on `M`, i.e. of all multilinear maps
.. MATH::
\underbrace{M\times\cdots\times M}_{p\ \; \mbox{times}} \longrightarrow R
that vanish whenever any of two of their arguments are equal. Note that `\Lambda^1(M^*) = M^*` (the dual of `M`). The exterior power `\Lambda^p(M^*)` is a free module of rank `\binom{n}{p}` over `R`, where `n` is the rank of `M`.
The class :class:`ExtPowerFreeModule` implements `\Lambda^p(M)`, while the class :class:`ExtPowerDualFreeModule` implements `\Lambda^p(M^*)`.
AUTHORS:
- Eric Gourgoulhon: initial version, regarding `\Lambda^p(M^*)` only (2015); add class for `\Lambda^p(M)` (2017)
REFERENCES:
- \K. Conrad: *Exterior powers* [Con2013]_ - Chap. 19 of S. Lang: *Algebra* [Lan2002]_
""" #****************************************************************************** # Copyright (C) 2017 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #******************************************************************************
r""" Exterior power of a free module of finite rank over a commutative ring.
Given a free module `M` of finite rank over a commutative ring `R` and a positive integer `p`, the `p`-*th exterior power of* `M` is the set `\Lambda^p(M)` of all alternating contravariant tensors of degree `p` on `M`, i.e. of all multilinear maps
.. MATH::
\underbrace{M^*\times\cdots\times M^*}_{p\ \; \mbox{times}} \longrightarrow R
that vanish whenever any of two of their arguments are equal. Note that `\Lambda^1(M) = M`.
`\Lambda^p(M)` is a free module of rank `\binom{n}{p}` over `R`, where `n` is the rank of `M`. Accordingly, the class :class:`ExtPowerFreeModule` inherits from the class :class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule`.
This is a Sage *parent* class, whose *element* class is :class:`~sage.tensor.modules.alternating_contr_tensor.AlternatingContrTensor`
INPUT:
- ``fmodule`` -- free module `M` of finite rank, as an instance of :class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule` - ``degree`` -- positive integer; the degree `p` of the alternating elements - ``name`` -- (default: ``None``) string; name given to `\Lambda^p(M)` - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote `\Lambda^p(M)`
EXAMPLES:
2nd exterior power of the dual of a free `\ZZ`-module of rank 3::
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: from sage.tensor.modules.ext_pow_free_module import ExtPowerFreeModule sage: A = ExtPowerFreeModule(M, 2) ; A 2nd exterior power of the Rank-3 free module M over the Integer Ring
Instead of importing ExtPowerFreeModule in the global name space, it is recommended to use the module's method :meth:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule.exterior_power`::
sage: A = M.exterior_power(2) ; A 2nd exterior power of the Rank-3 free module M over the Integer Ring sage: latex(A) \Lambda^{2}\left(M\right)
``A`` is a module (actually a free module) over `\ZZ`::
sage: A.category() Category of finite dimensional modules over Integer Ring sage: A in Modules(ZZ) True sage: A.rank() 3 sage: A.base_ring() Integer Ring sage: A.base_module() Rank-3 free module M over the Integer Ring
``A`` is a *parent* object, whose elements are alternating contravariant tensors, represented by instances of the class :class:`~sage.tensor.modules.alternating_contr_tensor.AlternatingContrTensor`::
sage: a = A.an_element() ; a Alternating contravariant tensor of degree 2 on the Rank-3 free module M over the Integer Ring sage: a.display() # expansion with respect to M's default basis (e) e_0/\e_1 sage: from sage.tensor.modules.alternating_contr_tensor import AlternatingContrTensor sage: isinstance(a, AlternatingContrTensor) True sage: a in A True sage: A.is_parent_of(a) True
Elements can be constructed from ``A``. In particular, 0 yields the zero element of ``A``::
sage: A(0) Alternating contravariant tensor zero of degree 2 on the Rank-3 free module M over the Integer Ring sage: A(0) is A.zero() True
while non-zero elements are constructed by providing their components in a given basis::
sage: e Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring sage: comp = [[0,3,-1],[-3,0,4],[1,-4,0]] sage: a = A(comp, basis=e, name='a') ; a Alternating contravariant tensor a of degree 2 on the Rank-3 free module M over the Integer Ring sage: a.display(e) a = 3 e_0/\e_1 - e_0/\e_2 + 4 e_1/\e_2
An alternative is to construct the alternating contravariant tensor from an empty list of components and to set the nonzero components afterwards::
sage: a = A([], name='a') sage: a.set_comp(e)[0,1] = 3 sage: a.set_comp(e)[0,2] = -1 sage: a.set_comp(e)[1,2] = 4 sage: a.display(e) a = 3 e_0/\e_1 - e_0/\e_2 + 4 e_1/\e_2
The exterior powers are unique::
sage: A is M.exterior_power(2) True
The exterior power `\Lambda^1(M)` is nothing but `M`::
sage: M.exterior_power(1) is M True
For a degree `p\geq 2`, there is a coercion `\Lambda^p(M)\rightarrow T^{(p,0)}(M)`::
sage: T20 = M.tensor_module(2,0) ; T20 Free module of type-(2,0) tensors on the Rank-3 free module M over the Integer Ring sage: T20.has_coerce_map_from(A) True
Of course, there is no coercion in the reverse direction::
sage: A.has_coerce_map_from(T20) False
The coercion map `\Lambda^2(M)\rightarrow T^{(2,0)}(M)` in action::
sage: ta = T20(a) ; ta Type-(2,0) tensor a on the Rank-3 free module M over the Integer Ring sage: ta.display(e) a = 3 e_0*e_1 - e_0*e_2 - 3 e_1*e_0 + 4 e_1*e_2 + e_2*e_0 - 4 e_2*e_1 sage: a.display(e) a = 3 e_0/\e_1 - e_0/\e_2 + 4 e_1/\e_2 sage: ta.symmetries() # the antisymmetry is of course preserved no symmetry; antisymmetry: (0, 1) sage: ta == a # equality as type-(2,0) tensors True
"""
r""" TESTS::
sage: from sage.tensor.modules.ext_pow_free_module import ExtPowerFreeModule sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: A = ExtPowerFreeModule(M, 2) ; A 2nd exterior power of the Rank-3 free module M over the Integer Ring sage: TestSuite(A).run()
""" # in what follows) fmodule._latex_name + r'\right)' name=name, latex_name=latex_name, start_index=fmodule._sindex, output_formatter=fmodule._output_formatter) # Unique representation: self._degree in self._fmodule._exterior_powers: raise ValueError("the {}th exterior power of ".format(degree) + "{}".format(self._fmodule) + " has already been created") else: # Zero element latex_name='0') self._zero_element._new_comp(basis) # (since new components are initialized to zero)
#### Parent methods
latex_name=None): r""" Construct an alternating contravariant tensor.
EXAMPLES::
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: A = M.exterior_power(2) sage: a = A._element_constructor_(0) ; a Alternating contravariant tensor zero of degree 2 on the Rank-3 free module M over the Integer Ring sage: a = A._element_constructor_([], name='a') ; a Alternating contravariant tensor a of degree 2 on the Rank-3 free module M over the Integer Ring sage: a[e,0,2], a[e,1,2] = 3, -1 sage: a.display() a = 3 e_0/\e_2 - e_1/\e_2
""" latex_name=latex_name)
r""" Construct some (unamed) alternating contravariant tensor.
EXAMPLES::
sage: M = FiniteRankFreeModule(QQ, 4, name='M') sage: e = M.basis('e') sage: a = M.exterior_power(2)._an_element_() ; a Alternating contravariant tensor of degree 2 on the 4-dimensional vector space M over the Rational Field sage: a.display() 1/2 e_0/\e_1 sage: a = M.exterior_power(3)._an_element_() ; a Alternating contravariant tensor of degree 3 on the 4-dimensional vector space M over the Rational Field sage: a.display() 1/2 e_0/\e_1/\e_2 sage: a = M.exterior_power(4)._an_element_() ; a Alternating contravariant tensor of degree 4 on the 4-dimensional vector space M over the Rational Field sage: a.display() 1/2 e_0/\e_1/\e_2/\e_3
"""
#### End of parent methods
r""" Return a string representation of ``self``.
EXAMPLES::
sage: M = FiniteRankFreeModule(ZZ, 5, name='M') sage: M.exterior_power(2)._repr_() '2nd exterior power of the Rank-5 free module M over the Integer Ring' sage: M.exterior_power(3)._repr_() '3rd exterior power of the Rank-5 free module M over the Integer Ring' sage: M.exterior_power(4)._repr_() '4th exterior power of the Rank-5 free module M over the Integer Ring' sage: M.exterior_power(5)._repr_() '5th exterior power of the Rank-5 free module M over the Integer Ring'
""" else:
r""" Return the free module on which ``self`` is constructed.
OUTPUT:
- instance of :class:`FiniteRankFreeModule` representing the free module on which the exterior power is defined.
EXAMPLES::
sage: M = FiniteRankFreeModule(ZZ, 5, name='M') sage: A = M.exterior_power(2) sage: A.base_module() Rank-5 free module M over the Integer Ring sage: A.base_module() is M True
"""
r""" Return the degree of ``self``.
OUTPUT:
- integer `p` such that ``self`` is the exterior power `\Lambda^p(M)`
EXAMPLES::
sage: M = FiniteRankFreeModule(ZZ, 5, name='M') sage: A = M.exterior_power(2) sage: A.degree() 2 sage: M.exterior_power(4).degree() 4
"""
#***********************************************************************
r""" Exterior power of the dual of a free module of finite rank over a commutative ring.
Given a free module `M` of finite rank over a commutative ring `R` and a positive integer `p`, the `p`-*th exterior power of the dual of* `M` is the set `\Lambda^p(M^*)` of all alternating forms of degree `p` on `M`, i.e. of all multilinear maps
.. MATH::
\underbrace{M\times\cdots\times M}_{p\ \; \mbox{times}} \longrightarrow R
that vanish whenever any of two of their arguments are equal. Note that `\Lambda^1(M^*) = M^*` (the dual of `M`).
`\Lambda^p(M^*)` is a free module of rank `\binom{n}{p}` over `R`, where `n` is the rank of `M`. Accordingly, the class :class:`ExtPowerDualFreeModule` inherits from the class :class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule`.
This is a Sage *parent* class, whose *element* class is :class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm`.
INPUT:
- ``fmodule`` -- free module `M` of finite rank, as an instance of :class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule` - ``degree`` -- positive integer; the degree `p` of the alternating forms - ``name`` -- (default: ``None``) string; name given to `\Lambda^p(M^*)` - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote `\Lambda^p(M^*)`
EXAMPLES:
2nd exterior power of the dual of a free `\ZZ`-module of rank 3::
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: from sage.tensor.modules.ext_pow_free_module import ExtPowerDualFreeModule sage: A = ExtPowerDualFreeModule(M, 2) ; A 2nd exterior power of the dual of the Rank-3 free module M over the Integer Ring
Instead of importing ExtPowerDualFreeModule in the global name space, it is recommended to use the module's method :meth:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule.dual_exterior_power`::
sage: A = M.dual_exterior_power(2) ; A 2nd exterior power of the dual of the Rank-3 free module M over the Integer Ring sage: latex(A) \Lambda^{2}\left(M^*\right)
``A`` is a module (actually a free module) over `\ZZ`::
sage: A.category() Category of finite dimensional modules over Integer Ring sage: A in Modules(ZZ) True sage: A.rank() 3 sage: A.base_ring() Integer Ring sage: A.base_module() Rank-3 free module M over the Integer Ring
``A`` is a *parent* object, whose elements are alternating forms, represented by instances of the class :class:`~sage.tensor.modules.free_module_alt_form.FreeModuleAltForm`::
sage: a = A.an_element() ; a Alternating form of degree 2 on the Rank-3 free module M over the Integer Ring sage: a.display() # expansion with respect to M's default basis (e) e^0/\e^1 sage: from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm sage: isinstance(a, FreeModuleAltForm) True sage: a in A True sage: A.is_parent_of(a) True
Elements can be constructed from ``A``. In particular, 0 yields the zero element of ``A``::
sage: A(0) Alternating form zero of degree 2 on the Rank-3 free module M over the Integer Ring sage: A(0) is A.zero() True
while non-zero elements are constructed by providing their components in a given basis::
sage: e Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring sage: comp = [[0,3,-1],[-3,0,4],[1,-4,0]] sage: a = A(comp, basis=e, name='a') ; a Alternating form a of degree 2 on the Rank-3 free module M over the Integer Ring sage: a.display(e) a = 3 e^0/\e^1 - e^0/\e^2 + 4 e^1/\e^2
An alternative is to construct the alternating form from an empty list of components and to set the nonzero components afterwards::
sage: a = A([], name='a') sage: a.set_comp(e)[0,1] = 3 sage: a.set_comp(e)[0,2] = -1 sage: a.set_comp(e)[1,2] = 4 sage: a.display(e) a = 3 e^0/\e^1 - e^0/\e^2 + 4 e^1/\e^2
The exterior powers are unique::
sage: A is M.dual_exterior_power(2) True
The exterior power `\Lambda^1(M^*)` is nothing but `M^*`::
sage: M.dual_exterior_power(1) is M.dual() True sage: M.dual() Dual of the Rank-3 free module M over the Integer Ring sage: latex(M.dual()) M^*
Since any tensor of type (0,1) is a linear form, there is a coercion map from the set `T^{(0,1)}(M)` of such tensors to `M^*`::
sage: T01 = M.tensor_module(0,1) ; T01 Free module of type-(0,1) tensors on the Rank-3 free module M over the Integer Ring sage: M.dual().has_coerce_map_from(T01) True
There is also a coercion map in the reverse direction::
sage: T01.has_coerce_map_from(M.dual()) True
For a degree `p\geq 2`, the coercion holds only in the direction `\Lambda^p(M^*)\rightarrow T^{(0,p)}(M)`::
sage: T02 = M.tensor_module(0,2) ; T02 Free module of type-(0,2) tensors on the Rank-3 free module M over the Integer Ring sage: T02.has_coerce_map_from(A) True sage: A.has_coerce_map_from(T02) False
The coercion map `T^{(0,1)}(M) \rightarrow M^*` in action::
sage: b = T01([-2,1,4], basis=e, name='b') ; b Type-(0,1) tensor b on the Rank-3 free module M over the Integer Ring sage: b.display(e) b = -2 e^0 + e^1 + 4 e^2 sage: lb = M.dual()(b) ; lb Linear form b on the Rank-3 free module M over the Integer Ring sage: lb.display(e) b = -2 e^0 + e^1 + 4 e^2
The coercion map `M^* \rightarrow T^{(0,1)}(M)` in action::
sage: tlb = T01(lb) ; tlb Type-(0,1) tensor b on the Rank-3 free module M over the Integer Ring sage: tlb == b True
The coercion map `\Lambda^2(M^*)\rightarrow T^{(0,2)}(M)` in action::
sage: ta = T02(a) ; ta Type-(0,2) tensor a on the Rank-3 free module M over the Integer Ring sage: ta.display(e) a = 3 e^0*e^1 - e^0*e^2 - 3 e^1*e^0 + 4 e^1*e^2 + e^2*e^0 - 4 e^2*e^1 sage: a.display(e) a = 3 e^0/\e^1 - e^0/\e^2 + 4 e^1/\e^2 sage: ta.symmetries() # the antisymmetry is of course preserved no symmetry; antisymmetry: (0, 1)
"""
r""" TESTS::
sage: from sage.tensor.modules.ext_pow_free_module import ExtPowerDualFreeModule sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: A = ExtPowerDualFreeModule(M, 2) ; A 2nd exterior power of the dual of the Rank-3 free module M over the Integer Ring sage: TestSuite(A).run()
""" # follows) else: fmodule._latex_name + r'^*\right)' latex_name=latex_name, start_index=fmodule._sindex, output_formatter=fmodule._output_formatter) # Unique representation: raise ValueError("the {}th exterior power of ".format(degree) + "the dual of {}".format(self._fmodule) + " has already been created") else: # Zero element latex_name='0') self._zero_element._new_comp(basis) # (since new components are initialized to zero)
#### Parent methods
latex_name=None): r""" Construct an alternating form.
EXAMPLES::
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: A = M.dual_exterior_power(1) sage: a = A._element_constructor_(0) ; a Linear form zero on the Rank-3 free module M over the Integer Ring sage: a = A._element_constructor_([2,0,-1], name='a') ; a Linear form a on the Rank-3 free module M over the Integer Ring sage: a.display() a = 2 e^0 - e^2 sage: A = M.dual_exterior_power(2) sage: a = A._element_constructor_(0) ; a Alternating form zero of degree 2 on the Rank-3 free module M over the Integer Ring sage: a = A._element_constructor_([], name='a') ; a Alternating form a of degree 2 on the Rank-3 free module M over the Integer Ring sage: a[e,0,2], a[e,1,2] = 3, -1 sage: a.display() a = 3 e^0/\e^2 - e^1/\e^2
""" # coercion of a tensor of type (0,1) to a linear form tensor.base_module() is self._fmodule: latex_name=tensor._latex_name) else: raise TypeError("cannot coerce the {} ".format(tensor) + "to an element of {}".format(self)) # standard construction latex_name=latex_name)
r""" Construct some (unamed) alternating form.
EXAMPLES::
sage: M = FiniteRankFreeModule(QQ, 4, name='M') sage: e = M.basis('e') sage: a = M.dual_exterior_power(1)._an_element_() ; a Linear form on the 4-dimensional vector space M over the Rational Field sage: a.display() 1/2 e^0 sage: a = M.dual_exterior_power(2)._an_element_() ; a Alternating form of degree 2 on the 4-dimensional vector space M over the Rational Field sage: a.display() 1/2 e^0/\e^1 sage: a = M.dual_exterior_power(3)._an_element_() ; a Alternating form of degree 3 on the 4-dimensional vector space M over the Rational Field sage: a.display() 1/2 e^0/\e^1/\e^2 sage: a = M.dual_exterior_power(4)._an_element_() ; a Alternating form of degree 4 on the 4-dimensional vector space M over the Rational Field sage: a.display() 1/2 e^0/\e^1/\e^2/\e^3
"""
r""" Determine whether coercion to ``self`` exists from other parent.
EXAMPLES:
Sets of type-`(0,1)` tensors coerce to ``self`` if the degree is 1::
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: L1 = M.dual_exterior_power(1) ; L1 Dual of the Rank-3 free module M over the Integer Ring sage: T01 = M.tensor_module(0,1) ; T01 Free module of type-(0,1) tensors on the Rank-3 free module M over the Integer Ring sage: L1._coerce_map_from_(T01) True
Of course, coercions from other tensor types are meaningless::
sage: L1._coerce_map_from_(M.tensor_module(1,0)) False sage: L1._coerce_map_from_(M.tensor_module(0,2)) False
If the degree is larger than 1, there is no coercion::
sage: L2 = M.dual_exterior_power(2) ; L2 2nd exterior power of the dual of the Rank-3 free module M over the Integer Ring sage: L2._coerce_map_from_(M.tensor_module(0,2)) False
""" # coercion of a type-(0,1) tensor to a linear form other.tensor_type() == (0,1):
#### End of parent methods
r""" Return a string representation of ``self``.
EXAMPLES::
sage: M = FiniteRankFreeModule(ZZ, 5, name='M') sage: M.dual_exterior_power(1)._repr_() 'Dual of the Rank-5 free module M over the Integer Ring' sage: M.dual_exterior_power(2)._repr_() '2nd exterior power of the dual of the Rank-5 free module M over the Integer Ring' sage: M.dual_exterior_power(3)._repr_() '3rd exterior power of the dual of the Rank-5 free module M over the Integer Ring' sage: M.dual_exterior_power(4)._repr_() '4th exterior power of the dual of the Rank-5 free module M over the Integer Ring' sage: M.dual_exterior_power(5)._repr_() '5th exterior power of the dual of the Rank-5 free module M over the Integer Ring'
""" else: self._fmodule)
r""" Return the free module on which ``self`` is constructed.
OUTPUT:
- instance of :class:`FiniteRankFreeModule` representing the free module on which the exterior power is defined.
EXAMPLES::
sage: M = FiniteRankFreeModule(ZZ, 5, name='M') sage: A = M.dual_exterior_power(2) sage: A.base_module() Rank-5 free module M over the Integer Ring sage: A.base_module() is M True
"""
r""" Return the degree of ``self``.
OUTPUT:
- integer `p` such that ``self`` is the exterior power `\Lambda^p(M^*)`
EXAMPLES::
sage: M = FiniteRankFreeModule(ZZ, 5, name='M') sage: A = M.dual_exterior_power(2) sage: A.degree() 2 sage: M.dual_exterior_power(4).degree() 4
"""
|