# Alternating contravariant tensors on free modules¶

Given a free module $$M$$ of finite rank over a commutative ring $$R$$ and a positive integer $$p$$, an alternating contravariant tensor of degree $$p$$ is a map

$a:\ \underbrace{M^*\times\cdots\times M^*}_{p\ \; \mbox{times}} \longrightarrow R$

that (i) is multilinear and (ii) vanishes whenever any of two of its arguments are equal ($$M^*$$ stands for the dual of $$M$$). $$a$$ is an element of the $$p$$-th exterior power of $$M$$, $$\Lambda^p(M)$$.

Alternating contravariant tensors are implemented via the class AlternatingContrTensor, which is a subclass of the generic tensor class FreeModuleTensor.

AUTHORS:

• Eric Gourgoulhon (2017): initial version

REFERENCES:

class sage.tensor.modules.alternating_contr_tensor.AlternatingContrTensor(fmodule, degree, name=None, latex_name=None)

Alternating contravariant tensor on a free module of finite rank over a commutative ring.

This is a Sage element class, the corresponding parent class being ExtPowerFreeModule.

INPUT:

• fmodule – free module $$M$$ of finite rank over a commutative ring $$R$$, as an instance of FiniteRankFreeModule
• degree – positive integer; the degree $$p$$ of the alternating contravariant tensor (i.e. the tensor rank)
• name – (default: None) string; name given to the alternating contravariant tensor
• latex_name – (default: None) string; LaTeX symbol to denote the alternating contravariant tensor; if none is provided, name is used

EXAMPLES:

Alternating contravariant tensor of degree 2 on a rank-3 free module:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1)
sage: e = M.basis('e')
sage: a = M.alternating_contravariant_tensor(2, name='a') ; a
Alternating contravariant tensor a of degree 2 on the Rank-3
free module M over the Integer Ring
sage: type(a)
<class 'sage.tensor.modules.ext_pow_free_module.ExtPowerFreeModule_with_category.element_class'>
sage: a.parent()
2nd exterior power of the Rank-3 free module M over the Integer Ring
sage: a[1,2], a[2,3] = 4, -3
sage: a.display(e)
a = 4 e_1/\e_2 - 3 e_2/\e_3


The alternating contravariant tensor acting on the dual basis elements:

sage: f = e.dual_basis(); f
Dual basis (e^1,e^2,e^3) on the Rank-3 free module M over the
Integer Ring
sage: a(f[1],f[2])
4
sage: a(f[1],f[3])
0
sage: a(f[2],f[3])
-3
sage: a(f[2],f[1])
-4


An alternating contravariant tensor of degree 1 is an element of the module $$M$$:

sage: b = M.alternating_contravariant_tensor(1, name='b') ; b
Element b of the Rank-3 free module M over the Integer Ring
sage: b[:] = [2,-1,3]  # components w.r.t. the module's default basis (e)
sage: b.parent() is M
True


The standard tensor operations apply to alternating contravariant tensors, like the extraction of components with respect to a given basis:

sage: a[e,1,2]
4
sage: a[1,2]  # since e is the module's default basis
4
sage: all( a[i,j] == - a[j,i] for i in {1,2,3} for j in {1,2,3} )
True


the tensor product:

sage: c = b*b ; c
Type-(2,0) tensor b*b on the Rank-3 free module M over the
Integer Ring
sage: c.symmetries()
symmetry: (0, 1); no antisymmetry
sage: c.parent()
Free module of type-(2,0) tensors on the Rank-3 free module M
over the Integer Ring
sage: c.display(e)
b*b = 4 e_1*e_1 - 2 e_1*e_2 + 6 e_1*e_3 - 2 e_2*e_1 + e_2*e_2
- 3 e_2*e_3 + 6 e_3*e_1 - 3 e_3*e_2 + 9 e_3*e_3


the contractions:

sage: w = f[1] + f[2] + f[3]  # a linear form
sage: s = a.contract(w) ; s
Element of the Rank-3 free module M over the Integer Ring
sage: s.display(e)
4 e_1 - 7 e_2 + 3 e_3


or tensor arithmetics:

sage: s = 3*a + c ; s
Type-(2,0) tensor on the Rank-3 free module M over the Integer Ring
sage: s.parent()
Free module of type-(2,0) tensors on the Rank-3 free module M
over the Integer Ring
sage: s.display(e)
4 e_1*e_1 + 10 e_1*e_2 + 6 e_1*e_3 - 14 e_2*e_1 + e_2*e_2
- 12 e_2*e_3 + 6 e_3*e_1 + 6 e_3*e_2 + 9 e_3*e_3


Note that tensor arithmetics preserves the alternating character if both operands are alternating:

