# Generic matrix algebras

AbstractAlgebra.jl allows the creation of an algebra (ring) of $m\times m$ matrices over a computable, commutative ring.

Functions specific to generic matrix algebras of $m\times m$ matrices are implemented in `src/generic/MatRing.jl`

. The remaining functionality is in the file `src/generic/Matrix.jl`

.

As well as implementing the entire Matrix interface, including the optional functionality, there are many additional generic algorithms implemented for matrix algebras.

Almost all of the functionality specified for generic matrices is available for matrix algebras. The exceptions are functions such as `solve`

and `nullspace`

which may return non-square matrices, or which don't accept square matrices.

All of the generic functionality is part of the Generic submodule of AbstractAlgebra.jl. This is exported by default, so it is not necessary to qualify names of functions.

## Types and parent objects

Generic matrices in AbstractAlgebra.jl have type `Generic.MatRingElem{T}`

for matrices in a matrix algebra, where `T`

is the type of elements of the matrix. Internally, generic matrices are implemented using an object wrapping a Julia two dimensional array, though they are not themselves Julia arrays. See the file `src/generic/GenericTypes.jl`

for details.

Parents of generic matrices in a matrix algebra have type `Generic.MatRing{T}`

.

Note that matrix algebras are noncommutative rings. Thus their types belong to `NCRing`

and `NCRingElem`

. They cannot be used in constructions which require a commutative ring (`Ring`

and `RingElem`

respectively).

The generic matrix algebra matrix types belong to the abstract type `MatRingElem{T}`

and the parent types belong to `MatRing{T}`

Note that both of these require disambiguation from the concrete types in `Generic`

of the same name.

The degree and base ring $R$ of a generic matrix are stored in its parent object, however to allow creation of matrices without first creating the matrix space parent, generic matrices in Julia do not contain a reference to their parent. They contain the row and column numbers (or degree, in the case of matrix algebras) and the base ring on a per matrix basis. The parent object can then be reconstructed from this data on demand.

## Matrix algebra constructors

A matrix algebra in AbstractAlgebra.jl represents a collection of all matrices with given degree and base ring.

In order to construct matrices in AbstractAlgebra.jl, one must construct the matrix algebra itself. This is accomplished with the following constructor.

`matrix_ring(R::Ring, degree::Int)`

Construct the algebra of matrices with the given degree over the given base ring.

Here are some examples of creating matrix algebras and making use of the resulting parent objects to coerce various elements into the matrix algebra.

**Examples**

```
julia> R, t = polynomial_ring(QQ, "t")
(Univariate polynomial ring in t over rationals, t)
julia> S = matrix_ring(R, 3)
Matrix ring of degree 3
over univariate polynomial ring in t over rationals
julia> A = S()
[0 0 0]
[0 0 0]
[0 0 0]
julia> B = S(12)
[12 0 0]
[ 0 12 0]
[ 0 0 12]
julia> C = S(R(11))
[11 0 0]
[ 0 11 0]
[ 0 0 11]
```

## Matrix algebra element constructors

The following additional constructors are provided for constructing various kinds of matrices in a matrix algebra.

`AbstractAlgebra.identity_matrix`

— Method`identity_matrix(M::MatElem{T}) where T <: NCRingElement`

Construct the identity matrix in the same matrix space as `M`

, i.e. with ones down the diagonal and zeroes elsewhere. `M`

must be square. This is an alias for `one(M)`

.

`identity_matrix(M::MatRingElem{T}) where T <: RingElement`

Return the identity matrix over the same base ring as $M$ and with the same dimensions.

*Examples*

```
S = matrix_ring(ZZ, 2)
M = zero(S)
P = identity_matrix(M)
```

## Matrix algebra functionality provided by AbstractAlgebra.jl

Most of the generic matrix functionality described in the generic matrix section of the documentation is available for both matrix spaces and matrix algebras. Exceptions include functions that do not return or accept square matrices or which cannot specify a parent. Such functions include `solve`

and `nullspace`

which can't be provided for matrix algebras.

In addition to the functionality described for matrix spaces, matrix algebras support all noncommutative ring operations, and matrix algebras can be used as a base ring for other generic constructs that accept a *noncommutative* base ring (`NCRing`

).

In this section we describe functionality provided for matrix algebras only.

### Basic matrix functionality

As well as the Ring and Matrix interfaces, the following functions are provided to manipulate matrices.

`AbstractAlgebra.degree`

— Method`degree(a::MatRingElem{T}) where T <: RingElement`

Return the degree $n$ of the given matrix algebra.

**Examples**

```
julia> R, t = polynomial_ring(QQ, "t")
(Univariate polynomial ring in t over rationals, t)
julia> S = matrix_ring(R, 3)
Matrix ring of degree 3
over univariate polynomial ring in t over rationals
julia> A = S([t + 1 t R(1); t^2 t t; R(-2) t + 2 t^2 + t + 1])
[t + 1 t 1]
[ t^2 t t]
[ -2 t + 2 t^2 + t + 1]
julia> n = degree(A)
3
```