ITensors中关于的"linkdims="使用的问题

在创建MPS或者是randomMPS的过程中,在教程文档中发现有一个可选参数是"linkdims=",我挺好奇他的作用是什么,于是进行了如下简单测试

julia> using ITensors

julia> sites=siteinds("S=1/2",5)
5-element Vector{Index{Int64}}:
 (dim=2|id=777|"S=1/2,Site,n=1")
 (dim=2|id=454|"S=1/2,Site,n=2")
 (dim=2|id=617|"S=1/2,Site,n=3")
 (dim=2|id=855|"S=1/2,Site,n=4")
 (dim=2|id=240|"S=1/2,Site,n=5")

julia> psi0=randomMPS(sites)
MPS
[1] ((dim=2|id=777|"S=1/2,Site,n=1"), (dim=1|id=832|"Link,l=1"))
[2] ((dim=1|id=832|"Link,l=1"), (dim=2|id=454|"S=1/2,Site,n=2"), (dim=1|id=296|"Link,l=2"))
[3] ((dim=1|id=296|"Link,l=2"), (dim=2|id=617|"S=1/2,Site,n=3"), (dim=1|id=213|"Link,l=3"))
[4] ((dim=1|id=213|"Link,l=3"), (dim=2|id=855|"S=1/2,Site,n=4"), (dim=1|id=959|"Link,l=4"))
[5] ((dim=1|id=959|"Link,l=4"), (dim=2|id=240|"S=1/2,Site,n=5"))

julia> orthogonalize!(psi0,3)
MPS
[1] ((dim=2|id=777|"S=1/2,Site,n=1"), (dim=1|id=127|"Link,l=1"))
[2] ((dim=2|id=454|"S=1/2,Site,n=2"), (dim=1|id=127|"Link,l=1"), (dim=1|id=877|"Link,l=2"))
[3] ((dim=2|id=617|"S=1/2,Site,n=3"), (dim=1|id=213|"Link,l=3"), (dim=1|id=877|"Link,l=2"))
[4] ((dim=1|id=213|"Link,l=3"), (dim=2|id=855|"S=1/2,Site,n=4"), (dim=1|id=959|"Link,l=4"))
[5] ((dim=1|id=959|"Link,l=4"), (dim=2|id=240|"S=1/2,Site,n=5"))

julia> U,S,V=svd(psi0[3],(linkinds(psi0,2),siteinds(psi0,3)))
ITensors.TruncSVD(ITensor ord=3
Dim 1: (dim=2|id=617|"S=1/2,Site,n=3")
Dim 2: (dim=1|id=877|"Link,l=2")
Dim 3: (dim=1|id=90|"Link,u")
NDTensors.Dense{Float64, Vector{Float64}}
 2×1×1
[:, :, 1] =
  0.3998390902383284
 -0.9165853489541417, ITensor ord=2
Dim 1: (dim=1|id=90|"Link,u")
Dim 2: (dim=1|id=413|"Link,v")
NDTensors.Diag{Float64, Vector{Float64}}
 1×1
 0.9999999999999997, ITensor ord=2
Dim 1: (dim=1|id=213|"Link,l=3")
Dim 2: (dim=1|id=413|"Link,v")
NDTensors.Dense{Float64, Vector{Float64}}
 1×1
 1.0, Spectrum{Vector{Float64}, Float64}([0.9999999999999993], 0.0), (dim=1|id=90|"Link,u"), (dim=1|id=413|"Link,v"))

首先我创建了有5个sites的自旋链,然后使用randomMPS创建了一个随机MPS的psi0,接着使用orthogonalize!更新psi0的值,使其以第3个site为中心进行正交化,接着对psi0进行svd分解,得到的结果中可以看到:如果在randomMPS过程中未指定linkdims,那么创建的MPS中的linkdim将全为1;这也导致了我们做svd分解得到的奇异值只有一个。

对svd分解不熟的读者参见链接

julia> psi0=randomMPS(sites;linkdims=4)
MPS
[1] ((dim=2|id=777|"S=1/2,Site,n=1"), (dim=4|id=144|"Link,l=1"))
[2] ((dim=4|id=144|"Link,l=1"), (dim=2|id=454|"S=1/2,Site,n=2"), (dim=4|id=137|"Link,l=2"))
[3] ((dim=4|id=137|"Link,l=2"), (dim=2|id=617|"S=1/2,Site,n=3"), (dim=4|id=419|"Link,l=3"))
[4] ((dim=4|id=419|"Link,l=3"), (dim=2|id=855|"S=1/2,Site,n=4"), (dim=2|id=793|"Link,l=4"))
[5] ((dim=2|id=793|"Link,l=4"), (dim=2|id=240|"S=1/2,Site,n=5"))

