-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ITensors] [BUG] Fix bug in
loginner
when inner is negative or comp…
…lex (#945) * Fix bug in `loginner` when inner is negative or complex. * Fix subtraction bug in `OpSum`. * Forward truncation arguments to more operations in `rrule` for `apply`.
- Loading branch information
Showing
10 changed files
with
244 additions
and
8 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using ITensors | ||
using OptimKit | ||
using Zygote | ||
|
||
function ising(n; J, h) | ||
os = OpSum() | ||
for j in 1:(n - 1) | ||
os += -J, "Z", j, "Z", j + 1 | ||
end | ||
for j in 1:n | ||
os += -h, "X", j | ||
end | ||
return os | ||
end | ||
|
||
function loss(H, ψ) | ||
n = length(ψ) | ||
ψHψ = ITensor(1.0) | ||
ψψ = ITensor(1.0) | ||
for j in 1:n | ||
ψHψ = ψHψ * dag(ψ[j]') * H[j] * ψ[j] | ||
ψψ = ψψ * replaceinds(dag(ψ[j]'), s[j]' => s[j]) * ψ[j] | ||
end | ||
return ψHψ[] / ψψ[] | ||
end | ||
|
||
n = 10 | ||
s = siteinds("S=1/2", n) | ||
J = 1.0 | ||
h = 0.5 | ||
|
||
# Loss function only works with `Vector{ITensor}`, | ||
# extract with `ITensors.data`. | ||
ψ0 = ITensors.data(randomMPS(s; linkdims=10)) | ||
H = ITensors.data(MPO(ising(n; J, h), s)) | ||
|
||
loss(ψ) = loss(H, ψ) | ||
|
||
optimizer = LBFGS(; maxiter=25, verbosity=2) | ||
function loss_and_grad(x) | ||
y, (∇,) = withgradient(loss, x) | ||
return y, ∇ | ||
end | ||
ψ, fs, gs, niter, normgradhistory = optimize(loss_and_grad, ψ0, optimizer) | ||
Edmrg, ψdmrg = dmrg(MPO(H), MPS(ψ0); nsweeps=10, cutoff=1e-8) | ||
|
||
@show loss(ψ0), norm(loss'(ψ0)) | ||
@show loss(ψ), norm(loss'(ψ)) | ||
@show loss(ITensors.data(ψdmrg)), norm(loss'(ITensors.data(ψdmrg))) |
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,63 @@ | ||
using ITensors | ||
using KrylovKit | ||
using LinearAlgebra | ||
using MKL | ||
|
||
include("fuse_inds.jl") | ||
|
||
ITensors.Strided.disable_threads() | ||
ITensors.disable_threaded_blocksparse() | ||
|
||
function heisenberg(n) | ||
os = OpSum() | ||
for j in 1:(n - 1) | ||
os += 1 / 2, "S+", j, "S-", j + 1 | ||
os += 1 / 2, "S-", j, "S+", j + 1 | ||
os += "Sz", j, "Sz", j + 1 | ||
end | ||
return os | ||
end | ||
|
||
function main(n; blas_num_threads=Sys.CPU_THREADS, fuse=true, binary=true) | ||
if n > 16 | ||
@warn "System size of $n is likely too large for exact diagonalization." | ||
end | ||
|
||
BLAS.set_num_threads(blas_num_threads) | ||
|
||
# Hilbert space | ||
s = siteinds("S=1/2", n; conserve_qns=true) | ||
H = MPO(heisenberg(n), s) | ||
initstate(j) = isodd(j) ? "↑" : "↓" | ||
ψ0 = randomMPS(s, initstate; linkdims=10) | ||
|
||
edmrg, ψdmrg = dmrg(H, ψ0; nsweeps=10, cutoff=1e-6) | ||
|
||
if fuse | ||
if binary | ||
println("Fuse the indices using a binary tree") | ||
T = fusion_tree_binary(s) | ||
H_full = @time fuse_inds_binary(H, T) | ||
ψ0_full = @time fuse_inds_binary(ψ0, T) | ||
else | ||
println("Fuse the indices using an unbalances tree") | ||
T = fusion_tree(s) | ||
H_full = @time fuse_inds(H, T) | ||
ψ0_full = @time fuse_inds(ψ0, T) | ||
end | ||
else | ||
println("Don't fuse the indices") | ||
@disable_warn_order begin | ||
H_full = @time contract(H) | ||
ψ0_full = @time contract(ψ0) | ||
end | ||
end | ||
|
||
vals, vecs, info = @time eigsolve( | ||
H_full, ψ0_full, 1, :SR; ishermitian=true, tol=1e-6, krylovdim=30, eager=true | ||
) | ||
|
||
@show edmrg, vals[1] | ||
end | ||
|
||
main(14) |
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,91 @@ | ||
using ITensors | ||
|
||
function fusion_tree(s::Vector{<:Index}) | ||
n = length(s) | ||
Cs = Vector{ITensor}(undef, n - 1) | ||
cj = s[1] | ||
for j in 1:(n - 1) | ||
fuse_inds = (cj, s[j + 1]) | ||
Cj = combiner(fuse_inds...) | ||
Cs[j] = Cj | ||
cj = uniqueind(Cj, fuse_inds) | ||
end | ||
return Cs | ||
end | ||
|
||
function fuse_inds(A::MPS, fusion_tree::Vector{ITensor}) | ||
n = length(A) | ||
A_fused = A[1] | ||
for j in 2:n | ||
A_fused = A_fused * A[j] * fusion_tree[j - 1] | ||
end | ||
return A_fused | ||
end | ||
|
||
function fuse_inds(A::MPO, fusion_tree::Vector{ITensor}) | ||
n = length(A) | ||
A_fused = A[1] | ||
for j in 2:n | ||
A_fused = A_fused * A[j] * dag(fusion_tree[j - 1]) * fusion_tree[j - 1]' | ||
end | ||
return A_fused | ||
end | ||
|
||
function fusion_tree_binary_layer(s::Vector{IndexT}; layer=1) where {IndexT<:Index} | ||
n = length(s) | ||
Cs = ITensor[] | ||
cs = IndexT[] | ||
for j in 1:2:(n - 1) | ||
fuse_inds = (s[j], s[j + 1]) | ||
Cj = combiner(fuse_inds...; tags="n=$(j)⊗$(j + 1),l=$(layer)") | ||
push!(Cs, Cj) | ||
cj = uniqueind(Cj, fuse_inds) | ||
push!(cs, cj) | ||
end | ||
if isodd(n) | ||
push!(cs, last(s)) | ||
end | ||
return Cs, cs | ||
end | ||
|
||
function fusion_tree_binary(s::Vector{<:Index}; depth=ceil(Int, log2(length(s)))) | ||
Cs = Vector{ITensor}[] | ||
c_layer = s | ||
for layer in 1:depth | ||
C_layer, c_layer = fusion_tree_binary_layer(c_layer; layer) | ||
push!(Cs, C_layer) | ||
end | ||
return Cs | ||
end | ||
|
||
function fuse_tensors(A::MPS, fusion_tree_layer::Vector{ITensor}, j::Int) | ||
return A[j] * A[j + 1] * fusion_tree_layer[(j + 1) ÷ 2] | ||
end | ||
|
||
function fuse_tensors(A::MPO, fusion_tree_layer::Vector{ITensor}, j::Int) | ||
return A[j] * | ||
A[j + 1] * | ||
dag(fusion_tree_layer[(j + 1) ÷ 2]) * | ||
fusion_tree_layer[(j + 1) ÷ 2]' | ||
end | ||
|
||
function fuse_inds_binary_layer(A::Union{MPS,MPO}, fusion_tree_layer::Vector{ITensor}) | ||
n = length(fusion_tree_layer) | ||
A_fused = ITensor[] | ||
for j in 1:2:(2n) | ||
push!(A_fused, fuse_tensors(A, fusion_tree_layer, j)) | ||
end | ||
if isodd(length(A)) | ||
push!(A_fused, A[end]) | ||
end | ||
return typeof(A)(A_fused) | ||
end | ||
|
||
function fuse_inds_binary(A::Union{MPS,MPO}, fusion_tree::Vector{Vector{ITensor}}) | ||
depth = length(fusion_tree) | ||
A_fused = A | ||
for layer in 1:depth | ||
A_fused = fuse_inds_binary_layer(A_fused, fusion_tree[layer]) | ||
end | ||
return only(A_fused) | ||
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
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
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
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