sage: s = a - 2*a ; s
Alternating contravariant tensor of degree 2 on the Rank-3 free
module M over the Integer Ring
sage: s.parent() # note the difference with s = 3*a + c above
2nd exterior power of the Rank-3 free module M over the Integer
Ring
sage: s == -a
True


An operation specific to alternating contravariant tensors is of course the exterior product:

sage: s = a.wedge(b) ; s
Alternating contravariant tensor a/\b of degree 3 on the Rank-3 free
module M over the Integer Ring
sage: s.parent()
3rd exterior power of the Rank-3 free module M over the Integer Ring
sage: s.display(e)
a/\b = 6 e_1/\e_2/\e_3
sage: s[1,2,3] == a[1,2]*b[3] + a[2,3]*b[1] + a[3,1]*b[2]
True


The exterior product is nilpotent on module elements:

sage: s = b.wedge(b) ; s
Alternating contravariant tensor b/\b of degree 2 on the Rank-3 free
module M over the Integer Ring
sage: s.display(e)
b/\b = 0

degree()

Return the degree of self.

EXAMPLES:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: a = M.alternating_contravariant_tensor(2, name='a')
sage: a.degree()
2

disp(basis=None, format_spec=None)

Display the alternating contravariant tensor self in terms of its expansion w.r.t. a given module basis.

The expansion is actually performed onto exterior products of elements of basis (see examples below). The output is either text-formatted (console mode) or LaTeX-formatted (notebook mode).

INPUT:

• basis – (default: None) basis of the free module with respect to which self is expanded; if none is provided, the module’s default basis is assumed
• format_spec – (default: None) format specification passed to self._fmodule._output_formatter to format the output

EXAMPLES:

Display of an alternating contravariant tensor of degree 2 on a rank-3 free module:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: e = M.basis('e')
sage: a = M.alternating_contravariant_tensor(2, 'a', latex_name=r'\alpha')
sage: a[0,1], a[0,2], a[1,2] = 3, 2, -1
sage: a.display()
a = 3 e_0/\e_1 + 2 e_0/\e_2 - e_1/\e_2
sage: latex(a.display())  # display in the notebook
\alpha = 3 e_{0}\wedge e_{1} + 2 e_{0}\wedge e_{2} -e_{1}\wedge e_{2}


Display of an alternating contravariant tensor of degree 3 on a rank-3 free module:

sage: b = M.alternating_contravariant_tensor(3, 'b')
sage: b[0,1,2] = 4
sage: b.display()
b = 4 e_0/\e_1/\e_2
sage: latex(b.display())
b = 4 e_{0}\wedge e_{1}\wedge e_{2}


Display of a vanishing alternating contravariant tensor:

sage: b[0,1,2] = 0  # the only independent component set to zero
sage: b.is_zero()
True
sage: b.display()
b = 0
sage: latex(b.display())
b = 0
sage: b[0,1,2] = 4  # value restored for what follows


Display in a basis which is not the default one:

sage: aut = M.automorphism(matrix=[[0,1,0], [0,0,-1], [1,0,0]],
....:                      basis=e)
sage: f = e.new_basis(aut, 'f')
sage: a.display(f)
a = -2 f_0/\f_1 - f_0/\f_2 - 3 f_1/\f_2
sage: a.disp(f)     # shortcut notation
a = -2 f_0/\f_1 - f_0/\f_2 - 3 f_1/\f_2
sage: b.display(f)
b = -4 f_0/\f_1/\f_2


The output format can be set via the argument output_formatter passed at the module construction:

sage: N = FiniteRankFreeModule(QQ, 3, name='N', start_index=1,
....:                   output_formatter=Rational.numerical_approx)
sage: e = N.basis('e')
sage: a = N.alternating_contravariant_tensor(2, 'a')
sage: a[1,2], a[1,3], a[2,3] = 1/3, 5/2, 4
sage: a.display()  # default format (53 bits of precision)
a = 0.333333333333333 e_1/\e_2 + 2.50000000000000 e_1/\e_3
+ 4.00000000000000 e_2/\e_3


The output format is then controlled by the argument format_spec of the method display():

sage: a.display(format_spec=10)  # 10 bits of precision
a = 0.33 e_1/\e_2 + 2.5 e_1/\e_3 + 4.0 e_2/\e_3

display(basis=None, format_spec=None)

Display the alternating contravariant tensor self in terms of its expansion w.r.t. a given module basis.

The expansion is actually performed onto exterior products of elements of basis (see examples below). The output is either text-formatted (console mode) or LaTeX-formatted (notebook mode).

INPUT:

• basis – (default: None) basis of the free module with respect to which self is expanded; if none is provided, the module’s default basis is assumed
• format_spec – (default: None) format specification passed to self._fmodule._output_formatter to format the output

