Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3fb6770
Shifted code, updated names
SirToby25 Mar 17, 2026
d3d62cf
Fixed various constructors. Added is_even, is_odd
SirToby25 Mar 18, 2026
86a1383
Added conformance testing
SirToby25 Mar 19, 2026
5a02a4a
Removed fields, shifted code, conformance works
SirToby25 Mar 19, 2026
69ddf79
Merge branch 'oscar-system:master' into tb/CliffordRingInterface
SirToby25 Mar 19, 2026
569c0fc
Added tests for matrices over Clifford algebras
SirToby25 Mar 19, 2026
ff85d7b
Initialise docs + added type param for OrderElem
SirToby25 Mar 24, 2026
3520e83
Merge branch 'oscar-system:master' into tb/CliffordRingInterface
SirToby25 Mar 25, 2026
185e483
Documentation complete, overhaul of centroids
SirToby25 Apr 2, 2026
5eca9e1
Merge branch 'oscar-system:master' into tb/CliffordRingInterface
SirToby25 Apr 2, 2026
0198fd4
Fixed doctest
SirToby25 Apr 7, 2026
460d118
Update experimental/CliffordAlgOrd/docs/src/introduction.md
SirToby25 Apr 7, 2026
5a44ec8
Update experimental/CliffordAlgOrd/src/CliffordOrder.jl
SirToby25 Apr 7, 2026
eef1cd7
Update experimental/CliffordAlgOrd/src/CliffordAlgebra.jl
SirToby25 Apr 7, 2026
1a78a68
Apply suggestion from @Copilot
SirToby25 Apr 7, 2026
71bb42c
Apply suggestion from @lgoettgens
SirToby25 Apr 7, 2026
a019882
Apply suggestion from @lgoettgens
SirToby25 Apr 7, 2026
9229b67
Apply suggestion from @Copilot
SirToby25 Apr 7, 2026
744a52f
Apply suggestion from @lgoettgens
SirToby25 Apr 7, 2026
84d41ab
conformance tests now recursive
SirToby25 Apr 7, 2026
944de20
conformance tests not recursive
SirToby25 Apr 7, 2026
3365e16
Update experimental/CliffordAlgOrd/src/Operators.jl
SirToby25 Apr 7, 2026
c647380
Update experimental/CliffordAlgOrd/src/CliffordOrder.jl
SirToby25 Apr 7, 2026
cb4898f
Update experimental/CliffordAlgOrd/src/CliffordOrder.jl
SirToby25 Apr 7, 2026
ed850b0
improved multiplication a lot
SirToby25 Apr 7, 2026
03153ba
Replaced fill
SirToby25 Apr 7, 2026
b90cee8
shifted code, reducing code dup
SirToby25 Apr 8, 2026
d18e05f
Removed duplicate mul!
SirToby25 Apr 8, 2026
ebd225e
minor fix
SirToby25 Apr 8, 2026
8f983d6
Merge branch 'oscar-system:master' into tb/CliffordRingInterface
SirToby25 Apr 8, 2026
fe60813
Retrigger tests (empty commit)
SirToby25 Apr 8, 2026
ac1c43c
Update experimental/CliffordAlgOrd/src/Operators.jl
SirToby25 Apr 9, 2026
de8561f
Update assignment syntax for unsafe functions
SirToby25 Apr 9, 2026
db3ff43
Better representation_matrix, add trace & is_unit
SirToby25 Apr 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions experimental/CliffordAlgOrd/docs/doc.main
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
"Clifford Algebras" => [
"introduction.md",
"clifford_algebras.md",
"clifford_orders.md",
],
]
135 changes: 135 additions & 0 deletions experimental/CliffordAlgOrd/docs/src/clifford_algebras.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
```@meta
CurrentModule = Oscar
CollapsedDocStrings = true
DocTestSetup = Oscar.doctestsetup()
```

# [Clifford Algebras over fields](@id cliffordalgebras)

