-
Notifications
You must be signed in to change notification settings - Fork 1
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
Add extension to convert
ITensorMPS.MPS
to Tenet.MPS
and viceversa
#251
Merged
Merged
Changes from 5 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
c6440d6
Add TenetITensorsMPSExt extension to convert ITensorsMPS.MPS to Tenet…
jofrevalles fbe5c69
Add tests to conver for the new convert function
jofrevalles 7dd98aa
Add ITensorMPS in weakdeps and add extension dependencies
jofrevalles 959e6a5
Format code
jofrevalles 515ba6b
Add ITensors in TenetITensorMPSExt module
jofrevalles 1aceb9b
Fix typo in Project.toml
jofrevalles e365623
Replace ITensorMPS specific minor version with its major one
jofrevalles a510320
Fix small typos
jofrevalles File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
module TenetITensorMPSExt | ||
|
||
using Tenet | ||
using ITensors: ITensor, Index, dim | ||
using ITensorMPS | ||
using Tenet: MPS, tensors, form, inds | ||
|
||
# Convert an AbstractMPS to an ITensor MPS | ||
function Base.convert(::Type{ITensorMPS.MPS}, mps::Tenet.AbstractMPS) | ||
@assert form(mps) isa MixedCanonical "Currently only MixedCanonical MPS conversion is supported" | ||
|
||
ortho_center = form(mps).orthog_center | ||
|
||
itensors = ITensor[] | ||
for (i, t) in enumerate(tensors(mps)) | ||
t = Tenet.permutedims( | ||
t, | ||
Vector{Symbol}( | ||
filter!( | ||
!isnothing, | ||
[inds(mps; at=Site(i)), inds(mps; at=Site(i), dir=:left), inds(mps; at=Site(i), dir=:right)], | ||
), | ||
), | ||
) | ||
|
||
site_index = Index(size(mps, inds(mps; at=Site(i))), "Site,n=$i") | ||
if i == 1 | ||
link_size = size(mps, inds(mps; at=Site(1), dir=:right)) | ||
link_indices = [Index(link_size, "Link,l=1")] | ||
else | ||
# Take index from previous tensor as the left link index | ||
prev_ind = ITensors.inds(itensors[end])[end] | ||
|
||
if i < length(tensors(mps)) | ||
next_link_size = size(mps, inds(mps; at=Site(i), dir=:right)) | ||
next_ind = Index(next_link_size, "Link,l=$(i)") | ||
link_indices = [prev_ind, next_ind] | ||
else | ||
link_indices = [prev_ind] | ||
end | ||
end | ||
all_indices = (site_index, link_indices...) | ||
|
||
it = ITensor(parent(t), all_indices...) | ||
push!(itensors, it) | ||
end | ||
|
||
itensors_mps = ITensorMPS.MPS(itensors) | ||
|
||
# Set llim and rlim based on the orthogonality center | ||
if isa(ortho_center, Site) | ||
n = Tenet.id(ortho_center) | ||
|
||
itensors_mps.llim = n - 1 | ||
itensors_mps.rlim = n + 1 | ||
elseif isa(ortho_center, Vector{Site}) | ||
ids = Tenet.id.(ortho_center) | ||
|
||
# For multiple orthogonality centers, set llim and rlim accordingly | ||
itensors_mps.llim = minimum(ids) - 1 | ||
itensors_mps.rlim = maximum(ids) + 1 | ||
end | ||
|
||
return itensors_mps | ||
end | ||
|
||
# Convert an ITensor MPS to an MPS | ||
function Base.convert(::Type{MPS}, itensors_mps::ITensorMPS.MPS) | ||
llim = itensors_mps.llim | ||
rlim = itensors_mps.rlim | ||
|
||
# Extract site and link indices | ||
sites = siteinds(itensors_mps) | ||
links = linkinds(itensors_mps) | ||
|
||
tensors_vec = [] | ||
first_ten = array(itensors_mps[1], sites[1], links[1]) | ||
push!(tensors_vec, first_ten) | ||
|
||
# Extract the bulk tensors | ||
for j in 2:(length(itensors_mps) - 1) | ||
ten = array(itensors_mps[j], sites[j], links[j - 1], links[j]) # Indices are ordered as (site index, left link, right link) | ||
push!(tensors_vec, ten) | ||
end | ||
last_ten = array(itensors_mps[end], sites[end], links[end]) | ||
push!(tensors_vec, last_ten) | ||
|
||
mps = Tenet.MPS(tensors_vec) | ||
|
||
# Map llim and rlim to your MPS's orthogonality center(s) | ||
mps_form = if llim + 1 == rlim - 1 | ||
Tenet.MixedCanonical(Tenet.Site(; n=llim + 1)) | ||
elseif llim + 1 < rlim - 1 | ||
Tenet.MixedCanonical([Tenet.Site(j) for j in (llim + 1):(rlim - 1)]) | ||
else | ||
Tenet.NonCanonical() | ||
end | ||
|
||
mps.form = mps_form | ||
|
||
return mps | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
@testset "ITensorMPS" begin | ||
using ITensorMPS | ||
using ITensors: ITensor, Index, dim, dims | ||
using Tenet: MPS, tensors, form | ||
|
||
# Tenet to ITensorMPS conversion | ||
tenet_mps = rand(MPS; n=5, maxdim=30) | ||
itensor_mps = convert(ITensorMPS.MPS, tenet_mps) | ||
|
||
@test length(tensors(tenet_mps)) == length(ITensors.tensors(itensor_mps)) | ||
|
||
for (t1, t2) in zip(tensors(tenet_mps), ITensors.tensors(itensor_mps)) | ||
@test issetequal(size(t1), dims(t2)) | ||
end | ||
|
||
@test itensor_mps.llim == Tenet.id(form(tenet_mps).orthog_center) - 1 | ||
@test itensor_mps.rlim == Tenet.id(form(tenet_mps).orthog_center) + 1 | ||
|
||
contracted = Tenet.contract(tenet_mps) | ||
permuted = permutedims(contracted, [inds(tenet_mps; at=Site(i)) for i in 1:length(tensors(tenet_mps))]) | ||
@test isapprox(parent(permuted), Array(ITensorMPS.contract(itensor_mps).tensor)) | ||
|
||
# ITensorMPS to Tenet conversion | ||
itensor_mps = ITensorMPS.random_mps(siteinds(4, 5); linkdims=7) | ||
tenet_mps = convert(MPS, itensor_mps) | ||
|
||
@test length(ITensors.tensors(itensor_mps)) == length(tensors(tenet_mps)) | ||
|
||
for (t1, t2) in zip(ITensors.tensors(itensor_mps), tensors(tenet_mps)) | ||
@test issetequal(dims(t1), size(t2)) | ||
end | ||
|
||
@test form(tenet_mps) isa MixedCanonical | ||
@test form(tenet_mps).orthog_center == Site(itensor_mps.llim + 1) | ||
@test form(tenet_mps).orthog_center == Site(itensor_mps.rlim - 1) | ||
|
||
contracted = Tenet.contract(tenet_mps) | ||
permuted = permutedims(contracted, [inds(tenet_mps; at=Site(i)) for i in 1:length(tensors(tenet_mps))]) | ||
@test isapprox(parent(permuted), Array(ITensorMPS.contract(itensor_mps).tensor)) | ||
end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmm if we set the patch version, will we have problems when v0.2.7 lands?
like, will it force it to use v0.2.6 or will it be compatible (but not included) up to v0.3.0?
in principle we should only mark major and minor versions, not patch version (unless a patch is completely required for it to work)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmmm I don't know, I just put the version since we also had that for
ITensors
andITensorNetworks
. Do you really think this is a problem?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should try to just set the major.minor version. If you need a higher patch version, you should just call
Pkg.update()
then.