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

rewritten "naive" alghoritm to work in place #115

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

VinceNeede
Copy link

I've rewritten the "naive" algorithm to modify the mps in place. As discussed on the forum ITensorDiscourseGroup/2271 this implementation is more memory efficient respect the previous one, without impacting the stability of the algorithm. As discussed on the forum the returned MPS is always going to be right orthogonal, this was already true for the densitymatrix algorithm and for the naive in the case truncate=true, while for truncate=false the returned MPS was not gauged.

Details on the Implementation
The implementation uses 2 MPS, one is the MPS passed as input, while another one is created with the same size, but no additional ITensors are created (Imagine it just as a Vector of pointers to Objects, which is what they actually are on a lower level). The data field of the 2 MPSs are used in a stack like manner, in particular ITensors are popped from one, elaborated an the result pushed in the other, in this way the ITensors are never referenced twice, allowing for the garbage collector to act more freely.
I'm gonna cite the comment also present in the code since I think it explains in good detail the implementation:

The main idea is to use 2 vectors as stack, we always pop from one, elaborate the element and push it to the other.
This will lead for a tensor to never be referenced twice, allowing for the garbage collector to free the memory.
To be consistent with the density matrix method, and since truncate! always returns a right orthogonal MPS,
we have to work such that also when truncate=false the resulting MPS must be right orthogonal. In order to achieve
this we will set some aliases at the beginning and leave the for loop as general as possible. In particular:

  • if truncate is true
    
    then whe have to supply to truncate! a left orthogonal MPS, this is achieved by populating the stackOut vector
    (the one from which we pop) with the tensors of ψ in reverse order. In this way when popping from it we are going
    to push the tensors into ψ in the right order.
    
  • if truncate is false
    
    then we have to obtain a right orthogonal MPS directly, in this case we are going to use ψ as stackOut and pushing
    the results in a new vector that is the data of a new MPS ϕ. This will have the tensors in reverse order
    so by left orthogonalizing it, we are right orthogonalizing ψ. At the end we will have to copy the data back to ψ.
    

Other changes
Instead of creating an "apply!" version I preferred to create a different utility function which I called evolve!, in a way to make it clearer that the idea is to evolve the MPS by applying the MPO to it, for the same reason the order of the arguments is reversed, putting the MPS first.

"""
  function evolve!(ψ::MPS, A::MPO; alg=Algorithm"naive"(), kwargs...)
  
  An in place version of [`apply`](@ref). The state ψ is evolved by the MPO A.
"""
function evolve!(ψ::MPS, A::MPO; alg=Algorithm"naive"(), kwargs...)
  ITensors.contract!(Algorithm(alg), A, ψ; kwargs...)
  replaceprime!(ψ, 1 => 0)
end

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.

1 participant