# Finite dimensional free algebra quotients#

REMARK:

This implementation only works for finite dimensional quotients, since a list of basis monomials and the multiplication matrices need to be explicitly provided.

The homogeneous part of a quotient of a free algebra over a field by a finitely generated homogeneous twosided ideal is available in a different implementation. See `free_algebra_letterplace` and `quotient_ring`.

class sage.algebras.free_algebra_quotient.FreeAlgebraQuotient(A, mons, mats, names)[source]#

Return a quotient algebra defined via the action of a free algebra A on a (finitely generated) free module.

The input for the quotient algebra is a list of monomials (in the underlying monoid for A) which form a free basis for the module of A, and a list of matrices, which give the action of the free generators of A on this monomial basis.

EXAMPLES:

Quaternion algebra defined in terms of three generators:

```sage: n = 3
sage: A = FreeAlgebra(QQ,n,'i')
sage: F = A.monoid()
sage: i, j, k = F.gens()
sage: mons = [F(1), i, j, k]
sage: M = MatrixSpace(QQ,4)
sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]),
....:         M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]),
....:         M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ]
sage: H3.<i,j,k> = FreeAlgebraQuotient(A,mons,mats)
sage: x = 1 + i + j + k
sage: x
1 + i + j + k
sage: x**128
-170141183460469231731687303715884105728
+ 170141183460469231731687303715884105728*i
+ 170141183460469231731687303715884105728*j
+ 170141183460469231731687303715884105728*k
```
```>>> from sage.all import *
>>> n = Integer(3)
>>> A = FreeAlgebra(QQ,n,'i')
>>> F = A.monoid()
>>> i, j, k = F.gens()
>>> mons = [F(Integer(1)), i, j, k]
>>> M = MatrixSpace(QQ,Integer(4))
>>> mats = [M([Integer(0),Integer(1),Integer(0),Integer(0), -Integer(1),Integer(0),Integer(0),Integer(0), Integer(0),Integer(0),Integer(0),-Integer(1), Integer(0),Integer(0),Integer(1),Integer(0)]),
...         M([Integer(0),Integer(0),Integer(1),Integer(0), Integer(0),Integer(0),Integer(0),Integer(1), -Integer(1),Integer(0),Integer(0),Integer(0), Integer(0),-Integer(1),Integer(0),Integer(0)]),
...         M([Integer(0),Integer(0),Integer(0),Integer(1), Integer(0),Integer(0),-Integer(1),Integer(0), Integer(0),Integer(1),Integer(0),Integer(0), -Integer(1),Integer(0),Integer(0),Integer(0)]) ]
>>> H3 = FreeAlgebraQuotient(A,mons,mats, names=('i', 'j', 'k',)); (i, j, k,) = H3._first_ngens(3)
>>> x = Integer(1) + i + j + k
>>> x
1 + i + j + k
>>> x**Integer(128)
-170141183460469231731687303715884105728
+ 170141183460469231731687303715884105728*i
+ 170141183460469231731687303715884105728*j
+ 170141183460469231731687303715884105728*k
```

Same algebra defined in terms of two generators, with some penalty on already slow arithmetic.

```sage: n = 2
sage: A = FreeAlgebra(QQ,n,'x')
sage: F = A.monoid()
sage: i, j = F.gens()
sage: mons = [ F(1), i, j, i*j ]
sage: r = len(mons)
sage: M = MatrixSpace(QQ,r)
sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]),
....:         M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]) ]
sage: H2.<i,j> = A.quotient(mons,mats)
sage: k = i*j
sage: x = 1 + i + j + k
sage: x
1 + i + j + i*j
sage: x**128
-170141183460469231731687303715884105728
+ 170141183460469231731687303715884105728*i
+ 170141183460469231731687303715884105728*j
+ 170141183460469231731687303715884105728*i*j
```
```>>> from sage.all import *
>>> n = Integer(2)
>>> A = FreeAlgebra(QQ,n,'x')
>>> F = A.monoid()
>>> i, j = F.gens()
>>> mons = [ F(Integer(1)), i, j, i*j ]
>>> r = len(mons)
>>> M = MatrixSpace(QQ,r)
>>> mats = [M([Integer(0),Integer(1),Integer(0),Integer(0), -Integer(1),Integer(0),Integer(0),Integer(0), Integer(0),Integer(0),Integer(0),-Integer(1), Integer(0),Integer(0),Integer(1),Integer(0)]),
...         M([Integer(0),Integer(0),Integer(1),Integer(0), Integer(0),Integer(0),Integer(0),Integer(1), -Integer(1),Integer(0),Integer(0),Integer(0), Integer(0),-Integer(1),Integer(0),Integer(0)]) ]
>>> H2 = A.quotient(mons,mats, names=('i', 'j',)); (i, j,) = H2._first_ngens(2)
>>> k = i*j
>>> x = Integer(1) + i + j + k
>>> x
1 + i + j + i*j
>>> x**Integer(128)
-170141183460469231731687303715884105728
+ 170141183460469231731687303715884105728*i
+ 170141183460469231731687303715884105728*j
+ 170141183460469231731687303715884105728*i*j
```
Element[source]#
dimension()[source]#