julia> orthogonalize!(psi0,3)
MPS
[1] ((dim=2|id=777|"S=1/2,Site,n=1"), (dim=2|id=68|"Link,l=1"))
[2] ((dim=2|id=454|"S=1/2,Site,n=2"), (dim=2|id=68|"Link,l=1"), (dim=4|id=660|"Link,l=2"))
[3] ((dim=2|id=617|"S=1/2,Site,n=3"), (dim=4|id=419|"Link,l=3"), (dim=4|id=660|"Link,l=2"))
[4] ((dim=4|id=419|"Link,l=3"), (dim=2|id=855|"S=1/2,Site,n=4"), (dim=2|id=793|"Link,l=4"))
[5] ((dim=2|id=793|"Link,l=4"), (dim=2|id=240|"S=1/2,Site,n=5"))

julia> U,S,V=svd(psi0[3],(linkinds(psi0,2),siteinds(psi0,3)))
ITensors.TruncSVD(ITensor ord=3
Dim 1: (dim=2|id=617|"S=1/2,Site,n=3")
Dim 2: (dim=4|id=660|"Link,l=2")
Dim 3: (dim=4|id=452|"Link,u")
NDTensors.Dense{Float64, Vector{Float64}}
 2×4×4
[:, :, 1] =
 0.2533027715297858  -0.11290055513641781  -0.10779798139105988  -0.0425664233268372
 0.9470843248865778  -0.07915018305035394  -0.03339714134551804  -0.07286992812929882

[:, :, 2] =
 -0.19298106444664254  -0.4515510126663929  0.060775932357448575  -0.193757175744999
 -0.07399376654891095  -0.6930383162825503  0.35867527816665495   -0.3212464694383822

[:, :, 3] =
  0.5482981693901439    0.1648346326980671  -0.6942658698386402    0.07559143771300501
 -0.24094430487417476  -0.3259550557447053  -0.10460341493752746  -0.09610810056890372

[:, :, 4] =
 -0.7090146314635059    0.34518474343783057  -0.5328241243308826    -0.20531480481603134
  0.16343994634940495  -0.09174803279441616   0.005441253744766603   0.13011573270037222, ITensor ord=2
Dim 1: (dim=4|id=452|"Link,u")
Dim 2: (dim=4|id=387|"Link,v")
NDTensors.Diag{Float64, Vector{Float64}}
 4×4
 0.8129226236883148  0.0                 0.0                 0.0
 0.0                 0.5123617636144631  0.0                 0.0
 0.0                 0.0                 0.2657922315772305  0.0
 0.0                 0.0                 0.0                 0.0774384963359903, ITensor ord=2
Dim 1: (dim=4|id=419|"Link,l=3")
Dim 2: (dim=4|id=387|"Link,v")
NDTensors.Dense{Float64, Vector{Float64}}
 4×4
 -0.4462604293364623    0.026587873542846252   0.8026199738654727    0.3948998502672461
  0.39933358449436096  -0.8822246556447892     0.24939535022552212   0.0037821360641111393
 -0.7260290912247391   -0.4625327956489041    -0.47637894347310933   0.17890856284714832
 -0.3380326555211795   -0.08388179124286545    0.25819806167653675  -0.9011279209111587, 
Spectrum{Vector{Float64}, Float64}([0.6608431921042934, 0.26251457681412294, 0.07064551036680411, 0.005996720714779183], 0.0), (dim=4|id=452|"Link,u"), (dim=4|id=387|"Link,v"))

接着我们测试了在创建psi0的时候定义"linkdims=4",接下来的操作同上,进行中心正交化和svd分解,可以看到奇异值增加到了四个。

继续

julia> psi0=randomMPS(sites;linkdims=10)
MPS
[1] ((dim=2|id=777|"S=1/2,Site,n=1"), (dim=10|id=655|"Link,l=1"))
[2] ((dim=10|id=655|"Link,l=1"), (dim=2|id=454|"S=1/2,Site,n=2"), (dim=8|id=49|"Link,l=2"))
[3] ((dim=8|id=49|"Link,l=2"), (dim=2|id=617|"S=1/2,Site,n=3"), (dim=4|id=810|"Link,l=3"))
[4] ((dim=4|id=810|"Link,l=3"), (dim=2|id=855|"S=1/2,Site,n=4"), (dim=2|id=692|"Link,l=4"))
[5] ((dim=2|id=692|"Link,l=4"), (dim=2|id=240|"S=1/2,Site,n=5"))


