Skip to content

Commit

Permalink
allow efficient both quadratic and sesqui-linear forms
Browse files Browse the repository at this point in the history
  • Loading branch information
kalmarek committed Dec 1, 2024
1 parent 41b20a4 commit 82d0cc8
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/StarAlgebras.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import MutableArithmetics as MA
export StarAlgebra, AlgebraElement
export basis, coeffs, star

function star end

# AbstractCoefficients
## abstract definitions
include("coefficients.jl")
Expand Down
18 changes: 13 additions & 5 deletions src/mstructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,28 +96,36 @@ end

"""
QuadraticForm(Q)
QuadraticForm{star}(Q)
A simple wrapper for representing a quadratic form.
A `QuadraticForm(Q)` represents actually a **sesquilinear form** with respect to
its basis `b`, i.e. `star.(b)·Q·b = ∑ᵢⱼ Q[i,j]·star(b[i])·b[j]`.
`QuadraticForm(Q)` represents an honest quadratic form, however in the context
of `*`-algebras a more canonical object is a **sesquilinear form** which can be
constructed as `QuadraticForm{star}(Q)`.
Both objects are defined by matrix coefficients with respect to their bases `b`,
i.e. their values at `i`-th and `j`-th basis elements:
`star.(b)·Q·b = ∑ᵢⱼ Q[i,j]·star(b[i])·b[j]`.
# Necessary methods:
* `basis(Q)` - a **finite** basis `b` of the quadratic form;
* `Base.getindex(Q, i::T, j::T)` - the value at `i`-th and `j`-th basis elements
where `T` is the type of indicies of `basis(Q)`;
* `Base.eltype(Q)` - the type of `Q[i,j]`.
"""
struct QuadraticForm{T}
struct QuadraticForm{T,involution}
Q::T
QuadraticForm(Q) = new{typeof(Q),identity}(Q)
QuadraticForm{star}(Q) = new{typeof(Q),star}(Q)
end

Base.eltype(qf::QuadraticForm) = eltype(qf.Q)
basis(qf::QuadraticForm) = basis(qf.Q)
Base.getindex(qf::QuadraticForm, i::T, j::T) where {T} = qf.Q[i, j]

function MA.operate!(op::UnsafeAddMul, res, Q::QuadraticForm)
function MA.operate!(op::UnsafeAddMul, res, Q::QuadraticForm{T,ε}) where {T,ε}
for (i, b1) in pairs(basis(Q))
b1★ = star(b1)
b1★ = ε(b1)
for (j, b2) in pairs(basis(Q))
MA.operate!(op, res, coeffs(b1★), coeffs(b2); cfs = Q[i, j])
end
Expand Down
8 changes: 8 additions & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ function AlgebraElement{T}(X::AlgebraElement) where {T}
return AlgebraElement(w, parent(X))
end

"""
AlgebraElement(qf::QuadraticForm, A::AbstractStarAlgebra)
Construct an algebra element in `A` representing quadratic form.
!!! warning
It is assumed that all basis elements of `qf` belong to `A`, or at least
that `keys` of their coefficients can be found in the basis of `A`.
"""
function AlgebraElement(qf::QuadraticForm, A::AbstractStarAlgebra)
@assert all(b -> parent(b) == A, basis(qf))
res = zero(eltype(qf), A)
Expand Down
12 changes: 9 additions & 3 deletions test/quadratic_form.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Base.getindex(g::Gramm, i, j) = g.matrix[i, j]
]
Q = SA.QuadraticForm(Gramm(m, gbasis))
b = basis(Q)
@test A(Q) == π * b[1]' * b[1]
@test A(Q) == π * b[1] * b[1]

m = [
0 1//2 0 0
Expand All @@ -39,7 +39,7 @@ Base.getindex(g::Gramm, i, j) = g.matrix[i, j]
]
Q = SA.QuadraticForm(Gramm(m, gbasis))
b = basis(Q)
@test A(Q) == 1 // 2 * b[1]' * b[2]
@test A(Q) == 1 // 2 * b[1] * b[2]

m = [
0 0 0 0
Expand All @@ -49,7 +49,7 @@ Base.getindex(g::Gramm, i, j) = g.matrix[i, j]
]
Q = SA.QuadraticForm(Gramm(m, gbasis))
b = basis(Q)
@test A(Q) == π * b[2]' * b[2] - b[2]' * b[3]
@test A(Q) == π * b[2] * b[2] - b[2] * b[3]

m = [
0 0 0 0
Expand All @@ -59,9 +59,15 @@ Base.getindex(g::Gramm, i, j) = g.matrix[i, j]
]
Q = SA.QuadraticForm(Gramm(m, gbasis))
b = basis(Q)
@test A(Q) == π * b[3] * b[2] + b[4] * b[3]

Q = SA.QuadraticForm{SA.star}(Gramm(m, gbasis))
@test A(Q) == π * b[3]' * b[2] + b[4]' * b[3]

m = ones(Int, 4, 4)
Q = SA.QuadraticForm(Gramm(m, gbasis))
@test A(Q) == sum(bi * bj for bi in gbasis for bj in gbasis)

Q = SA.QuadraticForm{SA.star}(Gramm(m, gbasis))
@test A(Q) == sum(bi' * bj for bi in gbasis for bj in gbasis)
end

0 comments on commit 82d0cc8

Please sign in to comment.