Return the rank of the algebra (as a free module).

EXAMPLES:

```sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].dimension()
4
```
```>>> from sage.all import *
>>> sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[Integer(0)].dimension()
4
```
free_algebra()[source]#

Return the free algebra generating the algebra.

EXAMPLES:

```sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].free_algebra()
Free Algebra on 3 generators (i0, i1, i2) over Rational Field
```
```>>> from sage.all import *
>>> sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[Integer(0)].free_algebra()
Free Algebra on 3 generators (i0, i1, i2) over Rational Field
```
gen(i)[source]#

Return the `i`-th generator of the algebra.

EXAMPLES:

```sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
sage: H.gen(0)
i
sage: H.gen(2)
k
```
```>>> from sage.all import *
>>> H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
>>> H.gen(Integer(0))
i
>>> H.gen(Integer(2))
k
```

An `IndexError` is raised if an invalid generator is requested:

```sage: H.gen(3)
Traceback (most recent call last):
...
IndexError: argument i (= 3) must be between 0 and 2
```
```>>> from sage.all import *
>>> H.gen(Integer(3))
Traceback (most recent call last):
...
IndexError: argument i (= 3) must be between 0 and 2
```

Negative indexing into the generators is not supported:

```sage: H.gen(-1)
Traceback (most recent call last):
...
IndexError: argument i (= -1) must be between 0 and 2
```
```>>> from sage.all import *
>>> H.gen(-Integer(1))
Traceback (most recent call last):
...
IndexError: argument i (= -1) must be between 0 and 2
```
gens()[source]#

Return the tuple of generators of `self`.

EXAMPLES:

```sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
sage: H.gens()
(i, j, k)
```
```>>> from sage.all import *
>>> H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)
>>> H.gens()
(i, j, k)
```
matrix_action()[source]#

Return the matrix action used to define the algebra.

EXAMPLES:

```sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].matrix_action()
(
[ 0  1  0  0]  [ 0  0  1  0]  [ 0  0  0  1]
[-1  0  0  0]  [ 0  0  0  1]  [ 0  0 -1  0]
[ 0  0  0 -1]  [-1  0  0  0]  [ 0  1  0  0]
[ 0  0  1  0], [ 0 -1  0  0], [-1  0  0  0]
)
```
```>>> from sage.all import *
>>> sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[Integer(0)].matrix_action()
(
[ 0  1  0  0]  [ 0  0  1  0]  [ 0  0  0  1]
[-1  0  0  0]  [ 0  0  0  1]  [ 0  0 -1  0]
[ 0  0  0 -1]  [-1  0  0  0]  [ 0  1  0  0]
[ 0  0  1  0], [ 0 -1  0  0], [-1  0  0  0]
)
```
module()[source]#

Return the free module of the algebra.

EXAMPLES:

```sage: H = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0]; H
Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field
sage: H.module()
Vector space of dimension 4 over Rational Field
```
```>>> from sage.all import *
>>> H = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[Integer(0)]; H
Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field
>>> H.module()
Vector space of dimension 4 over Rational Field
```
monoid()[source]#

Return the free monoid of generators of the algebra.

EXAMPLES:

```sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monoid()
Free monoid on 3 generators (i0, i1, i2)
```
```>>> from sage.all import *
>>> sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[Integer(0)].monoid()
Free monoid on 3 generators (i0, i1, i2)
```
monomial_basis()[source]#

The free monoid of generators of the algebra as elements of a free monoid.

EXAMPLES:

```sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].monomial_basis()
(1, i0, i1, i2)
```
```>>> from sage.all import *
>>> sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[Integer(0)].monomial_basis()
(1, i0, i1, i2)
```
ngens()[source]#

Return the number of generators of the algebra.

EXAMPLES:

```sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].ngens()
3
```
```>>> from sage.all import *
>>> sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[Integer(0)].ngens()
3
```
rank()[source]#

Return the rank of the algebra (as a free module).

EXAMPLES:

```sage: sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[0].rank()
4
```
```>>> from sage.all import *
>>> sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ)[Integer(0)].rank()
4
```
sage.algebras.free_algebra_quotient.hamilton_quatalg(R)[source]#

Hamilton quaternion algebra over the commutative ring `R`, constructed as a free algebra quotient.

INPUT:

• `R` – a commutative ring

OUTPUT:

• `Q` – quaternion algebra

• `gens` – generators for `Q`

EXAMPLES:

```sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)
sage: H
Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4
over Integer Ring
sage: i^2
-1
sage: i in H
True
```
```>>> from sage.all import *
>>> H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ)
>>> H
Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4
over Integer Ring
>>> i**Integer(2)
-1
>>> i in H
True
```

Note that there is another vastly more efficient model for quaternion algebras in Sage; the one here is mainly for testing purposes:

```sage: R.<i,j,k> = QuaternionAlgebra(QQ,-1,-1)  # much fast than the above
```
```>>> from sage.all import *
>>> R = QuaternionAlgebra(QQ,-Integer(1),-Integer(1), names=('i', 'j', 'k',)); (i, j, k,) = R._first_ngens(3)# much fast than the above
```