Hi everyone,
Not sure if this question truly belongs to the ITensor genre, but anyway I already struggled for quite some time before I decided to post here for help.
So basically my goal is to perform state preparation: to approximate a target state obtained via Trotterized time evolution of a simple XY model with a variational ansatz, similar to the way as done in: ITensors.jl/src/lib/ITensorMPS/examples/autodiff/circuit_optimization/vqe.jl at main · ITensor/ITensors.jl · GitHub
The time evolution code is easy (so I won’t show it here, and I benchmarked already with small system sizes). The issue is the variational optimization (that’s why I wonder if this is a truly question related to ITensor or not). I am trying to using a layer ansatz with R_n gates and CNOT gates which are different from the ansatz given in the above example link for VQE. For a small system as N=6, no matter how many depths (ndepth
in the code below; each depth means one odd layer and one even layer) I use, I am not able to obtain a converged result, as the loss function got stuck at about -0.75. Ideally, it should go to -0.999999\cdots.
I suspect that it got stuck in a local minimum? To this end, I think this might have something to do with the classical optimization part. I’m not that familiar with the \texttt{optimkit.jl}, but it seems that it has not been updated on github for some time or so? Should I explore to find a good optimization package in Julia?
Thank you!
s = siteinds("Qubit", nsites)
ψ0 = ψ_initial # a trivial initial state with |010101...>
function loss(θ0)
nsites = length(ψ0)
s = siteinds(ψ0)
order = 1
VQC_total_ansatz = []
for d in range(1,step=1,length=Int64(ndepth))
# odd sub-layer
CX_odd_layer = [];
Rn_odd_layer = [];
VQC_odd_layer = [];
for i in CX_odd_ls
CX_odd_layer = [CX_odd_layer; ("CX", (i, i + 1))];
end
for i in range(1,step=1,length=Int64(nsites))
Rn_odd_layer = [Rn_odd_layer; ("Rn", (i,), (θ=θ0[order],ϕ=θ0[order+1],λ=θ0[order+2]))];
order = order + 3;
end
VQC_odd_layer = [VQC_odd_layer; CX_odd_layer; Rn_odd_layer];
# even sub-layer
CX_even_layer = [];
Rn_even_layer = [];
VQC_even_layer = [];
for i in CX_even_ls
CX_even_layer = [CX_even_layer; ("CX", (i, i + 1))];
end
for i in range(2,step=1,length=Int64(nsites-2))
Rn_even_layer = [Rn_even_layer; ("Rn", (i,), (θ=θ0[order],ϕ=θ0[order+1],λ=θ0[order+2]))];
order = order + 3;
end
VQC_even_layer = [VQC_even_layer; CX_even_layer; Rn_even_layer];
VQC_single_ansatz = [VQC_odd_layer; VQC_even_layer]
VQC_total_ansatz = [VQC_total_ansatz;VQC_single_ansatz];
end
U0 = VQC_total_ansatz;
U1 = ops(U0, s)
ψu = apply(U1, ψ0; cutoff=1e-8)
return -abs(inner(ψf,ψu))^2
end
@show loss(θ0)
println("\nOptimize circuit with gradient optimization")
loss_∇loss(x) = (loss(x), convert(Vector, loss'(x)))
algorithm = LBFGS(; gradtol=gradtol, verbosity=2)
θₒₚₜ, lossₒₚₜ, ∇lossₒₚₜ, numfg, normgradhistory = optimize(loss_∇loss, θ0, algorithm)
@show loss(θₒₚₜ)