julia> psi0=randomMPS(sites;linkdims=12)
MPS
[1] ((dim=2|id=777|"S=1/2,Site,n=1"), (dim=12|id=288|"Link,l=1"))
[2] ((dim=12|id=288|"Link,l=1"), (dim=2|id=454|"S=1/2,Site,n=2"), (dim=8|id=959|"Link,l=2"))
[3] ((dim=8|id=959|"Link,l=2"), (dim=2|id=617|"S=1/2,Site,n=3"), (dim=4|id=303|"Link,l=3"))
[4] ((dim=4|id=303|"Link,l=3"), (dim=2|id=855|"S=1/2,Site,n=4"), (dim=2|id=383|"Link,l=4"))
[5] ((dim=2|id=383|"Link,l=4"), (dim=2|id=240|"S=1/2,Site,n=5"))


julia> orthogonalize!(psi0,3)
MPS
[1] ((dim=2|id=777|"S=1/2,Site,n=1"), (dim=2|id=540|"Link,l=1"))
[2] ((dim=2|id=454|"S=1/2,Site,n=2"), (dim=2|id=540|"Link,l=1"), (dim=4|id=372|"Link,l=2"))
[3] ((dim=2|id=617|"S=1/2,Site,n=3"), (dim=4|id=303|"Link,l=3"), (dim=4|id=372|"Link,l=2"))
[4] ((dim=4|id=303|"Link,l=3"), (dim=2|id=855|"S=1/2,Site,n=4"), (dim=2|id=383|"Link,l=4"))
[5] ((dim=2|id=383|"Link,l=4"), (dim=2|id=240|"S=1/2,Site,n=5"))


julia> U,S,V=svd(psi0[3],(linkinds(psi0,2),siteinds(psi0,3)))
ITensors.TruncSVD(ITensor ord=3
Dim 1: (dim=2|id=617|"S=1/2,Site,n=3")
Dim 2: (dim=4|id=372|"Link,l=2")
Dim 3: (dim=4|id=270|"Link,u")
NDTensors.Dense{Float64, Vector{Float64}}
 2×4×4
[:, :, 1] =
 -0.5464174373757957   0.45888580716451005   0.16666369347994472  0.206562144732366
  0.3916166629929395  -0.35483384019223696  -0.19036177106133295  0.3238808808696971

[:, :, 2] =
 0.4363905420896381  0.37032266738765024  -0.09336244838020219  -0.22858171355150397
 0.1329612665872821  0.4075802875807118   -0.5342642965030376    0.3771200637743431

[:, :, 3] =
 -0.5865500158494377   -0.352359890840481     0.14197554506293383  -0.274779648717522
  0.04066056713682271   0.43620900338635016  -0.44269924448805376  -0.21960527785818795

[:, :, 4] =
 -0.14615732603789583  0.6475776945188965  -0.0465829624078394    0.23599990154826261
 -0.17027675529737574  0.4410080726528175   0.18127406394956994  -0.4950481389614698, ITensor ord=2
Dim 1: (dim=4|id=270|"Link,u")
Dim 2: (dim=4|id=55|"Link,v")
NDTensors.Diag{Float64, Vector{Float64}}
 4×4
 0.6515122075090338  0.0                 0.0                 0.0
 0.0                 0.6317194321743365  0.0                 0.0
 0.0                 0.0                 0.3867383559974809  0.0
 0.0                 0.0                 0.0                 0.16399953195178998, ITensor ord=2
Dim 1: (dim=4|id=303|"Link,l=3")
Dim 2: (dim=4|id=55|"Link,v")
NDTensors.Dense{Float64, Vector{Float64}}
 4×4
  0.29627935454618776  -0.8996214185687609    0.09552574214758623  -0.30622651731876166
 -0.5237389971890132   -0.4184167168264435   -0.4667065309757959    0.5768968086652639
 -0.7947466974749519   -0.06997104894389002   0.4202634482756276   -0.43227349352675876
  0.07933280371825827  -0.10350268905783228   0.7722942966092462    0.6217354896069774, 
Spectrum{Vector{Float64}, Float64}([0.42446815653329434, 0.3990694409866661, 0.14956655599963428, 0.026895846480406185], 0.0), (dim=4|id=270|"Link,u"), (dim=4|id=55|"Link,v"))

接着我们把linkdims分别设置为了10和12,看到psi0中的dims除了第一项和我们的设置一样以外,其他的linkdims均保持不变,在进行完中心正交化之后发现,正交之后的MPS与linkdims=4的MPS是完全一样的,这说明了什么?

说明了当我们的自旋链是有限的时候,体系的linkdims是有上限的,只要设置超过了这个上限,最后的奇异值都是不变的,当然对应的纠缠熵也是不变的。但是当我们的体系很大的时候就需要使用linkdims对系统进行截断,扔掉奇异值较小的部分,进行计算。

最后说一句,在上述验证中,不需要关注为什么他们几次svd分解的奇异值不一样,因为我们每次都在使用randomMPS,所以每次MPS具体的值都是变化的,奇异值自然是不一样的。

posted @ 2026-04-15 02:07  欢腾嘻嘻  阅读(4)  评论(0)    收藏  举报