For Clifford algebras over fields, we introduce the following new types:
- `CliffordAlgebra{T, S} <: Hecke.AbstractAssociativeAlgebra{T}` for Clifford algebras
- `CliffordAlgebraElem{T, S} <: Hecke.AbstractAssociativeAlgebraElem{T}` for elements of Clifford algebras
Here, `T` is the element type of the base field and `S` is the element type of the Gram matrix of the
underlying quadratic space, respectively. For example, something like `CliffordAlgebra{QQFieldElem, QQMatrix}`
and `CliffordAlgebraElem{QQFieldElem, QQMatrix}` would be expected here.

We provide a constructor that, given a [`quadratic space`](@ref quadratic_space(::NumField, ::Int)) over some algebraic number
field, including the rationals, returns its Clifford algebra.

```@docs
clifford_algebra(qs::Hecke.QuadSpace)
```

## [Element construction](@id elementconstruction_clifford)

The Clifford algebra ``C`` of a quadratic ``K``-space ``V`` of dimension ``n`` is a free ``K``-algebra
of dimension ``2^n``. Since in this project, ``C`` is constructed based on a Gram matrix ``G \in K^{n \times n}``
with respect to some implicitly chosen ``K``-basis ``(e_i \mid I \subseteq \underline{n})`` of ``V``, we
represent an element ``a \in C`` as its coefficient vector with respect to the ``K``-basis
``(e_I \mid I \subseteq \underline{n})`` of ``C``.

!!! note "Ordering of the basis elements of the Clifford algebra"
The basis elements ``e_I`` are enumerated in increasing order of the integer represented by the
characteristic vectors of subsets ``I``, read as a binary number with the first entry being the
least significant bit. For example, if ``n = 3``, then this order is ``e_\emptyset, e_1, e_2, e_{1,2},
e_{3}, e_{1,3}, e_{2,3}, e_{1,2,3}``, which directly corresponds to the increasing sequence of binary
numbers ``000, 100, 010, 110, 001, 101, 011, 111``.

As a consequence, in our data structure the element ``2 - 2e_2 + 3 e_{2,3} - 5e_{1,2,3}`` is
represented by the vector `[2, 0, -2, 0, 0, 0, 3, -5]`.

We provide multiple ways of directly constructing elements of a given Clifford algebra:
- `(C::CliffordAlgebra)()` returns the zero element of the Clifford algebra `C`
- `(C::CliffordAlgebra)(a::T)` returns `a` as an element of `C`, if possible
- `(C::CliffordAlgebra)(coeffs::Vector)` returns the element in `C` with coefficient
vector `coeffs`

## [Basis and generators](@id basisandgenerators_clifford)

In addition to constructing elements of a Clifford algebra directly, we provide the methods below
to allow for direct access to the canonical basis elements ``e_I`` and algebra generators ``e_i``. One
can then use the usual arithmetic operators `+,-,*` to obtain arbitrary linear combinations and products
of these elements.

```@docs
basis(C::CliffordAlgebra, i::Int)
basis(C::CliffordAlgebra)
gen(C::CliffordAlgebra, i::Int)
gens(C::CliffordAlgebra)
```

## [Basic methods for Clifford algebras](@id basicmethodsforcliffordalgebras)

```@docs
zero(C::CliffordAlgebra)
one(C::CliffordAlgebra)
```
```@docs
base_ring(C::CliffordAlgebra)
space(C::CliffordAlgebra)
gram_matrix(C::CliffordAlgebra)
dim(C::CliffordAlgebra)
is_commutative(::CliffordAlgebra)
```

## [Basic methods for elements of a Clifford algebra](@id basicmethodsforelementsofacliffordalgebra)

```@docs
parent(x::CliffordAlgebraElem)
coeff(x::CliffordAlgebraElem, i::Int)
coefficients(x::CliffordAlgebraElem)
```

In addition to the above `coeff`-method, you can also use standard indexing syntax to conveniently access
and modify the coefficients of an element of a Clifford algebra.
```julia
#Access the third entry of an element x of a Clifford algebra
x[3]

#Modify the third entry of an element x of a Clifford algebra
x[3] = 2
```
### [Functionality for graded parts](@id functionalityforgradedparts_clifford)

