Skip to content

Commit 60d5f02

Browse files
authored
Faster getindex for BandedEigenvectors (#354)
* faster getindex for BandedEigenvectors with two caches * revert to using Array * Add getindex test * restrict getindex to Int * getindex with colon
1 parent 3baf6e7 commit 60d5f02

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/symbanded/bandedeigen.jl

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,33 @@
22
struct BandedEigenvectors{T} <: AbstractMatrix{T}
33
G::Vector{Givens{T}}
44
Q::Matrix{T}
5+
z1::Vector{T}
6+
z2::Vector{T}
57
end
68

79
size(B::BandedEigenvectors) = size(B.Q)
8-
getindex(B::BandedEigenvectors, i, j) = Matrix(B)[i, j]
10+
getindex(B::BandedEigenvectors, i, j) = Matrix(B)[i,j]
11+
function _getindex_vec(B::BandedEigenvectors{T}, j) where {T}
12+
z1, z2 = B.z1, B.z2
13+
z2 .= zero(T)
14+
z2[j] = oneunit(T)
15+
mul!(z1, B, z2)
16+
end
17+
function getindex(B::BandedEigenvectors, i::Int, j::Int)
18+
z = _getindex_vec(B, j)
19+
z[i]
20+
end
21+
function getindex(B::BandedEigenvectors, ::Colon, j::Int)
22+
z = _getindex_vec(B, j)
23+
copy(z)
24+
end
25+
function getindex(B::BandedEigenvectors, ::Colon, jr::AbstractVector{<:Int})
26+
M = similar(B, size(B,1), length(jr))
27+
for (ind, j) in enumerate(jr)
28+
M[:, ind] = _getindex_vec(B, j)
29+
end
30+
return M
31+
end
932

1033
# V = S⁻¹ Q W
1134
struct BandedGeneralizedEigenvectors{T,M<:AbstractMatrix{T}} <: AbstractMatrix{T}
@@ -39,7 +62,7 @@ function eigen!(A::Symmetric{T,<:BandedMatrix{T}}) where T <: Real
3962
AB = symbandeddata(A)
4063
sbtrd!('V', A.uplo, N, KD, AB, D, E, G, WORK)
4164
Λ, Q = eigen(SymTridiagonal(D, E))
42-
Eigen(Λ, BandedEigenvectors(G, Q))
65+
Eigen(Λ, BandedEigenvectors(G, Q, similar(Q, size(Q,1)), similar(Q, size(Q,2))))
4366
end
4467

4568
function eigen!(A::Symmetric{T,<:BandedMatrix{T}}, B::Symmetric{T,<:BandedMatrix{T}}) where T <: Real

test/test_symbanded.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ import BandedMatrices: MemoryLayout, SymmetricLayout, HermitianLayout, BandedCol
7373
FD = convert(Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}, F)
7474
@test FD.vectors'Matrix(A)*FD.vectors Diagonal(F.values)
7575

76+
MQ = Matrix(Q)
77+
@test Q[axes(Q,1),1:3] MQ[axes(Q,1),1:3]
78+
@test Q[:,1:3] MQ[:,1:3]
79+
@test Q[:,3] MQ[:,3]
80+
@test Q[1,2] MQ[1,2]
7681

7782
function An(::Type{T}, N::Int) where {T}
7883
A = Symmetric(BandedMatrix(Zeros{T}(N,N), (0, 2)))

0 commit comments

Comments
 (0)