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

Generalize infsiteinds to fractional QN densities #69

Merged
merged 29 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4ff1e6d
CompatHelper: bump compat for KrylovKit to 0.6, (keep existing compat)
Jan 24, 2023
e0091fd
Merge pull request #238 from LHerviou/compathelper/new_version/2023-0…
LHerviou Jan 24, 2023
2df126c
Format .jl files
mtfishman Feb 20, 2023
6d4e474
Merge branch 'ITensor:main' into main
LHerviou Feb 20, 2023
d4478f4
Merge pull request #239 from LHerviou/auto-juliaformatter-pr
LHerviou Feb 20, 2023
92d48c7
Fixing infsiteinds to accept "fractional" fluxes
LHerviou Feb 20, 2023
1ef6589
Update ITensorInfiniteMPS.jl
LHerviou Feb 20, 2023
c99718d
Fixing formatting
LHerviou Feb 20, 2023
5a53cbd
Forgot to define multiply
LHerviou Feb 20, 2023
cf767cf
Format .jl files
mtfishman Feb 21, 2023
6e24796
Merge branch 'ITensor:main' into main
LHerviou Mar 20, 2023
aec1ced
Merge pull request #240 from LHerviou/auto-juliaformatter-pr
LHerviou Mar 20, 2023
86e2064
Polished treatment of qns
LHerviou Mar 20, 2023
aa290fe
Format .jl files
mtfishman Mar 21, 2023
73f1f18
Fixing tests
LHerviou Mar 21, 2023
08eb569
Merge branch 'fixing_indices' into auto-juliaformatter-pr
LHerviou Mar 21, 2023
f87343f
Merge pull request #242 from LHerviou/auto-juliaformatter-pr
LHerviou Mar 21, 2023
c9a3a7d
Merge pull request #241 from LHerviou/fixing_indices
LHerviou Mar 21, 2023
79739c4
Improving some error messages
LHerviou Mar 21, 2023
a323971
Merge pull request #243 from LHerviou/fixing_indices
LHerviou Mar 21, 2023
695e0ce
Taking into account Mat comment
LHerviou Mar 22, 2023
60f9799
Update infinitecanonicalmps.jl
LHerviou Mar 22, 2023
eb1daca
Further simplification of the code
LHerviou Mar 22, 2023
0816e05
Merge pull request #244 from LHerviou/fixing_indices
LHerviou Mar 22, 2023
4801dbf
Better auto qns for Zn symmetries
LHerviou Mar 27, 2023
3ba996f
Merge pull request #246 from LHerviou/fixing_indices
LHerviou Mar 28, 2023
1a6038b
Comments and test
LHerviou Mar 28, 2023
7234efa
Debug
LHerviou Mar 28, 2023
96f4802
Merge pull request #247 from LHerviou/fixing_indices
LHerviou Mar 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 91 additions & 4 deletions src/infinitecanonicalmps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,47 @@ end

# TODO: Move to ITensors.jl
function Base.:/(qnval::ITensors.QNVal, n::Int)
div_val = ITensors.val(qnval) / n
if !isinteger(div_val)
error("Dividing $qnval by $n, the resulting QN value is not an integer")
if abs(qnval.modulus) <= 1
div_val = ITensors.val(qnval) / n
if !isinteger(div_val)
error("Dividing $qnval by $n, the resulting QN value is not an integer")
end
return setval(qnval, Int(div_val))
else
if mod(qnval.val, gcd(qnval.modulus, n)) != 0
error("Dividing $qnval by $n, no solution to the Chinese remainder theorem")
end
#We perform a brute force sieving solution -> should be ok for all reasonnable n
sol = qnval.val
for x in 1:n
if mod(sol, n) != 0
sol += qnval.modulus
else
break
end
x == n && error("Failed to find solution") #Bezut identity would be a better solver
end
modulus = lcm(qnval.modulus, n)
sol = mod(sol, modulus)
sol = sol < abs(sol - modulus) ? sol : sol - modulus
return setval(qnval, Int(sol / n))
end
return setval(qnval, Int(div_val))
end

function Base.:*(qnval::ITensors.QNVal, n::Int)
prod_val = ITensors.val(qnval) * n
return setval(qnval, Int(prod_val))
end

# TODO: Move to ITensors.jl
function Base.:/(qn::QN, n::Int)
return QN(map(qnval -> qnval / n, qn.data))
end

function Base.:*(qn::QN, n::Int)
return QN(map(qnval -> qnval * n, qn.data))
end

# of Index (Tuple, Vector, ITensor, etc.)
indtype(i::Index) = typeof(i)
indtype(T::Type{<:Index}) = T
Expand Down Expand Up @@ -48,11 +77,69 @@ function shift_flux(i::Index, flux_density::QN)
return ITensors.setspace(i, shift_flux(space(i), flux_density))
end

function scale_flux(qn::ITensors.QNVal, flux_factor::Int)
flux_factor == 1 && return qn #This test could occur earlier
if -1 <= qn.modulus <= 1 #U(1) symmetry, should remain a U(1) symmetry, if qn.modulus = 0, it is a dummy term and the code does nothing
return qn * flux_factor
else #To get the same algebra, multiplying the modulus by flux_factor works
return ITensors.QNVal(qn.name, qn.val * flux_factor, qn.modulus * flux_factor)
end
end