EXAMPLES:

Display of an alternating contravariant tensor of degree 2 on a rank-3 free module:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: e = M.basis('e')
sage: a = M.alternating_contravariant_tensor(2, 'a', latex_name=r'\alpha')
sage: a[0,1], a[0,2], a[1,2] = 3, 2, -1
sage: a.display()
a = 3 e_0/\e_1 + 2 e_0/\e_2 - e_1/\e_2
sage: latex(a.display())  # display in the notebook
\alpha = 3 e_{0}\wedge e_{1} + 2 e_{0}\wedge e_{2} -e_{1}\wedge e_{2}


Display of an alternating contravariant tensor of degree 3 on a rank-3 free module:

sage: b = M.alternating_contravariant_tensor(3, 'b')
sage: b[0,1,2] = 4
sage: b.display()
b = 4 e_0/\e_1/\e_2
sage: latex(b.display())
b = 4 e_{0}\wedge e_{1}\wedge e_{2}


Display of a vanishing alternating contravariant tensor:

sage: b[0,1,2] = 0  # the only independent component set to zero
sage: b.is_zero()
True
sage: b.display()
b = 0
sage: latex(b.display())
b = 0
sage: b[0,1,2] = 4  # value restored for what follows


Display in a basis which is not the default one:

sage: aut = M.automorphism(matrix=[[0,1,0], [0,0,-1], [1,0,0]],
....:                      basis=e)
sage: f = e.new_basis(aut, 'f')
sage: a.display(f)
a = -2 f_0/\f_1 - f_0/\f_2 - 3 f_1/\f_2
sage: a.disp(f)     # shortcut notation
a = -2 f_0/\f_1 - f_0/\f_2 - 3 f_1/\f_2
sage: b.display(f)
b = -4 f_0/\f_1/\f_2


The output format can be set via the argument output_formatter passed at the module construction:

sage: N = FiniteRankFreeModule(QQ, 3, name='N', start_index=1,
....:                   output_formatter=Rational.numerical_approx)
sage: e = N.basis('e')
sage: a = N.alternating_contravariant_tensor(2, 'a')
sage: a[1,2], a[1,3], a[2,3] = 1/3, 5/2, 4
sage: a.display()  # default format (53 bits of precision)
a = 0.333333333333333 e_1/\e_2 + 2.50000000000000 e_1/\e_3
+ 4.00000000000000 e_2/\e_3


The output format is then controlled by the argument format_spec of the method display():

sage: a.display(format_spec=10)  # 10 bits of precision
a = 0.33 e_1/\e_2 + 2.5 e_1/\e_3 + 4.0 e_2/\e_3

interior_product(form)

Interior product with an alternating form.

If self is an alternating contravariant tensor $$A$$ of degree $$p$$ and $$B$$ is an alternating form of degree $$q\geq p$$ on the same free module, the interior product of $$A$$ by $$B$$ is the alternating form $$\iota_A B$$ of degree $$q-p$$ defined by

$(\iota_A B)_{i_1\ldots i_{q-p}} = A^{k_1\ldots k_p} B_{k_1\ldots k_p i_1\ldots i_{q-p}}$

Note

A.interior_product(B) yields the same result as A.contract(0,..., p-1, B, 0,..., p-1) (cf. contract()), but interior_product is more efficient, the alternating character of $$A$$ being not used to reduce the computation in contract()

INPUT:

• form – alternating form $$B$$ (instance of FreeModuleAltForm); the degree of $$B$$ must be at least equal to the degree of self

OUTPUT:

• element of the base ring (case $$p=q$$) or FreeModuleAltForm (case $$p<q$$) representing the interior product $$\iota_A B$$, where $$A$$ is self

interior_product() for the interior product of an alternating form by an alternating contravariant tensor

EXAMPLES:

Let us consider a rank-4 free module:

sage: M = FiniteRankFreeModule(ZZ, 4, name='M', start_index=1)
sage: e = M.basis('e')


and various interior products on it, starting with a module element (p=1) and a linear form (q=1):

sage: a = M([-2,1,2,3], basis=e, name='A')
sage: b = M.linear_form(name='B')
sage: b[:] = [2, 0, -3, 4]
sage: c = a.interior_product(b); c
2
sage: c == a.contract(b)
True


Case p=1 and q=3:

sage: b = M.alternating_form(3, name='B')
sage: b[1,2,3], b[1,2,4], b[1,3,4], b[2,3,4] = 3, -1, 2, 5
sage: c = a.interior_product(b); c
Alternating form i_A B of degree 2 on the Rank-4 free module M over the Integer Ring
sage: c.display()
i_A B = 3 e^1/\e^2 + 3 e^1/\e^3 - 3 e^1/\e^4 + 9 e^2/\e^3 - 8 e^2/\e^4 + e^3/\e^4
sage: latex(c)
\iota_{A} B
sage: c == a.contract(b)
True


Case p=2 and q=3:

sage: a = M.alternating_contravariant_tensor(2, name='A')
sage: a[1,2], a[1,3], a[1,4] = 2, -5, 3
sage: a[2,3], a[2,4], a[3,4] = -1, 4, 2
sage: c = a.interior_product(b); c
Linear form i_A B on the Rank-4 free module M over the Integer Ring
sage: c.display()
i_A B = -6 e^1 + 56 e^2 - 40 e^3 - 34 e^4
sage: c == a.contract(0, 1, b, 0, 1)  # contraction on all indices of a
True


Case p=2 and q=4:

sage: b = M.alternating_form(4, name='B')
sage: b[1,2,3,4] = 5
sage: c = a.interior_product(b); c
Alternating form i_A B of degree 2 on the Rank-4 free module M over the Integer Ring
sage: c.display()
i_A B = 20 e^1/\e^2 - 40 e^1/\e^3 - 10 e^1/\e^4 + 30 e^2/\e^3 + 50 e^2/\e^4 + 20 e^3/\e^4
sage: c == a.contract(0, 1, b, 0, 1)
True


Case p=2 and q=2:

sage: b = M.alternating_form(2)
sage: b[1,2], b[1,3], b[1,4] = 6, 0, -2
sage: b[2,3], b[2,4], b[3,4] = 2, 3, 4
sage: c = a.interior_product(b); c
48
sage: c == a.contract(0, 1, b, 0, 1)
True


Case p=3 and q=3:

sage: a = M.alternating_contravariant_tensor(3, name='A')
sage: a[1,2,3], a[1,2,4], a[1,3,4], a[2,3,4] = -3, 2, 8, -5
sage: b = M.alternating_form(3, name='B')
sage: b[1,2,3], b[1,2,4], b[1,3,4], b[2,3,4] = 3, -1, 2, 5
sage: c = a.interior_product(b); c
-120
sage: c == a.contract(0, 1, 2, b, 0, 1, 2)
True


Case p=3 and q=4:

sage: b = M.alternating_form(4, name='B')
sage: b[1,2,3,4] = 5
sage: c = a.interior_product(b); c
Linear form i_A B on the Rank-4 free module M over the Integer Ring
sage: c.display()
i_A B = 150 e^1 + 240 e^2 - 60 e^3 - 90 e^4
sage: c == a.contract(0, 1, 2, b, 0, 1, 2)
True


Case p=4 and q=4:

sage: a = M.alternating_contravariant_tensor(4, name='A')
sage: a[1,2,3,4] = -2
sage: c = a.interior_product(b); c
-240
sage: c == a.contract(0, 1, 2, 3, b, 0, 1, 2, 3)
True

wedge(other)

Exterior product of self with the alternating contravariant tensor other.

INPUT:

• other – an alternating contravariant tensor

OUTPUT:

EXAMPLES:

Exterior product of two module elements:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: e = M.basis('e')
sage: a = M([1,-3,4], basis=e, name='A')
sage: b = M([2,-1,2], basis=e, name='B')
sage: c = a.wedge(b) ; c
Alternating contravariant tensor A/\B of degree 2 on the Rank-3
free module M over the Integer Ring
sage: c.display()
A/\B = 5 e_0/\e_1 - 6 e_0/\e_2 - 2 e_1/\e_2
sage: latex(c)
A\wedge B
sage: latex(c.display())
A\wedge B = 5 e_{0}\wedge e_{1} -6 e_{0}\wedge e_{2}
-2 e_{1}\wedge e_{2}


Test of the computation:

sage: a.wedge(b) == a*b - b*a
True


Exterior product of a module element and an alternating contravariant tensor of degree 2:

sage: d = M([-1,2,4], basis=e, name='D')
sage: s = d.wedge(c) ; s
Alternating contravariant tensor D/\A/\B of degree 3 on the Rank-3
free module M over the Integer Ring
sage: s.display()
D/\A/\B = 34 e_0/\e_1/\e_2


Test of the computation:

sage: s[0,1,2] == d[0]*c[1,2] + d[1]*c[2,0] + d[2]*c[0,1]
True


Let us check that the exterior product is associative:

sage: d.wedge(a.wedge(b)) == (d.wedge(a)).wedge(b)
True


and that it is graded anticommutative:

sage: a.wedge(b) == - b.wedge(a)
True
sage: d.wedge(c) == c.wedge(d)
True