The Clifford algebra ``C = C(V)`` carries a natural ``\mathbb{Z}/2\mathbb{Z}``-grading ``C = C_0(V) \oplus C_1(V)``, where
``C_i = C_i(V)`` is generated as a ``K``-space by the set of basis elements ``e_I`` of ``C`` with ``I \: \mathrm{mod} \: 2 = i``,
for ``i \in \lbrace 0, 1\rbrace``. In particular, both ``C_0`` and ``C_1`` are ``2^{n-1}``-dimensional subspaces
of ``C``. Moreover, ``C_0`` is a subalgebra of ``C``, called the *even Clifford algebra* of ``V`` and the *odd part*
``C_1`` is a ``C_0``-bimodule.

Currently, we only provide the following basic functionality on elements for the graded parts of the Clifford algebra:

```@docs
even_coefficients(::CliffordAlgebraElem)
even_part(::CliffordAlgebraElem)
is_even(::CliffordAlgebraElem)

odd_coefficients(::CliffordAlgebraElem)
odd_part(::CliffordAlgebraElem)
is_odd(::CliffordAlgebraElem)
```

## [Center, centroid and quadratic discriminant](@id centerandcentroid_clifford)

The *centroid* of ``V = (V,q)`` (or of ``C = C(V)``), denoted by ``\mathcal{Z}(V)``, is defined as the centraliser
of ``C_0(V)`` in ``C``. Unless ``n = \mathrm{dim}(V) = 0``, in which case ``C(V) = C_0(V) = \mathcal{Z}(V) \cong K``,
the centroid is always a separable quadratic ``K``-algebra. This means that ``\mathcal{Z}(V) \cong K[x]/(x^2 - d)``,
for some non-zero ``d \in K``. The square class ``d(K^\times)^2`` is uniquely determined and called the *quadratic
discriminant* of ``V`` (or of ``C``), denoted by ``\mathrm{disq}(V)``. If ``n = 0``, we put
``\mathrm{disq}(V) \coloneqq 1(K^\times)^2``.

Note that there are also the usual notions of the center of ``C`` (not. ``Z(C)``) and the discriminant of ``V``
(not. ``\mathrm{disc}(V)``) as a quadratic ``K``-space; see [`discriminant`](@ref discriminant(::Hecke.QuadSpace)).
The four concepts of the discriminant and quadratic discriminant of ``V`` and the center and centroid of ``C``
are connected as follows:

- If the dimension ``n`` is even, then ``\mathrm{disc}(V) = \mathrm{disq}(V)`` and ``C`` is a central simple ``K``-algebra, so ``Z(C) = K``.
Moreover, the centroid is entirely contained in the even Clifford algebra.
- If the dimension ``n`` is odd, then ``\mathrm{disc}(V) = 2\mathrm{disq}(V)`` and ``Z(C) = \mathcal{Z}(V)``.

```@docs
basis_of_center(::CliffordAlgebra)
basis_of_centroid(::CliffordAlgebra)
quadratic_discriminant(::CliffordAlgebra)
disq(::CliffordAlgebra)
```
220 changes: 220 additions & 0 deletions experimental/CliffordAlgOrd/docs/src/clifford_orders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
```@meta
CurrentModule = Oscar
CollapsedDocStrings = true
DocTestSetup = Oscar.doctestsetup()
```

# [Clifford orders over rings of integers](@id cliffordorders)

Throughout this page we make the additional assumption that the Dedekind domain ``R`` is the
ring of integers ``\mathcal{O}_K`` of the algebraic number field ``K``. For Clifford orders over rings of
integers, excluding ``\mathbb{Z}``, we introduce the following new types:
- `CliffordOrder{T, C} <: Hecke.AbstractAssociativeAlgebra{T}` for Clifford orders
- `CliffordOrderElem{T, C, S} <: Hecke.AbstractAssociativeAlgebraElem{T}` for elements of Clifford orders
Here, `T` is the element type of the base ring ``\mathcal{O}_K`` and `C` is the type of the Clifford
algebra of the ambient space of the underlying even ``\mathcal{O}_K``-lattice, respectively. Moreover,
``S`` is the element type of ``K``. It is used for storing coefficients of elements with respect
to some pseudo-basis of the Clifford order, as these need not lie in ``\mathcal{O}_K``.

In addition to that we introduce the following new types for Clifford orders over ``\mathbb{Z}``:
- `ZZCliffordOrder <: Hecke.AbstractAssociativeAlgebra{ZZRingElem}` for Clifford orders
- `ZZCliffordOrderElem <: Hecke.AbstractAssociativeAlgebraElem{ZZRingElem}` for elements of Clifford orders

Depending on whether the given even lattice is defined over ``\mathcal{O}_K`` or ``\mathbb{Z}``, we
provide a corresponding constructor to return its Clifford order.

```@docs
clifford_order(ls::QuadLat)
clifford_order(ls::ZZLat)
```

## [Element construction](@id elementconstruction_cliffordo)

Let ``L`` be an even ``R``-lattice with ambient space ``V = KL`` and suppose that the Clifford order
``C(L)`` was constructed with respect to the implicitly chosen pseudo-basis ``(e_i, \mathfrak{a}_i)_{i \in \underline{n}}``
of ``L``. An element ``a`` in the Clifford order ``C(L)`` is stored as it would be as an element of ``C(V)``;
as a vector of length ``2^n`` with entries in ``K``. This vector is the coefficient vector of ``a``
with respect to the ``K``-basis ``(e_I \mid I \subseteq \underline{n})`` of ``C(V)``. Upon creation and
whenever performing any arithmetic operations with ``a \in C(L)``, checks are performed to ensure
that the coefficient of ``e_I`` in this representation of ``a`` is actually contained in ``\mathfrak{a}_I``.

!!! note "Ordering of the basis elements of the Clifford order"
We use the exact same ordering of the basis elements ``e_I``: They are enumerated in increasing order
of the integer represented by the characteristic vectors of subsets ``I``, read as a binary number
with the first entry being the least significant bit.

We provide multiple ways of directly constructing elements of a given Clifford order

- `(C::Union{CliffordOrder, ZZCliffordOrder})()` returns the zero element of the Clifford order `C`
- `(C::Union{CliffordOrder, ZZCliffordOrder})(a::T)` returns `a` as an element of `C`, if possible
- `(C::Union{CliffordOrder, ZZCliffordOrder})(coeffs::Vector)` returns the element in `C` with coefficient
vector `coeffs`

## [(Pseudo-)basis and (pseudo-)generators](@id basisandgenerators_cliffordo)

Recall that over the integers, every even ``\mathbb{Z}``-lattice is free, so the theory is very similar
to the one over number fields. In particular, its Clifford order is free of rank ``2^n``, has the
``\mathbb{Z}``-basis ``(e_I \mid I \subseteq \underline{n})`` and is generated as a ``\mathbb{Z}``-algebra
by ``\lbrace e_i \mid i \in \underline{n}\rbrace``. We provide the following methods to access these canonical
basis elements and generators of the Clifford order.

```@docs
basis(C::ZZCliffordOrder, i::Int)
basis(C::ZZCliffordOrder)
gen(C::ZZCliffordOrder, i::Int)
gens(C::ZZCliffordOrder)
```

Over the ring of integers ``\mathcal{O}_K \neq \mathbb{Z}``, the Clifford order has the pseudo-basis
``(e_I, \mathfrak{a}_I)_{I \subseteq \underline{n}}`` and has the pseudo-generating system
``\lbrace e_i, \mathfrak{a}_i \rbrace_{i \in \underline{n}}`` as ``\mathcal{O}_K``-algebra. We provide
the following methods to access these canonical pseudo-basis elements and generators of the Clifford order.

```@docs
pseudo_basis(C::CliffordOrder, i::Int)
pseudo_basis(C::CliffordOrder)
pseudo_gen(C::CliffordOrder, i::Int)
pseudo_gens(C::CliffordOrder)
```

!!! note "Return type of pseudo-elements"
In the methods above, the ``e_I`` or ``e_i`` are returned as elements of the ambient algebra. This is because they
need not lie in the Clifford order themselves. In fact, this is the case if and only if ``1`` lies in the associated
fractional ideal ``\mathfrak{a}_I`` or ``\mathfrak{a}_i``.
In contrast, the methods for Clifford orders over the integers will always return the basis elements and generators
as elements of the Clifford order, not the ambient algebra.


## [Basic methods for Clifford orders](@id basicmethodsforcliffordorders)

```@docs
zero(C::Union{CliffordOrder, ZZCliffordOrder})
one(C::Union{CliffordOrder, ZZCliffordOrder})
```
```@docs
base_ring(C::CliffordOrder)
lattice(C::Union{CliffordOrder, ZZCliffordOrder})
gram_matrix(C::Union{CliffordOrder, ZZCliffordOrder})
rank(C::Union{CliffordOrder, ZZCliffordOrder})
is_commutative(C::Union{CliffordOrder, ZZCliffordOrder})
```

## [Basic methods for elements of a Clifford order](@id basicmethodsforelementsofacliffordorder)

```@docs
parent(x::Union{CliffordOrderElem, ZZCliffordOrderElem})
coeff(x::Union{CliffordOrderElem, ZZCliffordOrderElem}, i::Int)
coefficients(x::CliffordOrderElem)
```

In addition to the above `coeff`-method, you can also use standard indexing syntax to conveniently access
and modify the coefficients of an element of a Clifford order. When modifying coefficients this way, it
is verified that the new coefficient is valid. For `CliffordOrderElem`, it is checked that the value lies
within the associated fractional ideal of that entry. For `ZZCliffordOrderElem`, it is checked that the
value is an integer.

```julia
#Access the third entry of an element x of a Clifford order
x[3]

#Modify the third entry of an element x of a Clifford order
x[3] = 2
```

### [Containment and conversion](@id containmentandconversion_cliffordo)

Elements of the ambient Clifford algebra ``C(V)`` can be tested for membership in the Clifford order ``C(L)``.

```@docs
Base.in(x::CliffordAlgebraElem, C::CliffordOrder)
```

Additionally, we provide the following constructors to transition elements between the algebra and the order, raising an
error if an algebra element is not contained in the order:

- (C::CliffordAlgebra)(x::Union{CliffordOrderElem, ZZCliffordOrderElem})
- (C::Union{CliffordOrder, ZZCliffordOrder})(x::CliffordAlgebraElem)


### [Functionality for graded parts](@id functionalityforgradedparts_cliffordo)

The Clifford order ``C(L)`` inherits the ``\mathbb{Z}/2\mathbb{Z}``-grading ``C(L) = C_0(L) \oplus C_1(L)`` from
the ``\mathbb{Z}/2\mathbb{Z}``-grading [``C(V) = C_0(V) \oplus C_1(V)``](@ref functionalityforgradedparts_clifford)
via ``C_i(L) = C_i(V) \cap C(L)``, for ``i \in \lbrace 0, 1 \rbrace``. A pseudo-generating set of ``C_i(L)`` is
given by the set of pseudo-basis elements ``(e_I, \mathfrak{a}_I)`` of ``C(L)`` with ``I \: \mathrm{mod} \: 2 = i``.
Thus, ``C_0(L)`` and ``C_1(L)`` are ``\mathcal{O}_K``-submodules of ``C(L)`` of rank ``2^{n-1}``. Moreover, ``C_0(L)``
is an ``\mathcal{O}_K``-suborder of ``C(L)``, called the *even Clifford order* of ``L`` and the *odd part*
``C_1(L)`` is a ``C_0(L)``-bimodule.

Currently, we only provide the following basic functionality on elements for the graded parts of the Clifford order:

```@docs
even_coefficients(x::CliffordOrderElem)
even_part(x::Union{CliffordOrderElem, ZZCliffordOrderElem})
is_even(x::Union{CliffordOrderElem, ZZCliffordOrderElem})

odd_coefficients(x::CliffordOrderElem)
odd_part(x::Union{CliffordOrderElem, ZZCliffordOrderElem})
is_odd(x::Union{CliffordOrderElem, ZZCliffordOrderElem})
```

## [Center, centroid and quadratic discriminant](@id centerandcentroid_cliffordo)

