Skip to content
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

Extend KrylovKit.eigsolve by allowing the initial guess x₀ to be a Tensor #171

Merged
merged 6 commits into from
Jul 16, 2024

Conversation

jofrevalles
Copy link
Member

Summary

This PR extends the eigsolve function introduced in PR #157 by allowing the initial guess eigenvector x₀ to be a Tensor. Previously, this variable had to be an AbstractVector. We also updated the tests to cover this extension.

Example

julia> using KrylovKit

julia> using Tenet; using LinearAlgebra; using Test

julia> A = rand(ComplexF64, 4, 4)
4×4 Matrix{ComplexF64}: ...

julia> data = (A + A') / 2 # Make it Hermitian

julia> tensor = Tensor(data, (:i, :j))
4×4 Tensor{ComplexF64, 2, Matrix{ComplexF64}}: ..

julia> vals, vecs, info = eigsolve(tensor, Tensor(rand(ComplexF64, 4), (:i,)), 4, :SR, Lanczos(; krylovdim=4, tol=1e-16); left_inds=[:i], right_inds=[:j]) # Perform eigensolve
...

julia> V_matrix = hcat([reshape(parent(vec), :) for vec in vecs]...) # Convert vecs to matrix form for reconstruction
4×4 Matrix{ComplexF64}: ...

julia> D_matrix = Diagonal(vals)
4×4 Diagonal{Float64, Vector{Float64}}:
 -0.573245                       
           0.0709279             
                     0.430396    
                              2.32354

julia> reconstructed_matrix = V_matrix * D_matrix * inv(V_matrix)
4×4 Matrix{ComplexF64}: ...

julia> @test isapprox(reconstructed_matrix, parent(tensor))
Test Passed

@jofrevalles jofrevalles changed the title Extend KrylovKit.eigsolve by allowing the initial guess x₀ to be a Tensor Extend KrylovKit.eigsolve by allowing the initial guess x₀ to be a Tensor Jul 15, 2024
Copy link
Member

@mofeing mofeing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you gain something by making x0 a Tensor?

ext/TenetKrylovKitExt.jl Outdated Show resolved Hide resolved
ext/TenetKrylovKitExt.jl Outdated Show resolved Hide resolved
Comment on lines -53 to -66
function KrylovKit.eigsolve(
f::Tensor, x₀, howmany::Int=1, which::KrylovKit.Selector=:LM; left_inds=Symbol[], right_inds=Symbol[], kwargs...
)
Amat, left_sizes, right_sizes = eigsolve_prehook_tensor_reshape(A, left_inds, right_inds)

# Compute eigenvalues and eigenvectors
vals, vecs, info = KrylovKit.eigsolve(Amat, x₀, howmany, which; kwargs...)

# Tensorify the eigenvectors
Avecs = [Tensor(reshape(vec, left_sizes...), left_inds) for vec in vecs]

return vals, Avecs, info
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have you removed this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the comment from above.

ext/TenetKrylovKitExt.jl Outdated Show resolved Hide resolved
@jofrevalles
Copy link
Member Author

Do you gain something by making x0 a Tensor?

In some iterative algorithms (e.g., DMRG), we may have an initial tensor θ, and we update it with some eigenvector from eisolve. In this case we usually can pass θ to Lanczos, so it makes sense that we have that in a Tensor form.

Co-authored-by: Sergio Sánchez Ramírez <[email protected]>
@mofeing
Copy link
Member

mofeing commented Jul 15, 2024

In some iterative algorithms (e.g., DMRG), we may have an initial tensor θ, and we update it with some eigenvector from eisolve. In this case we usually can pass θ to Lanczos, so it makes sense that we have that in a Tensor form.

Yes, but as far as I've seen, the result of calling eigsolve now it's not a Tensor right. Maybe it would nice to return a Tensor?

@jofrevalles
Copy link
Member Author

Yes, but as far as I've seen, the result of calling eigsolve now it's not a Tensor right. Maybe it would nice to return a Tensor?

No, the result of eigvecs is a list of Tensors, so this is already working as expected.

Co-authored-by: Sergio Sánchez Ramírez <[email protected]>
@mofeing
Copy link
Member

mofeing commented Jul 15, 2024

Ok 👍

You just need to deduplicate the code and the PR should be ready.

@jofrevalles
Copy link
Member Author

Ok 👍

You just need to deduplicate the code and the PR should be ready.

Done!

ext/TenetKrylovKitExt.jl Outdated Show resolved Hide resolved
@mofeing mofeing merged commit 0b68cf6 into master Jul 16, 2024
6 checks passed
@mofeing mofeing deleted the fix/eigsolve branch July 16, 2024 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants