Skip to content
This repository has been archived by the owner on Jul 7, 2024. It is now read-only.

Fix canonize function and enhance index semantics #8

Merged
merged 8 commits into from
Feb 16, 2024

Conversation

jofrevalles
Copy link
Member

Summary

This PR fixes the canonize function, enabling it to correctly canonize a desired Tensor within a Site of a Chain. We have enhanced this function to allow users to choose the mode (:qr or :svd) in which the canonization is applied. By default, the :qr option is selected, preserving the total number of tensors in the TensorNetwork. The :svd mode, on the other hand, introduces a new tensor which is connected by a hyperindex to the bond between sites, and it contains the Schmidt values. Additionally, we have created a comprehensive test set to ensure the function's reliability and performance.

Furthermore, we have refactored the logic inside leftindex and rightindex. Now, these indices are determined by the intersection of the indices with those of the adjacent tensor in the Chain, rather than relying on the order of inds in the tensors. This enhancement is expected to make our library more robust and error-resistant, as changes in the tensor order will no longer have unintended side effects.

Example

Here we show how we create a Chain and we canonize the middle tensor:

julia> function is_left_canonical(qtn, s::Site)
          label_r = rightindex(qtn, s)
          A = select(qtn, :tensor, s)
          try
              contracted = contract(A, replace(conj(A), label_r => :new_ind_name))
              return isapprox(contracted, Matrix{Float64}(I, size(A, label_r), size(A, label_r)), atol=1e-12)
          catch
              return false
          end
       end
is_left_canonical (generic function with 1 method)

julia> function is_right_canonical(qtn, s::Site)
          label_l = leftindex(qtn, s)
          A = select(qtn, :tensor, s)
          try
              contracted = contract(A, replace(conj(A), label_l => :new_ind_name))
              return isapprox(contracted, Matrix{Float64}(I, size(A, label_l), size(A, label_l)), atol=1e-12)
          catch
              return false
          end
       end
is_right_canonical (generic function with 1 method)

julia> qtn  = Chain(State(), Open(), [rand(4, 4), rand(4, 4, 4), rand(4, 4)])
MPS (inputs=0, outputs=3)

julia> canonized = canonize(qtn, Site(2); direction=:left, mode=:qr) # We left-canonize the tensor on the second site
MPS (inputs=0, outputs=3)

julia> is_left_canonical(canonized, Site(2))
true

julia> canonized = canonize(qtn, Site(2); direction=:right, mode=:svd) # We right-canonize the tensor on the second site using svd
MPS (inputs=0, outputs=3)

julia> length(tensors(canonized))
4

julia> contract(transform(TensorNetwork(canonized), HyperindConverter())) |> inds^C

julia> isapprox(contract(transform(TensorNetwork(canonized), Tenet.HyperindConverter())), contract(TensorNetwork(qtn)))
true

@jofrevalles jofrevalles requested a review from mofeing February 15, 2024 14:05
@jofrevalles
Copy link
Member Author

Mmmm... This did not fail on my machine...

@mofeing
Copy link
Member

mofeing commented Feb 15, 2024

I think it fails because some of this features require Tenet on master. Maybe we can release a new "patch" version of Tenet with this changes?

@jofrevalles
Copy link
Member Author

I think it fails because some of this features require Tenet on master. Maybe we can release a new "patch" version of Tenet with this changes?

Ahh, it has to be that. Yes, that would be great, @mofeing !

Comment on lines 116 to 119
rightsite(::Union{Open, Periodic}, tn::Chain, site::Site) = Site(site.id + 1)

leftsite(tn::Chain, site::Site) = leftsite(boundary(tn), tn, site)
leftsite(::Open, tn::Chain, site::Site) = Site(site.id - 1)
leftsite(::Union{Open, Periodic}, tn::Chain, site::Site) = Site(site.id - 1)
Copy link
Member

Choose a reason for hiding this comment

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

Can we canonize a periodic MPS? If so, doing a ::Union{Open,Periodic} is probably not the best solution.

Copy link
Member Author

Choose a reason for hiding this comment

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

We can, but we need to include the proper logic on the canonize function. Nevertheless, we can always do leftsite and rightsite of Periodic MPS.

However, maybe it would be a good idea to put here a check so we don't go to the left of the Site(1), in the case of Open MPS.

Copy link
Member

Choose a reason for hiding this comment

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

I think it would be better to do 2 separa methods:

  • One, the leftsite(::Open) as it is now
  • The other leftsite(::Periodic) that wraps the i with the period

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, what do you think?

Copy link
Member

@mofeing mofeing Feb 16, 2024

Choose a reason for hiding this comment

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

Much better, but we should check whether site is in range for the Periodic case.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is not necessary, right? In Periodic we can assume Site(4) is effectively Site(1), for a periodic cell of 3 sites.

Copy link
Member

Choose a reason for hiding this comment

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

We can do that, but we have to stick to it then.

src/Ansatz/Chain.jl Show resolved Hide resolved
src/Ansatz/Chain.jl Show resolved Hide resolved
@mofeing mofeing self-requested a review February 16, 2024 10:10
@mofeing mofeing merged commit 7b4d4ef into master Feb 16, 2024
0 of 2 checks passed
@mofeing mofeing deleted the fix/enhance-canonize branch February 16, 2024 10:12
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants