Hi @JoeyT1994 thank you for your response! The functions scalar
, loginner
, and logscaler
from ITensorNetworks.jl/test/test_inner.jl at main · ITensor/ITensorNetworks.jl · GitHub have the same behavior. The code doesn’t return nan
but I mean a sudden large increase in the probability amplitude value for a bitstring as a state is evolved. The code should return a probability amplitude << 1 for the particular computational bitstring used but returns a finite value of 21.6200042978372. When \chi is increased it does give an expected result so I’m not sure why it is so different for lower \chi. Also tried normalize=True in the apply
function but this gives amplitudes much smaller than expected.
using ITensors
using ITensorNetworks
using NamedGraphs
using NamedGraphs: rem_edge!, add_edge!
using Graphs
using ITensorUnicodePlots
using ITensorNetworks: expect, apply
using Graphs: vertices
using ITensorNetworks:
BeliefPropagationCache,
ITensorNetwork,
VidalITensorNetwork,
environment,
norm_sqr_network,
siteinds,
update,
scalar,
inner_network,
loginner,
logscalar
using ITensors: ITensors, inner, op
using NamedGraphs.NamedGraphGenerators: named_grid
using NamedGraphs.PartitionedGraphs: PartitionVertex
using SplitApplyCombine: group
using ITensorNetworks.ModelHamiltonians: ising
# Sampled computational bitstrings. One in this case.
s_dec = [2095441]
# Convert bitstring decimal to binary
function decimal_to_binary(decimal_number::Int)
binary_digits = String[]
while decimal_number > 0
remainder = decimal_number % 2
pushfirst!(binary_digits, string(remainder))
decimal_number ÷= 2
end
return isempty(binary_digits) ? "0" : join(binary_digits)
end
# Evaluate probabilities corresponding to the sampled computational bitstrings
function main(θh::Float64, no_trotter_steps::Int64; apply_kwargs...)
# Build a system
L = 21
g_dims = (1, 1)
n = prod(g_dims)
g = named_grid(g_dims)
for i in 1:21
add_vertex!(g, (i,i))
end
for i in 1:8
add_edge!(g, (i,i), (i+1,i+1))
end
for i in 13:20
add_edge!(g, (i,i), (i+1,i+1))
end
add_edge!(g, (1,1), (10,10))
add_edge!(g, (10,10), (13,13))
add_edge!(g, (5,5), (11,11))
add_edge!(g, (11,11), (17,17))
add_edge!(g, (9,9), (12,12))
add_edge!(g, (12,12), (21,21))
s = siteinds("S=1/2", g)
ψ = ITensorNetwork(v -> "↑", s)
@visualize ψ
#z-polarized initial state
psi_init = ψ
X = OpSum()
for i=1:L
add!(X, 1.0, "X", (i,i))
end
X = Vector{ITensor}(X, s)
X = vcat(X)
v1, v2 = (1, 1), (2, 2)
ψψ = norm_sqr_network(ψ)
#Simple Belief Propagation Grouping
bp_cache = BeliefPropagationCache(ψψ, group(v -> v[1], vertices(ψψ)))
bp_cache = update(bp_cache; maxiter=20)
envsSBP = environment(bp_cache, PartitionVertex.([v1, v2]))
#Build gates
HX, HZZ = ising(g; h=θh / 2, J1=0), ising(g; h=0, J1=-pi / 4)
RX, RZZ = exp(-im * 2 * HX; alg=Trotter{1}()), exp(-im* 4 * HZZ; alg=Trotter{1}())
RX_gates, RZZ_gates = Vector{ITensor}(RX, s), Vector{ITensor}(RZZ, s)
gates = vcat(RX_gates, RZZ_gates)
for i in 1:no_trotter_steps
for gate in gates
ψ = apply(gate, ψ; envs=envsSBP, nfullupdatesweeps=10, maxdim=χ, cutoff=1e-16)
end
end
# Apply X only at initial state sites where binary digits from the sampled bitstrings are 1.
pztbp = []
for e in s_dec
t1 = time()
psi = psi_init
b = decimal_to_binary(e-1)
b = lpad(b, L, "0")
for i in 1:L
if parse(Int, b[i]) == 1
psi = apply(X[i], psi, cutoff=1e-16)
end
end
# Compute probability amplitude associated with bitstring
push!(pztbp, real(inner(psi, ψ, alg="bp")conj(inner(psi, ψ, alg="bp")))/(real(inner(ψ, ψ, alg="bp"))))
end
println(pztbp)
return pztbp
end
θh = pi / 4
no_trotter_steps = 10
χ = 64
mags = main(θh, no_trotter_steps)