Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge #34474
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Koeppe committed Sep 4, 2022
2 parents 45bf6f3 + 803f7e4 commit 0648daa
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 109 deletions.
74 changes: 3 additions & 71 deletions src/sage/tensor/modules/ext_pow_free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,21 +572,12 @@ class ExtPowerDualFreeModule(FiniteRankFreeModule_abstract):
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^*`::
It also coincides with the module of type-`(0,1)` tensors::
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())
sage: M.dual_exterior_power(1) is M.tensor_module(0,1)
True
For a degree `p\geq 2`, the coercion holds only in the direction
For a degree `p\geq 2`, there is a coercion map
`\Lambda^p(M^*)\rightarrow T^{(0,p)}(M)`::
sage: T02 = M.tensor_module(0,2) ; T02
Expand All @@ -597,24 +588,6 @@ class ExtPowerDualFreeModule(FiniteRankFreeModule_abstract):
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
Expand Down Expand Up @@ -782,47 +755,6 @@ def _an_element_(self):
resu.set_comp()[ind] = self._fmodule._ring.an_element()
return resu

def _coerce_map_from_(self, other):
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
"""
from sage.tensor.modules.tensor_free_module import TensorFreeModule
if isinstance(other, TensorFreeModule):
# coercion of a type-(0,1) tensor to a linear form
if self._fmodule is other._fmodule and self._degree == 1 and \
other.tensor_type() == (0,1):
return True
return False

#### End of parent methods

@cached_method
Expand Down
9 changes: 8 additions & 1 deletion src/sage/tensor/modules/finite_rank_free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -1311,11 +1311,16 @@ def tensor_module(self, k, l, *, sym=None, antisym=None):
sage: M.tensor_module(1,2) is T
True
The base module is itself the module of all type-`(1,0)` tensors::
The module of type-`(1,0)` tensors is the base module itself::
sage: M.tensor_module(1,0) is M
True
while the module of type-`(0,1)` tensors is the dual of the base module::
sage: M.tensor_module(0, 1) is M.dual()
True
By using the arguments ``sym`` and ``antisym``, submodules of a full tensor
module can be constructed::
Expand Down Expand Up @@ -1350,6 +1355,8 @@ def tensor_module(self, k, l, *, sym=None, antisym=None):
except KeyError:
if key == (1, 0):
T = self
elif key == (0, 1):
T = self.dual()
elif sym or antisym:
from sage.tensor.modules.tensor_free_submodule import TensorFreeSubmodule_sym
T = TensorFreeSubmodule_sym(self, (k, l), sym=sym, antisym=antisym)
Expand Down
41 changes: 4 additions & 37 deletions src/sage/tensor/modules/tensor_free_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,39 +238,11 @@ class TensorFreeModule(FiniteRankFreeModule_abstract):
sage: ta.symmetries() # the antisymmetry is of course preserved
no symmetry; antisymmetry: (0, 1)
For the degree `p=1`, there is a coercion in both directions::
For the degree `p=1`, we have the identity `\Lambda^1(M^*) = T^{(0,1)}(M) = 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: T01.has_coerce_map_from(L1)
True
sage: L1.has_coerce_map_from(T01)
sage: M.dual_exterior_power(1) is M.tensor_module(0,1)
True
The coercion map `\Lambda^1(M^*)\rightarrow T^{(0,1)}(M)` in action::
sage: a = M.linear_form('a')
sage: a[:] = -2, 4, 1 ; a.display(e)
a = -2 e^0 + 4 e^1 + e^2
sage: a.parent() is L1
True
sage: ta = T01(a) ; ta
Type-(0,1) tensor a on the Rank-3 free module M over the Integer Ring
sage: ta.display(e)
a = -2 e^0 + 4 e^1 + e^2
The coercion map `T^{(0,1)}(M) \rightarrow \Lambda^1(M^*)` in action::
sage: ta.parent() is T01
True
sage: lta = L1(ta) ; lta
Linear form a on the Rank-3 free module M over the Integer Ring
sage: lta.display(e)
a = -2 e^0 + 4 e^1 + e^2
sage: lta == a
sage: M.tensor_module(0,1) is M.dual()
True
There is a canonical identification between tensors of type `(1,1)` and
Expand Down Expand Up @@ -597,7 +569,7 @@ def _coerce_map_from_(self, other):
but not to tensor modules of other types::
sage: M.tensor_module(0,1)._coerce_map_from_(End(M))
sage: M.tensor_module(0,2)._coerce_map_from_(End(M))
False
and not to type-`(1,1)` tensor modules defined on another free module::
Expand All @@ -623,8 +595,6 @@ def _coerce_map_from_(self, other):
Coercion from alternating forms::
sage: M.tensor_module(0,1)._coerce_map_from_(M.dual_exterior_power(1))
True
sage: M.tensor_module(0,2)._coerce_map_from_(M.dual_exterior_power(2))
True
sage: M.tensor_module(0,2)._coerce_map_from_(M.dual_exterior_power(3))
Expand Down Expand Up @@ -682,9 +652,6 @@ def _repr_(self):
sage: M.tensor_module(1,1)
Free module of type-(1,1) tensors on the 2-dimensional vector space
M over the Rational Field
sage: M.tensor_module(0,1)
Free module of type-(0,1) tensors on the 2-dimensional vector space
M over the Rational Field
"""
description = "Free module of type-({},{}) tensors on the {}".format(
Expand Down

0 comments on commit 0648daa

Please sign in to comment.