Skip to content

Commit 17582f1

Browse files
authored
Backport: Reduce allocations in symmetric eigen (#534)
1 parent 09d8769 commit 17582f1

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

src/Spaces/QuotientSpace.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ import LinearAlgebra: LU, checknonsingular
22

33
export QuotientSpace
44

5-
struct QuotientSpace{S,O,D,R} <: Space{D,R}
5+
struct QuotientSpace{S,O,D,R,LUT<:LU{R}} <: Space{D,R}
66
space::S
77
bcs::O
8-
F::LU{R,Matrix{R}}
8+
F::LUT
99
x::Vector{R}
1010
function QuotientSpace{S,O,D,R}(space::S, bcs::O) where {S,O,D,R}
1111
n = size(bcs, 1)
1212
@assert isfinite(n)
13-
new{S,O,D,R}(space, bcs, lu!(Matrix{R}(I, n, n)), zeros(R, n))
13+
F = lu!(Matrix{R}(I, n, n))
14+
new{S,O,D,R,typeof(F)}(space, bcs, F, zeros(R, n))
1415
end
1516
end
1617

@@ -27,15 +28,16 @@ hasconversion(a::QuotientSpace,b::QuotientSpace) = hasconversion(a.space,b)
2728

2829

2930
Conversion(Q::QuotientSpace{S}, sp::S) where S<:Space = ConcreteConversion(Q, sp)
30-
@inline bandwidths(C::ConcreteConversion{QuotientSpace{S,O,D,R},S}) where {S,O,D,R} = (size(C.domainspace.F, 1), 0)
31+
@inline bandwidths(C::ConcreteConversion{<:QuotientSpace{S},S}) where {S} = (size(C.domainspace.F, 1), 0)
3132

32-
function getindex(C::ConcreteConversion{QuotientSpace{S,O,D,R},S}, i::Integer, j::Integer) where {S,O,D,R}
33+
function getindex(C::ConcreteConversion{<:QuotientSpace{S},S}, i::Integer, j::Integer) where {S}
3334
sp = domainspace(C)
3435
B = sp.bcs
3536
F = sp.F
3637
A = F.factors
3738
n = size(A, 1)
3839
x = sp.x
40+
R = rangetype(sp)
3941
if i == j
4042
return one(R)
4143
elseif j < i j+n
@@ -262,7 +264,7 @@ for (gesdd, elty, relty) in ((:dgesdd_,:Float64,:Float64),
262264
end
263265

264266

265-
function BandedMatrix(S::SubOperator{T,ConcreteConversion{QuotientSpace{SP,O,D,R},SP,T},NTuple{2,UnitRange{Int}}}) where {SP,O,D,R,T}
267+
function BandedMatrix(S::SubOperator{T,<:ConcreteConversion{<:QuotientSpace{SP},SP,T},NTuple{2,UnitRange{Int}}}) where {SP,T}
266268
kr,jr = parentindices(S)
267269
C = parent(S)
268270
#ret = BandedMatrix{eltype(S)}(undef, size(S), bandwidths(S))
@@ -275,6 +277,7 @@ function BandedMatrix(S::SubOperator{T,ConcreteConversion{QuotientSpace{SP,O,D,R
275277
n = size(A, 1)
276278
B = sp.bcs[1:n,1:last(jr)+n]
277279
x = sp.x
280+
R = rangetype(sp)
278281
@inbounds for j in 1:last(jr)
279282
kk = colrange(ret, j)
280283
if j in kk

src/eigen.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,14 @@ function basis_recombination(SE::EigenSystem)
161161
L, QS = SE.L, SE.QS
162162
S = domainspace(L)
163163
C = Conversion(S, rangespace(L))
164-
D1 = Conversion_normalizedspace(S)
165-
D2 = Conversion_normalizedspace(S, Val(:backward))
164+
C_S_NS = Conversion_normalizedspace(S)
165+
C_NS_S = Conversion_normalizedspace(S, Val(:backward))
166166
Q = Conversion(QS, S)
167-
R = D1*Q
168-
P = cache(PartialInverseOperator(C, (0, bandwidth(L, 1) + bandwidth(R, 1) + bandwidth(C, 2))));
169-
A = R'D1*P*L*D2*R
167+
R = C_S_NS * Q
168+
P = cache(PartialInverseOperator(C, (0, bandwidth(L, 1) + bandwidth(R, 1) + bandwidth(C, 2))))
169+
# A = R' * C_S_NS * P * L * C_NS_S * R
170+
# We use C_NS_S * R == Q to simplify this
171+
A = R' * C_S_NS * P * L * Q
170172
B = R'R
171173

172174
return A, B

0 commit comments

Comments
 (0)