You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Your current SkewHermTridiagonal only stores the lower diagonal ev, but this is only correct for real skew-tridiagonal. For complex skew-tridiagonal matrices, the diagonal may be nonzero (albeit purely imaginary).
To fix this, you need to add an optional field to store the diagonal imaginary parts if T is complex. Something like:
struct SkewHermTridiagonal{T, V<:AbstractVector{T}, Vim<:Union{AbstractVector{<:Real},Nothing}} <:AbstractMatrix{T}
ev::V# subdiagonal
dvim::Vim# diagonal imaginary parts (may be nothing if T is real)functionSkewHermTridiagonal{T, V, Vim}(ev, dvim) where {T, V<:AbstractVector{T}, Vim}
LA.require_one_based_indexing(ev)
if Vim !== Nothing
LA.require_one_based_indexing(dvim)
eltype(dvim) ===real(T) ||throw(ArgumentError("mismatch between $(real(T)) and $(eltype(dvim))"))
endnew{T, V, Vim}(ev, dvim)
endend# real skew-symmetric caseSkewHermTridiagonal(ev::AbstractVector{T}) where {T<:Real} =SkewHermTridiagonal{T, typeof(ev), Nothing}(ev, nothing)
SkewHermTridiagonal{T}(ev::AbstractVector) where {T<:Real} =SkewHermTridiagonal(convert(AbstractVector{T}, ev)::AbstractVector{T})
# complex skew-hermitian caseSkewHermTridiagonal(ev::AbstractVector{Complex{T}}, dvim::AbstractVector{T}) where T =SkewHermTridiagonal{Complex{T}, typeof(ev), typeof(dvim)}(ev, dvim)
SkewHermTridiagonal{Complex{T}}(ev::AbstractVector, dvim::AbstractVector) where T =SkewHermTridiagonal(convert(AbstractVector{Complex{T}}, ev)::AbstractVector{Complex{T}}, convert(AbstractVector{T}, dvim)::AbstractVector{T})
and then you would need to specialize getindex and other functions, e.g.
Base.@propagate_inboundsfunction Base.getindex(A::SkewHermTridiagonal{T}, i::Integer, j::Integer) where T
@boundscheckcheckbounds(A, i, j)
if i == j +1return@inbounds A.ev[j]
elseif i +1== j
return@inbounds-A.ev[i]'elseif T <:Complex&& i == j
returncomplex(zero(real(T)), A.dvim[i])
elsereturnzero(T)
endend
(Note the compiler will optimize out the T <: Complex check.)
The text was updated successfully, but these errors were encountered:
Your current
SkewHermTridiagonal
only stores the lower diagonalev
, but this is only correct for real skew-tridiagonal. For complex skew-tridiagonal matrices, the diagonal may be nonzero (albeit purely imaginary).To fix this, you need to add an optional field to store the diagonal imaginary parts if
T
is complex. Something like:and then you would need to specialize
getindex
and other functions, e.g.(Note the compiler will optimize out the
T <: Complex
check.)The text was updated successfully, but these errors were encountered: