-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fast qr for BlockSkylineMatrix
and Cholesky for Symmetric{<:Any,<:BlockSkylineMatrix}
#28
Comments
Since I'm at the point where I've transitioned FEDVRQuasi to |
One thing I forgot to mention, I need to update my factorizations every iteration, so it would be nice to be able to precompute the structure of the factorization (since that will not change), and every iteration do something along the lines of copyto!(factorization, Factorization(H) where An example that works with latest FEDVRQuasi, which I'd like to be fast: using FEDVRQuasi
using LinearAlgebra
using ArnoldiMethod
L = 40.0
ℓ = 1 # Angular momentum
Z = 1 # Nuclear charge
t = range(0.0,stop=L,length=10)
R = FEDVR(t, 10)[:,2:end-1]
D = Derivative(axes(R,1))
∇² = R' * D' * D * R
T = -0.5∇²
V = Matrix(r -> -Z/r + ℓ*(ℓ+1)/2r^2, R)
H = T + V
# Aim slightly below the ground state eigenvalue
σ = 1.1*(-Z^2/2)
H⁻¹ = factorize(Symmetric(Matrix(H - σ*I))) Diagonalizing: struct ShiftInvert{Factorization, T}
A⁻¹::Factorization
σ::T
end
Base.size(S::ShiftInvert, args...) = size(S.A⁻¹, args...)
Base.eltype(S::ShiftInvert) = eltype(S.A⁻¹)
LinearAlgebra.mul!(y, si::ShiftInvert, x) = ldiv!(y, si.A⁻¹, x)
println("Direct:")
schurQR,history = @time partialschur(H,nev=1,which=SR())
println(history)
println("Shift-and-invert:")
schurQR,history = @time partialschur(ShiftInvert(H⁻¹,σ),nev=1,which=LR())
println(history) gives
|
Perhaps I'm not understanding but factorizations are typically in-place. So I think the code would actually be something like: F_data .= H - σ*I # or applied(-, H, σ*I) to avoid allocation
F = cholesky!(Symmetric(F_data)) PS Is |
BlockSkylineMatrix
BlockSkylineMatrix
and Cholesky for Symmetric{<:Any,<:BlockSkylineMatrix}
For hydrogen (or any one-electron problem), you can always choose a shift such that the Hermitian matrix becomes positive-definite, it is more complicated for multi-electron problems, where you need to optimize multiple (coupled) eigenvectors, belonging to different eigenvalues at the same time. Then, for some of the interior eigenvalues, the shifted matrix is not positive definite any more. Furthermore, the integral part of the integro-differential operator is not easily factorizable, so for problems where integral operators arise, my strategy is to use IterativeSolvers.jl with a preconditioner built from the part that I can factorize, i.e. the one-body operator above and some extra potentials. At the moment I'm doing straight Arnoldi, but that has convergence issues and high condition numbers. Simple shift-and-invert does not work very well either, since the spectrum is very dense. I'm thinking maybe I need inverse iterations, which also needs factorizations as above. EDIT: TL-DR, Cholesky is nice, but I need the more general case as well. |
I think you want LDLT, which should be even faster than Cholesky for symmetric block-skyline matrices. |
Yes, that's what I get back for finite-differences, where the Hamiltonian is symmetric tridiagonal. |
@jagot I'm going to tackle this soon which should speed up \ a lot. Essentially its not too hard to do this in-place, calling LAPACK to do the heavy work.
The text was updated successfully, but these errors were encountered: