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

Implement SplitSimplification transformation for TensorNetwork #70

Merged
merged 7 commits into from
Jul 4, 2023

Conversation

jofrevalles
Copy link
Member

@jofrevalles jofrevalles commented Jul 3, 2023

Summary

This PR introduces the SplitSimplification transformation as part of the transform! function for TensorNetworks, addressing issue #18 (resolve #18). The transformation applies the split simplification procedure, as outlined in this paper, to reduce the complexity of the tensor network while ensuring the rank of any tensor does not increase. The main strategy involves performing a singular value decomposition across all possible bipartitions of a tensor's indices, and replacing the tensor with a lower-rank approximation when this results in a simplification of the TensorNetwork.

Additionally, this PR includes comprehensive tests that verify the correctness and robustness of the newly implemented transformation.

Example

julia> using Tenet

julia> v1 = Tensor([1, 2, 3], (:i,))
3-element Tensor{Int64, 1, Vector{Int64}}:
...

julia> v2 = Tensor([4, 5, 6], (:j, ))
3-element Tensor{Int64, 1, Vector{Int64}}:
...

julia> m1 = Tensor(rand(3, 3), (:k, :l))
3×3 Tensor{Float64, 2, Matrix{Float64}}:
...

julia> t1 = contract(v1, v2)
3×3 Tensor{Int64, 2, Matrix{Int64}}:
...

julia> tensor = contract(t1, m1) # Define a tensor which can be splitted in three
3×3×3×3 Tensor{Float64, 4, Array{Float64, 4}}:
...

julia> tn = TensorNetwork([tensor, Tensor(rand(3, 3, 3), (:k, :m, :n)), Tensor(rand(3, 3, 3), (:l, :n, :o))])
TensorNetwork{Arbitrary, NamedTuple{(), Tuple{}}}(#tensors=3, #labels=7)

julia> reduced = transform(tn, SplitSimplification)
TensorNetwork{Arbitrary, NamedTuple{(), Tuple{}}}(#tensors=5, #labels=9)

julia> size.(tensors(tn))
3-element Vector{Tuple{Int64, Int64, Int64, Vararg{Int64}}}:
 (3, 3, 3, 3)
 (3, 3, 3)
 (3, 3, 3)

julia> size.(tensors(reduced))
5-element Vector{Tuple{Int64, Int64, Vararg{Int64}}}:
 (3, 3, 3)
 (3, 3, 3)
 (3, 1)
 (3, 1)
 (1, 1, 3, 3)

In this example, the SplitSimplification transformation is applied to a tensor network that includes a rank-4 tensor that can be simplified using svd into two vectors and a matrix. The result is a network containing five tensors, each of lower rank and dimensions.

@codecov
Copy link

codecov bot commented Jul 3, 2023

Codecov Report

Merging #70 (274fc08) into master (2b37db3) will decrease coverage by 0.66%.
The diff coverage is 95.83%.

@@            Coverage Diff             @@
##           master      #70      +/-   ##
==========================================
- Coverage   88.50%   87.84%   -0.66%     
==========================================
  Files           9        9              
  Lines         600      625      +25     
==========================================
+ Hits          531      549      +18     
- Misses         69       76       +7     
Impacted Files Coverage Δ
src/Transformations.jl 97.46% <95.83%> (-0.30%) ⬇️

... and 4 files with indirect coverage changes

@mofeing
Copy link
Member

mofeing commented Jul 3, 2023

Super!

julia> size.(tensors(reduced))
5-element Vector{Tuple{Int64, Int64, Vararg{Int64}}}:
 (3, 3, 3)
 (3, 3, 3)
 (3, 1)
 (3, 1)
 (1, 1, 3, 3)

I think it's best to directly remove the indices whose resulting dimension is 1. What do you think @jofrevalles?

@jofrevalles
Copy link
Member Author

I think it's best to directly remove the indices whose resulting dimension is 1. What do you think @jofrevalles?

Maybe we could extend dropdims for Tensors, right? This would be easier.

src/Transformations.jl Outdated Show resolved Hide resolved
src/Transformations.jl Outdated Show resolved Hide resolved
src/Transformations.jl Outdated Show resolved Hide resolved
src/Transformations.jl Outdated Show resolved Hide resolved
src/Transformations.jl Outdated Show resolved Hide resolved
@mofeing
Copy link
Member

mofeing commented Jul 3, 2023

I think it's best to directly remove the indices whose resulting dimension is 1. What do you think @jofrevalles?

Maybe we could extend dropdims for Tensors, right? This would be easier.

Yeah, that seems correct to me.

@mofeing
Copy link
Member

mofeing commented Jul 3, 2023

@jofrevalles I've implemented dropdims for Tensor and released in the new Tensors v0.1.9 release. Update the compat section to get the dropdims method.

@jofrevalles
Copy link
Member Author

@mofeing In the quimb library, they choose whether to apply split-simplification to a tensor based on the condition if max(prod(size(u)), prod(size(v))) < prod(size(tensor)). Here, u and v are the tensors obtained from the SVD decomposition of a given tensor. This condition essentially checks if the total number of elements in the larger of the two new tensors (resulting from the split) is less than the number of elements in the original tensor, aiming for a reduction in total tensor elements.

In our current implementation, we've been using a slightly different approach by examining the rank of the singular values. Our idea is to perform the split if there are some singular values that are zero. I believe this approach is equivalent to quimb's, but it saves us the computational expense of having to truncate the tensors after SVD.

Please let me know your thoughts on this.

@mofeing
Copy link
Member

mofeing commented Jul 4, 2023

Both conditions should be equivalent mathematically, so our implementation should be correct.

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.

I'm committing this minor fixes and it should be ready to merge.

src/Transformations.jl Outdated Show resolved Hide resolved
src/Transformations.jl Outdated Show resolved Hide resolved
src/Transformations.jl Outdated Show resolved Hide resolved
Co-authored-by: Sergio Sánchez Ramírez <[email protected]>
@mofeing mofeing merged commit 64005a1 into master Jul 4, 2023
4 of 5 checks passed
@mofeing mofeing deleted the feature/split-transformation branch July 4, 2023 10:24
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.

Implement "Split simplification" transformation
2 participants