# Tensor Categories

Magma allows tensors and tensor spaces to change categories. Unless a user specifies otherwise, all tensors are assigned a category that is natural to the method by which it was created. For example a tensor created from an algebra will be assigned an algebra category, whereas a tensor created by structure constants will be assigned the Albert homotopism category [[Albert, 1942](../../references.md#cite-albert-fundamentals)]. Tensor categories influence the behavior of commands such as kernels and images as well as the algebraic invariants such as derivation algebras of a tensor.

Our conventions follow [[Wilson, 2013](../../references.md#cite-wilson-division)]. In particular, given a tensor $T$ framed by $[U_{\nu},\dots,U_0]$ then a tensor category for $T$ will specify a function $A:[\nu]\to \{-1,0,1\}$ along with a partition ${\cal P}$ of $[\nu]$ such that the following rules apply to the tensors and morphisms in the category.

**(1)**
for each tensor $T$ framed by $[U_{\nu},\dots,U_0]$, if $X\in{\cal P}$, then

$$
\forall i,j\in X,\quad U_i=U_j.
$$

**(2)**
Given a second tensor $S$ framed by $[V_v,\dots,V_0]$, a morphism $f:T\to S$ (Magma type `Hmtp`) will be a list $[f_{\nu},\dots,f_0]$ of homomorphisms as follows:

**•**
(Covariant) if $A(i)=1$ then $f_i:U_i\to V_i$;

**•**
(Constant) if $A(i)=0$ then $U_i=V_i$ and $f_i=1_{U_i}$; or else

**•**
(Contravariant) $A(i)=-1$ and $f_i:U_i\leftarrow V_i$. So if $A(0)=1$ then

$$
\left\langle \sum_{i\in A^{-1}(1)} u_i f_i
        +\sum_{j\not\in A^{-1}(-1)} v_j\right\rangle_S
        = \left\langle  \sum_{i\in A^{-1}(1)} u_i
        +\sum_{j\not\in A^{-1}(-1)} v_j f_j\right\rangle_T f_0;
$$

if $A(0)=0$ then

$$
\left\langle \sum_{i\in A^{-1}(1)} u_i f_i
        +\sum_{j\not\in A^{-1}(-1)} v_j\right\rangle_S
        = \left\langle  \sum_{i\in A^{-1}(1)} u_i
        +\sum_{j\not\in A^{-1}(-1)} v_j f_j\right\rangle_T;
$$

else $A(0)=-1$ and

$$
\left\langle \sum_{i\in A^{-1}(1)} u_i f_i
        +\sum_{j\not\in A^{-1}(-1)} v_j\right\rangle_S f_0
        = \left\langle  \sum_{i\in A^{-1}(1)} u_i
        +\sum_{j\not\in A^{-1}(-1)} v_j f_j\right\rangle_T.
$$

Magma manages internally the differences between vectors and covectors and more generally tensors and cotensors. Both types are issued the Magma type `TenSpcElt`. For operations sensitive to the difference, Magma stores a value of co/contra-variance of the tensor as a property of the tensor category. This is the third general property stored in Magma’s tensor category type `TenCat`.

We use the phrase tensor category exclusively for categories that describe tensors and tensor spaces. In other words, the data structure of a tensor category is a function $A:[\nu]\rightarrow \{-1,0,1\}$ and a partition ${\cal P}$ of $[\nu]$. It is useful to distinguish from tensors and cotensors at the categorical level, so a tensor category is either covariant or contravariant as well (in the latter case, referred to as a cotensor category).

## Constructing Tensor Categories

### `TensorCategory(A, P): [RngIntElt], {SetEnum} -> TenCat`

### `TensorCategory(A, P): Map, {SetEnum} -> TenCat`

Sets up a covariant tensor space category with specified direction of arrows $A$, and a partition ${\cal P}$ indicating variables to be treated as equivalent. The fiber $A^{-1}(1)$ denotes the covariant variables, $A^{-1}(0)$ identifies the constant variables, and $A^{-1}(-1)$ marks the contra-variant variables.

### `CotensorCategory(A, P): [RngIntElt], {SetEnum} -> TenCat`

### `CotensorCategory(A, P): Map, {SetEnum} -> TenCat`

Sets up a contra-variant tensor space category with specified direction of arrows $A$, and a partition ${\cal P}$ indicating variables to be treated as equivalent. The fiber $A^{-1}(1)$ denotes the covariant variables, $A^{-1}(0)$ identifies the constant variables, and $A^{-1}(-1)$ marks the contra-variant variables.

### `Example: Basic Cat Const (ex-2873fe)`

We demonstrate the basic tensor category constructor. The difference between `TensorCategory` and `CotensorCategory` is only that the former is covariant and the latter is contravariant.

```magma
> C := TensorCategory([1,0,-1], {{0},{1},{2}});
> C;
Tensor category of valence 3 (->,==,<-) ({ 1 },{ 2 },{ 0 })
> IsCovariant(C);
true
>
> arrows := map< {1..5} -> {1} | x :-> 1 >;
> C := CotensorCategory(arrows, {{1..5}});
> C;
Cotensor category of valence 6 (->,->,->,->,->,==) ({ 0 },{ 1 .. 5 })
> IsContravariant(C);
true

```

### `HomotopismCategory(v : parameters): RngIntElt -> TenCat`

```magma
Contravariant: BoolElt                    Default: false
```

Returns Albert’s homotopism category – all modules categories are covariant and no duplicates considered. Set the optional parameter `Contravariant` to `true` to make it a cotensor category.

### `CohomotopismCategory(v): RngIntElt -> TenCat`

Returns the cohomotopism category – all domain modules categories are covariant, the codomain is contravariant, and no duplicates considered.

### `AdjointCategory(v, s, t): RngIntElt, RngIntElt, RngIntElt -> TenCat`

### `LinearCategory(v, s, t): RngIntElt, RngIntElt, RngIntElt -> TenCat`

Returns the tensor category where all modules are constant except in position $s$ and $t$. Both $s$ and $t$ are in $[v]$. Position $s$ is covariant, position $t$ is contravariant.

### `Example: Ten Cat Special (ex-f54041)`

Now we look at a few special tensor category constructors. The default tensor category is the homotopism category, so we construct the homotopism category using `TensorCategory` and verify they are equivalent.

```magma
> C := TensorCategory([1,1,1,1], {{i} : i in [0..3]});
> C;
Tensor category of valence 4 (->,->,->,->) ({ 1 },{ 2 },{ 0 },{ 3 })
> HomotopismCategory(4) eq C;
true

```

The other special tensor categories can be constructed using `TensorCategory` as well, but we just construct a few to show their properties.

```magma
> CohomotopismCategory(3);
Tensor category of valence 3 (->,->,<-) ({ 1 },{ 2 },{ 0 })
>
> AdjointCategory(5, 4, 1);
Tensor category of valence 5 (<-,==,==,->,==) ({ 1 },{ 0, 2, 3 },{ 4 })

```

## Operations on Tensor Categories

In this section the basic operations for tensor categories are described.

### `C1 eq C2: TenCat, TenCat -> BoolElt`

Returns `true` if the tensor categories are the same.

### `Valence(C): TenCat -> RngIntElt`

Returns the valence of the tensor category.

### `Arrows(C): TenCat -> SeqEnum`

Returns the sequence of arrows of the tensor category. A $-1$ signifies a contravariant index, a $0$ signifies a constant index, and a $1$ signifies a covariant index.

### `RepeatPartition(C): TenCat -> SetEnum`

Returns the repeat partition for the tensor category.

### `IsCovariant(C): TenCat -> BoolElt`

### `IsContravariant(C): TenCat -> BoolElt`

Returns `true` if the tensor category is covariant or contravariant.

### `Example: Ten Cat Properties (ex-d61054)`

We obtain basic properties of tensor categories.

```magma
> C := CotensorCategory([1,0,-1,1],{{4,3},{1},{2}});
> C;
Cotensor category of valence 5 (->,==,<-,->,==) ({ 1 },{ 2 },{ 0 },{ 3, 4 })
>
> Valence(C);
5
> Arrows(C);
[ 1, 0, -1, 1 ]
> IsContravariant(C);
true
> RepeatPartition(C);
{
    { 1 },
    { 2 },
    { 3, 4 }
}

```

## Categorical Operations

In this section, we define subtensors, local ideals, ideals, and quotients of tensors. For the following definitions fix a tensor $t\in T$, with frame $\oslash_{a\in[\nu]}U_a$—that is $U_{\nu}\times\cdots\times U_1\rightarrowtail U_0$.

A tensor $s:V_{\nu}\times \cdots\times V_1\rightarrowtail V_0$ is a *subtensor* of $t$ if for all $a$, $V_a\leq U_a$.

For $A\subseteq [\nu]-0$, a tensor $s:V_{\nu}\times \cdots\times V_1\rightarrowtail V_0$ is an $A$*-local ideal* of $t$ if $s$ is a subtensor of $t$ and for each $a\in A$,

$$
\langle s \,|\, V_{\nu},\dots, V_{a+1}, U_a,
V_{a-1},\dots, V_1\rangle \leq V_0.
$$

A tensor $s$ is an *ideal* of $t$ if it is a $\{1,\dots,\nu\}$-local ideal of $t$.

The $A$*-local quotient* of a tensor $t$ by an $A$-local ideal $s$ is the tensor $q:U_{\nu}/V_{\nu} \times \cdots \times U_1/V_1\rightarrowtail U_0/V_0$ where for all $| \overline{\nu}\rangle$,

$$
\langle q \,|\, \overline{\nu}\rangle
\equiv \langle q \,|\, \nu\rangle \rm{mod} V_0.
$$

The *quotient* of a tensor $t$ by an ideal $s$ is the $\{1,\dots,\nu\}$-local quotient of $t$ by $s$.

### Categorical Operations on Tensors

We include functions defined for the category of tensors. Most functions are currently defined only for the homotopism category.

#### `Subtensor(T, S): TenSpcElt, List -> TenSpcElt`

#### `Subtensor(T, S): TenSpcElt, SeqEnum -> TenSpcElt`

Returns the smallest submap of $T$ containing $S$.

#### `Subtensor(T, D, C): TenSpcElt, List, Any -> TenSpcElt`

#### `Subtensor(T, D, C): TenSpcElt, SeqEnum, Any -> TenSpcElt`

Returns the smallest submap of $T$ containing $D$ in the domain and $C$ in the codomain.

#### `IsSubtensor(T, S): TenSpcElt, TenSpcElt -> BoolElt`

Decides whether $S$ is a subtensor of $T$.

#### `Example: Subtensors (ex-b3fa65)`

We construct the tensor $t$ given by octonion multiplication. The quaternions $H$ are a subalgebra of $A= O$ generated by the first four basis elements. However, $H$ cannot be coerced into $A$ because of how Magma organizes algebras.

```magma
> A := OctonionAlgebra(Rationals(), -1, -1, -1);
> t := Tensor(A);
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 8 over Rational Field
U1 : Full Vector space of degree 8 over Rational Field
U0 : Full Vector space of degree 8 over Rational Field
> H := sub< A | A.1, A.2, A.3, A.4 >;
> H;
Algebra of dimension 4 with base ring Rational Field

```

There are multiple ways to get the subtensor of multiplication from $H$. We will create $H\times H\rightarrowtail H$ as a subtensor of $A\times A\rightarrowtail A$.

```magma
> H_gens := [A.i : i in [1..4]];
> s := Subtensor(t, [*H_gens, H_gens, A!0*]);
> s;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Vector space of degree 8, dimension 4 over Rational Field
Generators:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
Echelonized basis:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
U1 : Vector space of degree 8, dimension 4 over Rational Field
Generators:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
Echelonized basis:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
U0 : Vector space of degree 8, dimension 4 over Rational Field
Generators:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
Echelonized basis:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)

```

Note that because $H$ cannot be coerced into $A$ (i.e. `A!H` produces an error), a subtensor of `AlgGen` cannot be done by `Subtensor(t, [H, H, H])`. Now we will construct the tensor straight from $H$. There is a subtle difference between the subtensor from $A$ and the tensor from $H$—namely, the frame is different.

```magma
> s2 := Tensor(H);
> s2;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 4 over Rational Field
U1 : Full Vector space of degree 4 over Rational Field
U0 : Full Vector space of degree 4 over Rational Field
> s eq s2;
false
> Eltseq(s) eq Eltseq(s2);
true

```

#### `LocalIdeal(T, S, I): TenSpcElt, List, {RngIntElt} -> TenSpcElt`

#### `LocalIdeal(T, S, I): TenSpcElt, SeqEnum, {RngIntElt} -> TenSpcElt`

Returns the local ideal of $T$ at $I$ containing $S$.

#### `LocalIdeal(T, D, C, I): TenSpcElt, List, Any, {RngIntElt} -> TenSpcElt`

#### `LocalIdeal(T, D, C, I): TenSpcElt, SeqEnum, Any, {RngIntElt} -> TenSpcElt`

Returns the local ideal of $T$ at $I$ containing $D$ in the domain and $C$ in the codomain.

#### `LocalIdeal(T, S, I): TenSpcElt, TenSpcElt, {RngIntElt} -> TenSpcElt`

Returns the local ideal of $T$ at $I$ containing $S$ as a submap.

#### `IsLocalIdeal(T, S, I): TenSpcElt, TenSpcElt, {RngIntElt} -> BoolElt`

Decides if $S$ is a local ideal of $T$ at $I$.

#### `Example: Local Ideals (ex-96befc)`

We use the same tensor $t$ as the previous example, multiplication in $A= O$, and we construct the subtensor $t_2$ given by multiplication in $H$. We construct a subtensor $s$ of $t$ as the submap containing $\langle A_2\rangle \times \langle A_1, A_4\rangle \rightarrowtail \langle 0\rangle$, which is equal to $\langle A_2\rangle \times \langle A_1, A_4\rangle \rightarrowtail \langle A_2A_1, A_2A_4\rangle$.

```magma
> A := OctonionAlgebra(Rationals(), -1, -1, -1);
> t := Tensor(A);
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 8 over Rational Field
U1 : Full Vector space of degree 8 over Rational Field
U0 : Full Vector space of degree 8 over Rational Field
> H_gens := [A.i : i in [1..4]];
> t2 := Subtensor(t, [*H_gens, H_gens, H_gens*]);
> s := Subtensor(t, [* A.2, [A.1, A.4], A!0 *]);
> s;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Vector space of degree 8, dimension 1 over Rational Field
Generators:
(0 1 0 0 0 0 0 0)
Echelonized basis:
(0 1 0 0 0 0 0 0)
U1 : Vector space of degree 8, dimension 2 over Rational Field
Generators:
(1 0 0 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
Echelonized basis:
(1 0 0 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
U0 : Vector space of degree 8, dimension 2 over Rational Field
Generators:
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
Echelonized basis:
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)

```

The quaternions are a subalgebra of $A$ generated by $\{A_1,A_2,A_3,A_4\}$. Therefore, the $\{2\}$-local ideal of $s$ in $t$ must contain $A$ in the codomain. However, the $\{2\}$-local ideal of $s$ in $t_2$ must only contain $\langle A_1, A_2, A_3, A_4\}$ in the codomain.

```magma
> s1 := LocalIdeal(t, s, {2});
> Codomain(s1);
Full Vector space of degree 8 over Rational Field
Generators:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
(0 0 0 0 1 0 0 0)
(0 0 0 0 0 1 0 0)
(0 0 0 0 0 0 1 0)
(0 0 0 0 0 0 0 1)
> s2 := LocalIdeal(t2, s, {2});
> Codomain(s2);
Vector space of degree 8, dimension 4 over Rational Field
Generators:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)
Echelonized basis:
(1 0 0 0 0 0 0 0)
(0 1 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0)
(0 0 0 1 0 0 0 0)

```

#### `Ideal(T, S): TenSpcElt, List -> TenSpcElt`

#### `Ideal(T, S): TenSpcElt, SeqEnum -> TenSpcElt`

Returns the ideal of $T$ containing $S$.

#### `Ideal(T, D, C): TenSpcElt, List, Any -> TenSpcElt`

#### `Ideal(T, D, C): TenSpcElt, SeqEnum, Any -> TenSpcElt`

Returns the ideal of $T$ containing $D$ in the domain and $C$ in the codomain.

#### `Ideal(T, S): TenSpcElt, TenSpcElt -> TenSpcElt`

Returns the ideal of $T$ containing $S$ as a submap.

#### `IsIdeal(T, S): TenSpcElt, TenSpcElt -> BoolElt`

Decides if $S$ is an ideal of $T$.

#### `Example: Ideals (ex-fad333)`

First we will construct the tensor from the ${\mathbb{Q}}$-algebra, ${\mathbb{Q}}^5$.

```magma
> T := KTensorSpace(Rationals(), [5,5,5]);
> A := VectorSpace(Rationals(), 5);
> t := T!0;
> for i in [1..5] do
>   Assign(~t, [i,i,i], 1);
> end for;
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 5 over Rational Field
U1 : Full Vector space of degree 5 over Rational Field
U0 : Full Vector space of degree 5 over Rational Field
> SystemOfForms(t);
[
    [1 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0],

    [0 0 0 0 0]
    [0 1 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0],

    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 1 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0],

    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 1 0]
    [0 0 0 0 0],

    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 0]
    [0 0 0 0 1]
]

```

Now we will construct the ideal tensor from the subtensor containing $\langle A_1\rangle \times \langle A_2\rangle \rightarrowtail \langle A_3\rangle$. Note that the $\{2\}$-local ideal must include $\langle A_2,A_3\rangle$ in the codomain, and the $\{1\}$-local ideal must contain $\langle A_1,A_3\rangle$ in the codomain.

```magma
> s := Ideal(t, [A.1, A.2, A.3]);
> s;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Vector space of degree 5, dimension 1 over Rational Field
Generators:
(1 0 0 0 0)
Echelonized basis:
(1 0 0 0 0)
U1 : Vector space of degree 5, dimension 1 over Rational Field
Generators:
(0 1 0 0 0)
Echelonized basis:
(0 1 0 0 0)
U0 : Vector space of degree 5, dimension 3 over Rational Field
Generators:
(1 0 0 0 0)
(0 1 0 0 0)
(0 0 1 0 0)
Echelonized basis:
(1 0 0 0 0)
(0 1 0 0 0)
(0 0 1 0 0)

```

Finally, we verify that the subtensor containing $\langle A_1\rangle \times \langle A_2\rangle \rightarrowtail \langle A_2, A_3\rangle$ is not an ideal.

```magma
> r := Subtensor(t, [A.1, A.2], [A.2, A.3]);
> IsIdeal(t, r);
false

```

#### `LocalQuotient(T, S, I : parameters): TenSpcElt, TenSpcElt, {RngIntElt} -> TenSpcElt, Hmtp`

```magma
Check: BoolElt                    Default: true
```

Returns the local quotient of $T$ by $S$ at $I\subseteq[\nu]-0$. If you know $S$ is a local ideal of $T$ at $I$, set `Check` to `false` to skip the verification. A homotopism is also returned, mapping from $T$ to $T/S$.

#### `Quotient(T, S : parameters): TenSpcElt, TenSpcElt -> TenSpcElt, Hmtp`

#### `T / S: TenSpcElt, TenSpcElt -> TenSpcElt, Hmtp`

```magma
Check: BoolElt                    Default: true
```

Returns the quotient of $T$ by $S$. If you know $S$ is an ideal of $T$, set `Check` to `false` to skip the verification. A homotopism is also returned, mapping from $T$ to $T/S$.

#### `Example: Quotients (ex-0f6850)`

We will demonstrate one of the most common uses for quotienting tensors: constructing the associated fully nondegenerate tensor. We first construct a tensor with a nontrivial radical given by matrix multiplication: $\rm{Mat}_{3\times 2}({\mathbb{Q}})\times {\mathbb{Q}}^3\rightarrowtail {\mathbb{Q}}^3$, where we take a projection of ${\mathbb{Q}}^3$ onto ${\mathbb{Q}}^2$ in the 1 coordinate.

```magma
> K := Rationals();
> F := [*KMatrixSpace(K, 3, 2), VectorSpace(K, 3), VectorSpace(K, 3)*];
> mult := function(x)
>   return Transpose(x[1]*Matrix(2, 1, Eltseq(x[2])[2..3]));
> end function;
> t := Tensor(F, mult);
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 6 over Rational Field
U1 : Full Vector space of degree 3 over Rational Field
U0 : Full Vector space of degree 3 over Rational Field
> s := Subtensor(t, [*[F[1].1, F[1].4], F[2], F[3]*]);
> s;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Vector space of degree 6, dimension 2 over Rational Field
Generators:
(1 0 0 0 0 0)
(0 0 0 1 0 0)
Echelonized basis:
(1 0 0 0 0 0)
(0 0 0 1 0 0)
U1 : Full Vector space of degree 3 over Rational Field
Generators:
(1 0 0)
(0 1 0)
(0 0 1)
U0 : Full Vector space of degree 3 over Rational Field
Generators:
(1 0 0)
(0 1 0)
(0 0 1)
> IsFullyNondegenerate(s);
false

```

Now we will construct the ideal $r$ that evaluates to 0 and the largest subspace of ${\mathbb{Q}}^3$ not contained in the image.

```magma
> r := Ideal(t, [*F[1]!0, F[2].1, F[3].3*]);
> r;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Vector space of degree 6, dimension 0 over Rational Field
Generators:

U1 : Vector space of degree 3, dimension 1 over Rational Field
Generators:
(1 0 0)
Echelonized basis:
(1 0 0)
U0 : Vector space of degree 3, dimension 1 over Rational Field
Generators:
(0 0 1)
Echelonized basis:
(0 0 1)
> IsIdeal(t, r);
true

```

Finally, we quotient $s$ by $r$ to obtain a fully nondegenerate tensor.

```magma
> q := s/r;
> q;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 2 over Rational Field
U1 : Full Vector space of degree 2 over Rational Field
U0 : Full Vector space of degree 2 over Rational Field
> IsFullyNondegenerate(q);
true

```

### Categorical Operations on Tensor Spaces

We have categorical notions for tensor spaces as well, and these are inherited from the module structure on tensor spaces.

#### `SubConstructor(T, L): TenSpc, Any -> TenSpc, Map`

#### `sub< T | L >: TenSpc, Any -> TenSpc, Map`

Returns the subtensor space of $T$ generated by the tensors in the sequence $L$.

#### `IsSubtensorSpace(T, S): TenSpc, TenSpc -> BoolElt`

Decides if the tensor space $S$ is a subtensor space of $T$.

#### `Example: Subtensor Spaces (ex-40cd43)`

We will construct the subspace $S$ of symmetric forms from the tensor space $T$ with frame ${\mathbb{Q}}^2\times{\mathbb{Q}}^2\rightarrowtail {\mathbb{Q}}$.

```magma
> K := Rationals();
> T := KTensorSpace(K, [2,2,1]);
> T;
Tensor space of dimension 4 over Rational Field with valence 3
U2 : Full Vector space of degree 2 over Rational Field
U1 : Full Vector space of degree 2 over Rational Field
U0 : Full Vector space of degree 1 over Rational Field
> S := sub< T | T.1, T.2+T.3, T.4 >;
> S;
Tensor space of dimension 3 over Rational Field with valence 3
U2 : Full Vector space of degree 2 over Rational Field
U1 : Full Vector space of degree 2 over Rational Field
U0 : Full Vector space of degree 1 over Rational Field
> IsSymmetric(S);
true

```

Now we will construct the subspace $A$ of alternating forms from $T$.

```magma
> A := sub< T | T.2-T.3 >;
> A;
Tensor space of dimension 1 over Rational Field with valence 3
U2 : Full Vector space of degree 2 over Rational Field
U1 : Full Vector space of degree 2 over Rational Field
U0 : Full Vector space of degree 1 over Rational Field
> IsAlternating(A);
true

```

Now we verify that $A$ is not a subtensor space of $S$, and thus, we have constructed a direct decomposition of $T$ into its symmetric and alternating space.

```magma
> IsSubtensorSpace(S, A);
false

```

#### `QuoConstructor(T, X): TenSpc, Any -> TenSpc, Map`

#### `quo< T | X >: TenSpc, Any -> TenSpc, Map`

#### `T / S: TenSpc, TenSpc -> TenSpc, Map`

Returns the quotient tensor space of $T$ by $S$.

#### `Example: Quotient Tensor Spaces (ex-87c8de)`

We pick up with the same tensor spaces as the previous example: $T$ has frame ${\mathbb{Q}}^2\times{\mathbb{Q}}^2\rightarrowtail {\mathbb{Q}}$, $S$ is the symmetric subspace, and $A$ is the alternating subspace.

```magma
> K := Rationals();
> T := KTensorSpace(K, [2,2,1]);
> T;
Tensor space of dimension 4 over Rational Field with valence 3
U2 : Full Vector space of degree 2 over Rational Field
U1 : Full Vector space of degree 2 over Rational Field
U0 : Full Vector space of degree 1 over Rational Field
> S := sub< T | T.1, T.2+T.3, T.4 >;
> A := sub< T | T.2-T.3 >;

```

Now we construct the quotient of $T$ by $A$. The result is not a symmetric tensor space. Note that $Q_2$ is equivalent to a symmetric tensor modulo $A$, but this choice is arbitrary.

```magma
> Q := T/A;
> Q;
Tensor space of dimension 3 over Rational Field with valence 3
U2 : Full Vector space of degree 2 over Rational Field
U1 : Full Vector space of degree 2 over Rational Field
U0 : Full Vector space of degree 1 over Rational Field
> SystemOfForms(Q.1);
[
    [1 0]
    [0 0]
]
> SystemOfForms(Q.2);
[
    [0 0]
    [1 0]
]
> SystemOfForms(Q.3);
[
    [0 0]
    [0 1]
]

```

## Homotopisms

Magma provides functions for homotopisms, i.e. morphisms of tensors. Homotopisms are also equipped with a tensor category. Because homotopisms can contain multiple maps between modules, it is not really clear what is meant by the domain or codomain of a given homotopism. In this context, the *domain* of a homotopism $H$ will refer to the tensor, $t:U_{\nu}\times \cdots \times U_1\rightarrowtail U_0$, where an arrow equal to $1$ at coordinate $a$ will mean that the corresponding map at coordinate $a$ has domain equal to $U_a$. And in the same vain, the tensor $s:V_{\nu} \times\cdots \times V_1\rightarrowtail V_0$ is the *codomain* of $H$ if an arrow equal to $1$ at coordinate $a$ implies that the corresponding map at coordinate $a$ has codomain equal to $V_a$.

### Constructions of Homotopisms

#### `Homotopism(T, S, M : parameters): TenSpcElt, TenSpcElt, List -> Hmtp`

#### `Homotopism(T, S, M : parameters): TenSpcElt, TenSpcElt, SeqEnum -> Hmtp`

#### `Homotopism(T, S, M, C : parameters): TenSpcElt, TenSpcElt, List, TenCat -> Hmtp`

#### `Homotopism(T, S, M, C : parameters): TenSpcElt, TenSpcElt, SeqEnum, TenCat -> Hmtp`

```magma
Check: BoolElt                    Default: true
```

```magma
Check: BoolElt                    Default: true
```

Returns the homotopism from $T$ to $S$ given by the list of maps $M$ and the category $C$. The default tensor category is the same as tensor categories for $T$ and $S$. If the maps $M$ will produce a homotopism, then set `Check` to `false` to skip the verification.

#### `Homotopism(M, C): List, TenCat -> Hmtp`

#### `Homotopism(M, C): SeqEnum, TenCat -> Hmtp`

Returns the homotopism given by the maps in $M$ with tensor category $C$.

#### `IsHomotopism(T, s, H): TenSpcElt, TenSpcElt, Hmtp -> BoolElt`

#### `IsHomotopism(T, s, M): TenSpcElt, TenSpcElt, List -> BoolElt`

#### `IsHomotopism(T, s, M): TenSpcElt, TenSpcElt, SeqEnum -> BoolElt`

#### `IsHomotopism(T, s, M, C): TenSpcElt, TenSpcElt, List, TenCat -> BoolElt`

#### `IsHomotopism(T, s, M, C): TenSpcElt, TenSpcElt, SeqEnum, TenCat -> BoolElt`

Decides if the list of maps $M$ induces a homotopism from $T$ to $S$ in the tensor category $C$. The default tensor category is the homotopism category. If it does induce a homotopism, it is also returned.

#### `Example: Homotopism Const (ex-6fd856)`

We will construct two symmetric tensors $t,s: {\bf F}_{3}^3 \times {\bf F}_{3}^3 \rightarrowtail {\bf F}_{3}^3$ and apply permutations to the bases.

```magma
> T := KTensorSpace(GF(3), [3,3,3]);
> t := T.1+T.14+T.27;
> SystemOfForms(t);
[
    [1 0 0]
    [0 0 0]
    [0 0 0],

    [0 0 0]
    [0 1 0]
    [0 0 0],

    [0 0 0]
    [0 0 0]
    [0 0 1]
]
> s := (T.4+T.10)+(T.8+T.20)+(T.18+T.24);
> SystemOfForms(s);
[
    [0 1 0]
    [1 0 0]
    [0 0 0],

    [0 0 1]
    [0 0 0]
    [1 0 0],

    [0 0 0]
    [0 0 1]
    [0 1 0]
]

```

Now we construct a homotopism from $t$ to $t$ given by apply a permutation matrix in every coordinate.

```magma
> P := PermutationMatrix(GF(3), [2,1,3]);
> H := Homotopism(t, t, [*P, P, P*]);
> H;
Maps from U2 x U1 >-> U0 to V2 x V1 >-> V0.
U2 -> V2:
[0 1 0]
[1 0 0]
[0 0 1]
U1 -> V1:
[0 1 0]
[1 0 0]
[0 0 1]
U0 -> V0:
[0 1 0]
[1 0 0]
[0 0 1]

```

Note that this permutation matrix does not induce a homotopism of $s$.

```magma
> IsHomotopism(s, s, [*P, P, P*]);
false

```

#### `Example: Mixed Homotopisms (ex-d02f12)`

Homotopisms can take mixed categories of maps. To reuse the above example, we can encode the permutation as a `Map` and construct homotopisms from these types.

```magma
> V := VectorSpace(GF(3), 3);
> T := TensorSpace([V, V, V]);
> t := T.1+T.14+T.27;
> P := PermutationMatrix(GF(3), [2,1,3]);
> f := hom< V -> V | [<V.1, V.2>, <V.2, V.1>, <V.3, V.3>] >;
> H := Homotopism(t, t, [*f, f, f*]);
> H;
Maps from U2 x U1 >-> U0 to V2 x V1 >-> V0.
U2 -> V2: Mapping from: Full Vector space of degree 3 over GF(3) to Full
Vector space of degree 3 over GF(3)
U1 -> V1: Mapping from: Full Vector space of degree 3 over GF(3) to Full
Vector space of degree 3 over GF(3)
U0 -> V0: Mapping from: Full Vector space of degree 3 over GF(3) to Full
Vector space of degree 3 over GF(3)

```

Furthermore, we can input lists with types `Mtrx` and `Map` included.

```magma
> H2 := Homotopism(t, t, [*P, f, P*]);
> H2;
Maps from U2 x U1 >-> U0 to V2 x V1 >-> V0.
U2 -> V2:
[0 1 0]
[1 0 0]
[0 0 1]
U1 -> V1: Mapping from: Full Vector space of degree 3 over GF(3) to Full
Vector space of degree 3 over GF(3)
U0 -> V0:
[0 1 0]
[1 0 0]
[0 0 1]

```

### Basic Operations with Homotopisms

We provide some operations for homotopisms.

#### `H1 * H2: Hmtp, Hmtp -> Hmtp`

Returns the composition of the homotopisms $H_1$ and $H_2$.

#### `H . a: Hmtp, RngIntElt -> Map`

Returns the map on the $a$th coordinate.

#### `Example: Homotopism Ops (ex-c4051c)`

We construct a nondegenerate alternating form $t$ on $V={\mathbb{Q}}^6$. The group of isometries are isomorphic to $\rm{Sp}(6, {\mathbb{Q}})$, the group generated by all transvections. We construct a transvection $L$ and a corresponding matrix.

```magma
> V := VectorSpace(Rationals(), 6);
> T := KTensorSpace(Rationals(), [6, 6, 1]);
> t := T.2-T.7+T.16-T.21+T.30-T.35;
> t;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 6 over Rational Field
U1 : Full Vector space of degree 6 over Rational Field
U0 : Full Vector space of degree 1 over Rational Field
>
> u := V.2+2*V.3-V.5;
> L := map< V -> V | x :-> x + (x*t*u)[1]*u >;
> L;
Mapping from: ModTupFld: V to ModTupFld: V given by a rule [no inverse]
> M := Matrix(6, 6, [V.i @ L : i in [1..6]]);
> M;
[ 1  1  2  0 -1  0]
[ 0  1  0  0  0  0]
[ 0  0  1  0  0  0]
[ 0 -2 -4  1  2  0]
[ 0  0  0  0  1  0]
[ 0  1  2  0 -1  1]

```

We construct a homotopism from the transvection.

```magma
> H := Homotopism(t, t, [*L, L, IdentityMatrix(Rationals(), 1)*]);
> H;
Maps from U2 x U1 >-> U0 to V2 x V1 >-> V0.
U2 -> V2: Mapping from: Full Vector space of degree 6 over Rational Field to
Full Vector space of degree 6 over Rational Field given by a rule [no inverse]
U1 -> V1: Mapping from: Full Vector space of degree 6 over Rational Field to
Full Vector space of degree 6 over Rational Field given by a rule [no inverse]
U0 -> V0:
[1]

```

Since $H$ is an isometry of $t$, $H^2$ is also an isometry of $t$. We verify that the 2-coordinate map of $H^2$ is exactly $M^2$.

```magma
> H2 := H*H;
> H2;
Maps from U2 x U1 >-> U0 to V2 x V1 >-> V0.
U2 -> V2: Mapping from: Full Vector space of degree 6 over Rational Field to
Full Vector space of degree 6 over Rational Field
Composition of Mapping from: Full Vector space of degree 6 over Rational Field
to Full Vector space of degree 6 over Rational Field given by a rule [no
inverse] and
Mapping from: Full Vector space of degree 6 over Rational Field to Full Vector
space of degree 6 over Rational Field given by a rule [no inverse]
U1 -> V1: Mapping from: Full Vector space of degree 6 over Rational Field to
Full Vector space of degree 6 over Rational Field
Composition of Mapping from: Full Vector space of degree 6 over Rational Field
to Full Vector space of degree 6 over Rational Field given by a rule [no
inverse] and
Mapping from: Full Vector space of degree 6 over Rational Field to Full Vector
space of degree 6 over Rational Field given by a rule [no inverse]
U0 -> V0:
[1]
> M2 := Matrix(6, 6, [V.i @ H2.2 : i in [1..6]]);
> M2;
[ 1  2  4  0 -2  0]
[ 0  1  0  0  0  0]
[ 0  0  1  0  0  0]
[ 0 -4 -8  1  4  0]
[ 0  0  0  0  1  0]
[ 0  2  4  0 -2  1]
> M^2 eq M2;
true

```

#### `Precompose(T, f, a): TenSpcElt, Map, RngIntElt -> TenSpcElt`

#### `Precompose(T, M, a): TenSpcElt, Mtrx, RngIntElt -> TenSpcElt`

If $a>0$, then the tensor returned is the tensor that has been pre-composed by the map $f$ or matrix $M$.

#### `T @ H: TenSpcElt, Hmtp -> TenSpcElt`

If $H$ is a cohomotopism (a homotopism in the cohomotopism category), then either the domain or codomain of $H$ is returned, depending on the orientation of the arrows of $H$.

### Basic Properties of Homotopisms

#### `Domain(H): Hmtp -> TenSpcElt`

Returns the domain tensor of $H$.

#### `Codomain(H): Hmtp -> TenSpcElt`

Returns the codomain tensor of $H$.

#### `Maps(H): Hmtp -> List`

Returns the list of maps for the various modules in the domain and codomain tensors.

#### `TensorCategory(H): Hmtp -> TenCat`

Returns the tensor category of $H$.

#### `ChangeTensorCategory(H, C): Hmtp, TenCat -> Hmtp`

#### `ChangeTensorCategory(~H, C): Hmtp, TenCat`

Changes the tensor category of $H$ to the given category.

#### `Valence(H): Hmtp -> RngIntElt`

Returns the valence of the underlying tensor category of the homotopism $H$.

#### `Kernel(H): Hmtp -> TenSpcElt`

Returns the kernel of $H$ as an ideal of its domain tensor.

#### `Image(H): Hmtp -> TenSpcElt`

Returns the image of $H$ as a submap of the codomain tensor.

#### `Example: Homotopism Props (ex-5a1efc)`

We demonstrate how to access properties of a homotopism. We construct tensors $t:{\mathbb{Q}}^4\times{\mathbb{Q}}^4\rightarrowtail {\mathbb{Q}}$ and $s:{\mathbb{Q}}^6\times{\mathbb{Q}}^6\rightarrowtail{\mathbb{Q}}$ given by the dot product.

```magma
> t := Tensor(IdentityMatrix(Rationals(), 4), 2, 1);
> s := Tensor(IdentityMatrix(Rationals(), 6), 2, 1);
> Z := ZeroMatrix(Rationals(), 4, 6);
> M := InsertBlock(Z, IdentityMatrix(Rationals(), 4), 1, 1);
> H := Homotopism(t, s, [*M, M, IdentityMatrix(Rationals(), 1)*]);
> H;
Maps from U2 x U1 >-> U0 to V2 x V1 >-> V0.
U2 -> V2:
[1 0 0 0 0 0]
[0 1 0 0 0 0]
[0 0 1 0 0 0]
[0 0 0 1 0 0]
U1 -> V1:
[1 0 0 0 0 0]
[0 1 0 0 0 0]
[0 0 1 0 0 0]
[0 0 0 1 0 0]
U0 -> V0:
[1]

```

Like with maps, we can obtain standard properties of homotopisms.

```magma
> Domain(H);
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 4 over Rational Field
U1 : Full Vector space of degree 4 over Rational Field
U0 : Full Vector space of degree 1 over Rational Field
> Codomain(H);
Tensor of valence 3, U2 x U1 >-> U0
U2 : Full Vector space of degree 6 over Rational Field
U1 : Full Vector space of degree 6 over Rational Field
U0 : Full Vector space of degree 1 over Rational Field
> Maps(H);
[*
    [1 0 0 0 0 0]
    [0 1 0 0 0 0]
    [0 0 1 0 0 0]
    [0 0 0 1 0 0],

    [1 0 0 0 0 0]
    [0 1 0 0 0 0]
    [0 0 1 0 0 0]
    [0 0 0 1 0 0],

    [1]
*]
> TensorCategory(H);
Tensor category of valence 3 (->,->,->) ({ 1 },{ 2 },{ 0 })

```

When the image and kernel can be computed for the each of the maps in the homotopism, then the image and kernel can be computed for the homotopism.

```magma
> Im := Image(H);
> Im;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Vector space of degree 6, dimension 4 over Rational Field
Echelonized basis:
(1 0 0 0 0 0)
(0 1 0 0 0 0)
(0 0 1 0 0 0)
(0 0 0 1 0 0)
U1 : Vector space of degree 6, dimension 4 over Rational Field
Echelonized basis:
(1 0 0 0 0 0)
(0 1 0 0 0 0)
(0 0 1 0 0 0)
(0 0 0 1 0 0)
U0 : Full Vector space of degree 1 over Rational Field
> Ker := Kernel(H);
> Ker;
Tensor of valence 3, U2 x U1 >-> U0
U2 : Vector space of degree 4, dimension 0 over Rational Field
U1 : Vector space of degree 4, dimension 0 over Rational Field
U0 : Vector space of degree 1, dimension 0 over Rational Field

```

#### `Shuffle(H, g): Hmtp, GrpPermElt -> Hmtp`

#### `Shuffle(H, g): Hmtp, [RngIntElt] -> Hmtp`

Just like the shuffle for tensors, this returns the shuffle of the homotopism $H$. This is a functor from one tensor category to another and changes the order of the maps to

$$
\{H_{\nu^g},\dots, H_{1^g}, H_{0^g}\}.
$$

In order to be defined, $g\in{\operatorname{Sym}}(\{0,\dots,\nu \})$. If $0^g\ne 0$, then both the image and pre-image of $0$ under $g$ will be replaced by their $K$-dual space. For cotensors, $g\in{\operatorname{Sym}}(\{1,\dots,\nu\})$. Sequences $[a_1,\dots,a_{\nu+1}]$ will be interpreted as a permutation in one-line notation.