Similar to the [field case](@ref centerandcentroid_clifford), the *centroid* of the even lattice ``L = (L,q)``
(or of ``C = C(L)``), denoted by ``\mathcal{Z}(L)``, is the centraliser of ``C_0(L)`` in ``C``. Thus, we have
``\mathcal{Z}(L) = \mathcal{Z}(V) \cap C(L)``. Unless ``n = \mathrm{dim}(V) = \mathrm{rank}(L) = 0``, in which
case ``C(L) = C_0(L) = \mathcal{Z}(L) \cong \mathcal{O}_K``, the centroid is always an ``\mathcal{O}_K``-order
in the separable quadratic ``K``-algebra ``\mathcal{Z}(V)``. This means that
```math
\mathcal{Z}(L) = \mathcal{O}_K\cdot 1_C \oplus \mathfrak{a}x
```
with a fractional ideal ``\mathfrak{a}`` and some root ``x \in C(V)`` of the polynomial ``X^2 - tX + n \in K[X]``,
where ``t \in \mathfrak{a}^{-1}`` and ``n \in \mathfrak{a}^{-2}``. Every such quadratic ``\mathcal{O}_K``-order
``\Lambda`` contains a unique maximal orthogonal suborder, denoted by ``\Lambda^o``, where orthogonal means that
one can choose ``t = 0`` in the above representation and maximal is meant with respect to set inclusion.
If we write ``\Lambda^o = \mathcal{O}_K \cdot 1_\Lambda \oplus \mathfrak{b}z`` with ``z \in K\Lambda``
satisfying ``z^2 - d \in K^\times``, then ``\mathcal{Z}(L)^o`` is determined as an ``\mathcal{O}_K``-algebra
up to isomorphism by the fractional ideal ``\mathfrak{b}^2 n`` and the ``K``-square class of ``d``. The pair
``(\mathfrak{b}^2 n, d(K^\times)^2)`` is called the *quadratic discriminant* of ``\Lambda``.

The *quadratic discriminant* of the lattice ``L`` (or of ``C``), denoted by ``\mathrm{disq}(L)``, is defined as
the quadratic discriminant of its centroid ``\mathcal{Z}(L)``.

!!! note "Quadratic discriminant over principal ideal domains"
Unlike the field case where the quadratic discriminant is simply a square class, for an even lattice it is
a pair living in ``\mathcal{I}(\mathcal{O}_K) \times K^\times/(K^\times)^2``, where ``\mathcal{I}(\mathcal{O}_K)``
is the group of fractional ideals of ``\mathcal{O}_K``.

If ``\mathcal{O}_K`` is a principal ideal domain, the quadratic discriminant can be identified with the
unique square class ``d(\mathcal{O}_K^\times)^2`` for some ``d \in \mathcal{O}_K`` such that
``\mathcal{Z}(L) = \mathcal{O}_K[X]/(X^2 - d)``. In particular, if ``\mathcal{O}_K = \Z``,
then the quadratic discriminant can be regarded as an integer.

Just as in the field case, the behavior of the center and the centroid heavily depends on the parity of the rank ``n`` of the lattice:

- If the rank ``n`` is even, the centroid is entirely contained within the even Clifford order, i.e. ``\mathcal{Z}(L) \subseteq C_0(L)``.
Moreover, the center is trivial, ``Z(C) = \mathcal{O}_K``.
- If the rank ``n`` is odd, the centroid is strictly orthogonal, meaning ``\mathcal{Z}(L) = \mathcal{Z}(L)^o``.
In this case, the generator of the centroid can be chosen from ``C_1(L)`` such that it has a trace of zero. Furthermore,
the centroid coincides with the center of the Clifford order, ``Z(C) = \mathcal{Z}(L)``.

For Clifford orders over ``\mathcal{O}_K \neq \Z`` we provide the following methods:

```@docs
pseudo_basis_of_center(::CliffordOrder)
pseudo_basis_of_centroid(::CliffordOrder)
pseudo_basis_of_max_orth_suborder_of_centroid(::CliffordOrder)
quadratic_discriminant(::CliffordOrder)
disq(::CliffordOrder)
```

For Clifford orders over the integers we provide the following methods:

```@docs
basis_of_center(::ZZCliffordOrder)
basis_of_centroid(::ZZCliffordOrder)
basis_of_max_orth_suborder_of_centroid(::ZZCliffordOrder)
quadratic_discriminant(::ZZCliffordOrder)
disq(::ZZCliffordOrder)
```

Loading
Loading