Skip to content

Commit 43764a2

Browse files
authored
Faster indexing for BandedGeneralizedEigenvectors (#364)
* Faster indexing for BandedGeneralizedEigenvectors * merge getindex methods
1 parent c32e3e0 commit 43764a2

File tree

2 files changed

+37
-26
lines changed

2 files changed

+37
-26
lines changed

src/symbanded/bandedeigen.jl

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,45 +29,46 @@ function eigvals!(A::Symmetric{T,<:BandedMatrix{T}}, B::Symmetric{T,<:BandedMatr
2929
eigvals!(A)
3030
end
3131

32-
# V = G Q
33-
struct BandedEigenvectors{T} <: AbstractMatrix{T}
34-
G::Vector{Givens{T}}
35-
Q::Matrix{T}
36-
z1::Vector{T}
37-
end
32+
abstract type AbstractBandedEigenvectors{T} <: AbstractMatrix{T} end
3833

39-
size(B::BandedEigenvectors) = size(B.Q)
40-
getindex(B::BandedEigenvectors, i, j) = Matrix(B)[i,j]
41-
function _getindex_vec(B::BandedEigenvectors{T}, j) where {T}
42-
z1 = B.z1
43-
z2 = OneElement(one(T), j, size(B,2))
34+
getindex(B::AbstractBandedEigenvectors, i, j) = Matrix(B)[i,j]
35+
function _getindex_vec(B, j)
36+
z1 = _get_scratch(B)
37+
z2 = OneElement(one(eltype(B)), j, size(B,2))
4438
mul!(z1, B, z2)
4539
end
46-
function getindex(B::BandedEigenvectors, i::Int, j::Int)
40+
function getindex(B::AbstractBandedEigenvectors, i::Union{Int, Colon, AbstractVector{Int}}, j::Int)
4741
z = _getindex_vec(B, j)
4842
z[i]
4943
end
50-
function getindex(B::BandedEigenvectors, ::Colon, j::Int)
51-
z = _getindex_vec(B, j)
52-
copy(z)
53-
end
54-
function getindex(B::BandedEigenvectors, ::Colon, jr::AbstractVector{<:Int})
44+
function getindex(B::AbstractBandedEigenvectors, ::Colon, jr::AbstractVector{Int})
5545
M = similar(B, size(B,1), length(jr))
5646
for (ind, j) in enumerate(jr)
5747
M[:, ind] = _getindex_vec(B, j)
5848
end
5949
return M
6050
end
6151

52+
# V = G Q
53+
struct BandedEigenvectors{T} <: AbstractBandedEigenvectors{T}
54+
G::Vector{Givens{T}}
55+
Q::Matrix{T}
56+
z1::Vector{T} # scratch space, used in indexing
57+
end
58+
59+
size(B::BandedEigenvectors) = size(B.Q)
60+
61+
_get_scratch(B::BandedEigenvectors) = B.z1
62+
6263
# V = S⁻¹ Q W
63-
struct BandedGeneralizedEigenvectors{T,M<:AbstractMatrix{T}} <: AbstractMatrix{T}
64+
struct BandedGeneralizedEigenvectors{T,M<:AbstractMatrix{T}} <: AbstractBandedEigenvectors{T}
6465
S::SplitCholesky{T,M}
6566
Q::Vector{Givens{T}}
6667
W::BandedEigenvectors{T}
6768
end
6869

6970
size(B::BandedGeneralizedEigenvectors) = size(B.W)
70-
getindex(B::BandedGeneralizedEigenvectors, i, j) = Matrix(B)[i, j]
71+
_get_scratch(B::BandedGeneralizedEigenvectors) = _get_scratch(B.W)
7172

7273
convert(::Type{Eigen{T, T, Matrix{T}, Vector{T}}}, F::Eigen{T, T, BandedEigenvectors{T}, Vector{T}}) where T = Eigen(F.values, Matrix(F.vectors))
7374
convert(::Type{GeneralizedEigen{T, T, Matrix{T}, Vector{T}}}, F::GeneralizedEigen{T, T, BandedGeneralizedEigenvectors{T}, Vector{T}}) where T = GeneralizedEigen(F.values, Matrix(F.vectors))

test/test_symbanded.jl

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,25 @@ using Test
143143
@test V'AM*V Diagonal(Λ)
144144
@test V'Matrix(B)*V I
145145

146-
# misc mul/div tests
147146
VM = Matrix(V)
148-
@test AM * V AM * VM
149-
@test V * AM VM * AM
150-
x = rand(T, size(V,2))
151-
@test ldiv!(similar(x), V, x) ldiv!(similar(x), factorize(VM), x)
152147

153-
z = OneElement{T}(4, size(V,2))
154-
@test V * z V * Vector(z)
148+
@testset "indexing" begin
149+
@test V[axes(V,1),1:3] VM[axes(V,1),1:3]
150+
@test V[:,1:3] VM[:,1:3]
151+
@test V[:,3] VM[:,3]
152+
@test V[axes(V,1),3] VM[axes(V,1),3]
153+
@test V[1,2] VM[1,2]
154+
end
155+
156+
@testset "mul/div" begin
157+
@test AM * V AM * VM
158+
@test V * AM VM * AM
159+
x = rand(T, size(V,2))
160+
@test ldiv!(similar(x), V, x) ldiv!(similar(x), factorize(VM), x)
161+
162+
z = OneElement{T}(4, size(V,2))
163+
@test V * z V * Vector(z)
164+
end
155165
end
156166

157167
@testset "eigen with mismatched parent bandwidths" begin

0 commit comments

Comments
 (0)