这里的for center循环我希望每次更新psi
psi,U = itinnerexceptcenter(psi,psio,center);
但好像系统把所有的循环过来的psi都记住了导致了内存随循环次数近线性增长。
该如何降低内存占用,感谢~
using Random
N = 10;#物理格点个数
maxdim=16;
sites=siteinds("S=1/2",N); # siteinds给出后是不会变的 但是linkinds会变化
s=siteinds("S=1/2",N);
#file = h5open("Final MPS.h5", "r")
#psiT=read(file,list_first_level(file)[1],MPS);
Random.seed!(1234)
psiT=randomMPS(ComplexF64, sites; linkdims=64);
psio=randomMPS(ComplexF64, sites; linkdims=64);
"""
innerexcept(psi::MPS, psio::MPS, center::Int)
return the optimised ITensor for center & psi of orthogonal center = center
Inputs:
-------
- psi :MPS as iterative start point
- psio :MPS without truncate
"""
function innerexceptcenter(psi::MPS, psio::MPS, center::Int, N::Int=length(psio))
psi=orthogonalize(psi,center) # 移动正交中心 注意会改变linkinds
psi=dag(psi) # dag 不会改变linkinds
res=ITensor[];
for i in 1:N
if i==center
push!(res,psio[i])
else
push!(res,psio[i]*psi[i])
end
end
L=res[1];
R=res[end];
if center==1 # 仅有R
# 对R计算
for j in (N-1): -1 : (center+1)
R*=res[j]
end
return L*R #再dag回来
elseif center==N # 仅有L
# 对L计算
for j in 2:(center-1)
L*=res[j]
end
return L*R#再dag回来
else
# 对R计算
for j in 2:(center-1)
L*=res[j]
end
# 对R计算
for j in (N-1): -1 : (center+1)
R*=res[j]
end
return L*res[center]*R #再dag回来
end
end
# 迭代方法innerexceptcenter
function itinnerexceptcenter(psi::MPS, psio::MPS, center::Int, N::Int=length(psio))
psi=orthogonalize(psi,center) # 移动正交中心 注意会改变linkinds
psi=dag(psi) # dag 不会改变linkinds 需要dagger才能
function fl(n::Int)
if n==0
return ITensor(1)
else
return psi[n]*psio[n]*fl(n-1)
end
end
function fr(n::Int)
if n==N+1
return ITensor(1)
else
return psi[n]*psio[n]*fr(n+1)
end
end
return dag(psi), fl(center-1)*psio[center]*fr(center+1)
end
"""
iterative_truncate(psio::MPS)
return a MPS global truncated from psio
Inputs:
-------
- psio :MPS that is subjected to truncation
"""
function iterative_truncate(psio::MPS,N::Int=length(psio))
psi=copy(psio);
truncate!(psi;maxdim=maxdim) # psi作为迭代truncate的原始输入 truncate后并不归一!!!
ustart=norm(psi-psio)
observable = ustart
@show ustart
for center in vcat(collect(range(1,N)),reverse(collect(range(1,N))))
psi,U = itinnerexceptcenter(psi,psio,center); #返回正交中心应取的值U以及移动过后的psi
psi[center] .= U;
a=norm(psi-psio)
if a<= observable
observable = a
end
end
uover=observable;
@show uover
return psi;
end
psi=truncate(psiT;maxdim=maxdim)
a=8;
#@time innerexceptcenter(psiT,psiT,a);
#@time itinnerexceptcenter(psiT,psiT,a)
@time iterative_truncate(psiT)