-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathhamiltonian_solvers.jl
50 lines (44 loc) · 1.85 KB
/
hamiltonian_solvers.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
export iter_groundstate!, itime_groundstate!, vqe_solve!
"""
iter_groundstate!({reg::AbstractRegister}, h::AbstractBlock; niter::Int=100) -> AbstractRegister
project wave function to ground state by iteratively apply -h.
"""
iter_groundstate!(h::AbstractBlock; niter::Int=100) = reg -> iter_groundstate!(reg, h, niter=niter)
function iter_groundstate!(reg::AbstractRegister, h::AbstractBlock; niter::Int=100)
for i = 1:niter
reg |> h
i%5 == 0 && reg |> normalize!
end
reg |> normalize!
end
"""
itime_groundstate!({reg::AbstractRegister}, h::AbstractBlock; τ::Int=20, tol=1e-4) -> AbstractRegister
Imaginary time evolution method to get ground state, i.e. by projecting wave function to ground state by exp(-hτ). `tol` is for `expmv`.
"""
itime_groundstate!(h::AbstractBlock; τ::Real=20, tol=1e-4) = reg -> itime_groundstate!(reg, h; τ=τ, tol=tol)
function itime_groundstate!(reg::AbstractRegister, h::AbstractBlock; τ::Int=20, tol=1e-4)
span = 1.0
te = time_evolve(h, -im*span)
for i = 1:τ÷span
reg |> te |> normalize!
end
if τ%span != 0
reg |> time_evolve(h, τ%span) |> normalize!
end
reg
end
import Optimisers
"""
vqe_solve!(circuit::AbstractBlock{N}, hamiltonian::AbstractBlock; niter::Int=100) -> circuit
variational quantum eigensolver, faithful simulation with optimizer `ADAM(0.01)`.
"""
function vqe_solve!(circuit::AbstractBlock{D}, hamiltonian::AbstractBlock; niter::Int=100) where D
params = parameters(circuit)
optimizer = Optimisers.setup(Optimisers.ADAM(0.01), params)
for i = 1:niter
grad = expect'(hamiltonian, zero_state(nqudits(circuit)) => circuit).second
dispatch!(circuit, Optimisers.update!(optimizer, params, grad)[2])
println("Step $i, Energy = $(expect(hamiltonian, zero_state(nqudits(circuit)) |> circuit))")
end
circuit
end