Skip to content

Commit

Permalink
Move Hermitian() within mul_hermi
Browse files Browse the repository at this point in the history
  • Loading branch information
abussy committed Feb 3, 2025
1 parent c2b074b commit e7dd283
Showing 1 changed file with 14 additions and 25 deletions.
39 changes: 14 additions & 25 deletions src/eigen/lobpcg_hyper_impl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,25 +106,21 @@ Base.:*(Aadj::Adjoint{T,<:LazyHcat}, B::AbstractMatrix) where {T} = Aadj * LazyH
rows = size(A, 2)
cols = size(B, 2)
ret = similar(B.blocks[1], rows, cols)
fill!(ret, zero(T))

orow = 0 # row offset
for (ia, blA) in enumerate(A.blocks)
ocol = 0 # column offset
for (ib, blB) in enumerate(B.blocks)
ib > ia && continue
fac = one(T)
if ia == ib fac = T(0.5) end
ret[orow .+ (1:size(blA, 2)), ocol .+ (1:size(blB, 2))] .= fac .* (blA' * blB)
ocol += size(blB, 2)
ocol = 0 # column offset
for (ib, blB) in enumerate(B.blocks)
orow = 0 # row offset
for (ia, blA) in enumerate(A.blocks)
ib < ia && continue
ret[orow .+ (1:size(blA, 2)), ocol .+ (1:size(blB, 2))] .= blA' * blB
orow += size(blA, 2)
end
orow += size(blA, 2)
ocol += size(blB, 2)
end
# populate the lower diagonal with conjugate
ret + adjoint(ret)
Hermitian(ret)
end

mul_hermi(Aadj::AbstractArray{T}, B::AbstractArray{T}) where {T} = Aadj * B
mul_hermi(Aadj::AbstractArray{T}, B::AbstractArray{T}) where {T} = Hermitian(Aadj * B)

@views function *(Ablock::LazyHcat, B::AbstractMatrix)
res = Ablock.blocks[1] * B[1:size(Ablock.blocks[1], 2), :] # First multiplication
Expand All @@ -138,20 +134,13 @@ end

@views function LinearAlgebra.mul!(res::AbstractMatrix, Ablock::LazyHcat,
B::AbstractVecOrMat, α::Number, β::Number)
mul!(res, Ablock.blocks[1], B[1:size(Ablock.blocks[1], 2), :], α, β) # First multiplication
offset = size(Ablock.blocks[1], 2)
for block in Ablock.blocks[2:end]
mul!(res, block, B[offset .+ (1:size(block, 2)), :], α, 1)
offset += size(block, 2)
end
res
mul!(res, Ablock*B, I, α, β)
end

# Perform a Rayleigh-Ritz for the N first eigenvectors.
@timing function rayleigh_ritz(X, AX, N)
XAX = mul_hermi(X', AX)
@assert !any(isnan, XAX)
rayleigh_ritz(Hermitian(XAX), N)
rayleigh_ritz(XAX, N)
end
@views function rayleigh_ritz(XAX::Hermitian, N)
# Fallback: Use whatever is the default dense eigensolver.
Expand Down Expand Up @@ -181,7 +170,7 @@ end
# (which implies that X'BX is relatively well-conditioned, and
# therefore that it is safe to cholesky it and reuse the B apply)
function B_ortho!(X, BX)
O = Hermitian(mul_hermi(X'*BX))
O = mul_hermi(X', BX)
U = cholesky(O).U
@assert !any(isnan, U)
rdiv!(X, U)
Expand All @@ -205,7 +194,7 @@ normest(M) = maximum(abs.(diag(M))) + norm(M - Diagonal(diag(M)))
success = false
nchol = 0
while true
O = Hermitian(mul_hermi(X', X))
O = mul_hermi(X', X)
try
R = cholesky(O).U
nchol += 1
Expand Down

0 comments on commit e7dd283

Please sign in to comment.