function scale_flux(qn::ITensors.QNVal, flux_factor::Dict{ITensors.SmallString,Int})
!haskey(flux_factor, qn.name) && return qn #Ensure that we do not touch empty QNs or QNs that we do not need to rescale because the shift is 0
return scale_flux(qn, flux_factor[qn.name])
end

function scale_flux(qn::QN, flux_factor::Union{Int,Dict{ITensors.SmallString,Int}})
return QN(map(qnval -> scale_flux(qnval, flux_factor), qn.data))
end

function scale_flux(
qnblock::Pair{QN,Int}, flux_factor::Union{Int,Dict{ITensors.SmallString,Int}}
)
return (scale_flux(ITensors.qn(qnblock), flux_factor) => ITensors.blockdim(qnblock))
end

function scale_flux(
space::Vector{Pair{QN,Int}}, flux_factor::Union{Int,Dict{ITensors.SmallString,Int}}
)
return map(qnblock -> scale_flux(qnblock, flux_factor), space)
end

function scale_flux(i::Index, flux_factor::Union{Int,Dict{ITensors.SmallString,Int}})
return ITensors.setspace(i, scale_flux(space(i), flux_factor))
end

function shift_flux_to_zero(s::Vector{<:Index}, flux::QN)
if iszero(flux)
return s
end
#We are introducing a factor per QN
n = length(s)
multipliers = Dict{ITensors.SmallString,Int}() #multipliers is assigned using the names
for qn in flux.data
if qn.val == 0 #We do not need to multiply in this case. It also takes into account the empty QNs which have val and modulus 0
continue
end
multipliers[qn.name] = abs(lcm(qn.val, n) ÷ qn.val)#default solution with positive multiplier
if abs(qn.modulus) > 1
#We find a multiplier which guarantees a solution of the Chinese theorem
#For now, brute force:
multipliers[qn.name] = abs(lcm(qn.val, n) ÷ qn.val)
for x in 1:(multipliers[qn.name] - 1)
if mod(n, x) != 0
continue
end
if mod(qn.val * x, gcd(n, x * qn.modulus)) == 0
multipliers[qn.name] = x
break
end
end
end
end
s = map(sₙ -> scale_flux(sₙ, multipliers), s)
flux = scale_flux(flux, multipliers)
flux_density = flux / n
return map(sₙ -> shift_flux(sₙ, flux_density), s)
end
Expand Down
6 changes: 3 additions & 3 deletions src/subspace_expansion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function generate_twobody_nullspace(

range_H = nrange(ψ, H[1])

@assert range_H > 1 "Not defined for purely local Hamiltonians"
@assert range_H > 1 "Subspace expansion for InfiniteSum{MPO} is not defined for purely local Hamiltonians"

if range_H > 2
ψᴴ = dag(ψ)
Expand Down Expand Up @@ -181,7 +181,7 @@ function subspace_expansion(
@assert dˡ == dʳ
if dˡ ≥ maxdim
println(
"Current bond dimension at bond $b is $dˡ while desired maximum dimension is $maxdim, skipping bond dimension increase",
"Current bond dimension at bond $b is $dˡ while desired maximum dimension is $maxdim, skipping bond dimension increase at $b",
)
flush(stdout)
flush(stderr)
Expand All @@ -199,7 +199,7 @@ function subspace_expansion(
#Added due to crash during testing
if norm(ψHN2.tensor) < 1e-12
println(
"Impossible to do a subspace expansion, probably due to conservation constraints"
"The two-site subspace expansion produced a zero-norm expansion at $b. This is likely due to the long-range nature of the QN conserving Hamiltonian.",
)
flush(stdout)
flush(stderr)
Expand Down
47 changes: 47 additions & 0 deletions test/test_unitcell_qns.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using ITensors
using ITensorInfiniteMPS
using Test
using Random

@testset "unitcell_qns" begin
function initstate(n)
if n % 2 == 0
if (n / 2) % 2 == 1
return "Dn"
else
return "Up"
end
else
if (n + 1) / 2 <= 19
if ((n + 1) / 2) % 2 == 1
return "Up"
else
return "Dn"
end
else
return "Emp"
end
end
end
conserve_qns = true
N = 62
s = infsiteinds(n -> isodd(n) ? "tJ" : "S=1/2", N; conserve_qns, initstate)
ψ = InfMPS(s, initstate)
@show N
@show s

function initstate(n)
if mod(n, 4) == 1
return 2
else
return 1
end
end

for N in 1:6
s = infsiteinds("S=1/2", N; conserve_szparity=true, initstate)
ψ = InfMPS(s, initstate)
@show N
@show s
mtfishman marked this conversation as resolved.
Show resolved Hide resolved
end
end
2 changes: 1 addition & 1 deletion test/test_vumpsmpo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function expect_three_site(ψ::MPS, h::ITensor, n::Int)
end

#Ref time is 21.6s with negligible compilation time
@time @testset "vumpsmpo_ising" begin
@testset "vumpsmpo_ising" begin
Random.seed!(1234)

model = Model("ising")
Expand Down
2 changes: 1 addition & 1 deletion test/test_vumpsmpo_fqhe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ end

#Currently, VUMPS cannot give the right result as the subspace expansion is too small
#This is meant to test the generalized translation rules
@time @testset "vumpsmpo_fqhe" begin
@testset "vumpsmpo_fqhe" begin
Random.seed!(1234)
function initstate(n)
if mod(n, 3) == 1
Expand Down