Groups.jl/src/matrix_groups/eltary_symplectic.jl

77 lines
2.2 KiB
Julia

struct ElementarySymplectic{N,T} <: Groups.GSymbol
symbol::Symbol
i::Int
j::Int
val::T
function ElementarySymplectic{N}(s::Symbol, i::Integer, j::Integer, val=1) where {N}
@assert s (:A, :B)
@assert iseven(N)
n = N ÷ 2
if s === :A
@assert 1 i n && 1 j n && i j
elseif s === :B
@assert xor(1 i n, 1 j n) && xor(n < i N, n < j N)
end
return new{N,typeof(val)}(s, i, j, val)
end
end
function Base.show(io::IO, s::ElementarySymplectic)
i, j = Groups.subscriptify(s.i), Groups.subscriptify(s.j)
print(io, s.symbol, i, j)
!isone(s.val) && print(io, "^$(s.val)")
end
_ind(s::ElementarySymplectic{N}) where {N} = (s.i, s.j)
_local_ind(N_half::Integer, i::Integer) = ifelse(i <= N_half, i, i - N_half)
function _dual_ind(s::ElementarySymplectic{N}) where {N}
if s.symbol === :A && return _ind(s)
else#if s.symbol === :B
return _dual_ind(N ÷ 2, s.i, s.j)
end
end
function _dual_ind(N_half, i, j)
@assert i <= N_half < j || j <= N_half < i
if i <= N_half # && j > N_half
i, j = j - N_half, i + N_half
else
i, j = j + N_half, i - N_half
end
return i, j
end
function Base.:(==)(s::ElementarySymplectic{N}, t::ElementarySymplectic{M}) where {N,M}
N == M || return false
s.symbol == t.symbol || return false
s.val == t.val || return false
return _ind(t) == _ind(s) || _ind(t) == _dual_ind(s)
end
Base.hash(s::ElementarySymplectic, h::UInt) =
hash(Set([_ind(s); _dual_ind(s)]), hash(s.symbol, hash(s.val, h)))
LinearAlgebra.transpose(s::ElementarySymplectic{N}) where {N} =
ElementarySymplectic{N}(s.symbol, s.j, s.i, s.val)
Base.inv(s::ElementarySymplectic{N}) where {N} =
ElementarySymplectic{N}(s.symbol, s.i, s.j, -s.val)
function matrix(s::ElementarySymplectic{N,T}) where {N,T}
@assert iseven(N)
n = div(N, 2)
m = StaticArrays.MMatrix{N,N,T}(LinearAlgebra.I)
i, j = _ind(s)
m[i, j] = s.val
if s.symbol === :A
m[n+j, n+i] = -s.val
else#if s.symbol === :B
if i > n
m[j+n, i-n] = s.val
else
m[j-n, i+n] = s.val
end
end
return StaticArrays.SMatrix{N,N}(m)
end