Skip to content

Commit

Permalink
Add Two Spin Tests (#26)
Browse files Browse the repository at this point in the history
* reorg test constants and transverse ising hamiltonian
* add basic two spin analytical solution tests
* clean up analytical models and revise their function apis
* improve test naming conventions
  • Loading branch information
ccoffrin committed Feb 25, 2022
1 parent 4037d0e commit 9b8dab0
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 109 deletions.
64 changes: 44 additions & 20 deletions test/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,78 +69,102 @@

end


@testset "ising energy computations" begin

@testset "single qubit, single state" begin
@testset "1 qubit, single state" begin
@test isapprox(eval_ising_state_energy([1],Dict((1,) => 1)), 1)
@test isapprox(eval_ising_state_energy([-1],Dict((1,) => 1)), -1)
end

@testset "single qubit, all states" begin
@testset "1 qubit, all states" begin
energies = compute_ising_state_energies(Dict((1,) => 1))
@test isapprox(energies[0], 1)
@test isapprox(energies[1], -1)
end

@testset "two qubit, single state" begin
@testset "2 qubit, single state" begin
ising_model = Dict((1,) => 1, (2,) => 1, (1,2) => -1)
@test isapprox(eval_ising_state_energy([1, 1], ising_model), 1)
@test isapprox(eval_ising_state_energy([1, -1], ising_model), 1)
@test isapprox(eval_ising_state_energy([-1, 1], ising_model), 1)
@test isapprox(eval_ising_state_energy([-1, -1], ising_model), -3)
end

@testset "two qubit, all state energies" begin
@testset "2 qubit, all state energies" begin
energies = compute_ising_state_energies(Dict((1,) => 1, (1,2) => -1))
@test isapprox(energies[0], 0)
@test isapprox(energies[1], 0)
@test isapprox(energies[2], 2)
@test isapprox(energies[3], -2)
end

@testset "two qubit, energy levels" begin
@testset "2 qubit, energy levels" begin
energy_levels = compute_ising_energy_levels(Dict((1,2) => -1))
@test energy_levels[1].energy == -1.0
@test energy_levels[1].states == Set([0,3])
@test energy_levels[2].energy == 1.0
@test energy_levels[2].states == Set([1,2])
end

@testset "two qubit, print energy levels" begin
@testset "2 qubit, print energy levels" begin
mktemp() do path,io
out = stdout
err = stderr
redirect_stdout(io)
redirect_stderr(io)

print_ising_energy_levels(Dict((1,2) => -1))
print_ising_energy_levels(Dict((1,2) => -1), limit=0)
print_ising_energy_levels(Dict((1,2) => -1), limit=1)
print_ising_energy_levels(Dict((1,2) => -1), limit=10)

print_ising_energy_levels(two_spin_model)
print_ising_energy_levels(two_spin_model, limit=0)
print_ising_energy_levels(two_spin_model, limit=1)
print_ising_energy_levels(two_spin_model, limit=10)
flush(io)
redirect_stdout(out)
redirect_stderr(err)
end
end

@testset "transverse ising hamiltonian building" begin
ising_model = Dict((1,) => 1)
annealing_schedule = AS_CIRCULAR
end


H_00 = transverse_ising_hamiltonian(ising_model, annealing_schedule, 0.0)
H_05 = transverse_ising_hamiltonian(ising_model, annealing_schedule, 0.5)
H_10 = transverse_ising_hamiltonian(ising_model, annealing_schedule, 1.0)
@testset "transverse ising hamiltonian" begin

@testset "1 qubit, analytical solution" begin
@test all(isapprox(one_spin_H(s), transverse_ising_hamiltonian(one_spin_model, AS_CIRCULAR, s)) for s in s_100)
end

@testset "2 qubit, analytical solution" begin
@test all(isapprox(two_spin_H(s), transverse_ising_hamiltonian(two_spin_model, AS_CIRCULAR, s)) for s in s_100)
end

@testset "1 qubit, linear schedule" begin
annealing_schedule = AS_LINEAR

H_00 = transverse_ising_hamiltonian(one_spin_model, annealing_schedule, 0.0)
H_05 = transverse_ising_hamiltonian(one_spin_model, annealing_schedule, 0.5)
H_10 = transverse_ising_hamiltonian(one_spin_model, annealing_schedule, 1.0)

@test isapprox(H_00, [0 1; 1 0])
@test isapprox(H_05, [1/sqrt(2) 1/sqrt(2); 1/sqrt(2) -1/sqrt(2)])
@test isapprox(H_05, [0.5 0.5; 0.5 -0.5])
@test isapprox(H_10, [1 0; 0 -1])
end

@testset "2 qubit, linear schedule" begin
annealing_schedule = AS_LINEAR

H_00 = transverse_ising_hamiltonian(two_spin_model, annealing_schedule, 0.0)
H_05 = transverse_ising_hamiltonian(two_spin_model, annealing_schedule, 0.5)
H_10 = transverse_ising_hamiltonian(two_spin_model, annealing_schedule, 1.0)

@test isapprox(H_00, [0.0 1.0 1.0 0.0; 1.0 0.0 0.0 1.0; 1.0 0.0 0.0 1.0; 0.0 1.0 1.0 0.0])
@test isapprox(H_05, [1.0 0.5 0.5 0.0; 0.5 -1.0 0.0 0.5; 0.5 0.0 -1.0 0.5; 0.0 0.5 0.5 1.0])
@test isapprox(H_10, [2.0 0.0 0.0 0.0; 0.0 -2.0 0.0 0.0; 0.0 0.0 -2.0 0.0; 0.0 0.0 0.0 2.0])
end

end


@testset "csv annealing schedules" begin
s_100 = range(0, 1, length=100)
s_10000 = range(0, 1, length=10000)

@testset "piecewise constant" begin
deltas = [AS_CIRCULAR.A(s) - AS_CIRCULAR_pwc_csv_100.A(s) for s in s_100]
Expand Down
51 changes: 40 additions & 11 deletions test/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,63 @@ X = [0 1; 1 0]
Y = [0 -im; im 0]
Z = [1 0; 0 -1]

function single_spin_h(s; T=1.0)
r = 2.0 * T
ω0 = π/2
ω1 = sqrt(4.0 * T^2 + π^2/4.0)

return r*cos(ω0*s)*[1.0;0.0;0.0] + r*sin(ω0*s)*[0.0;0.0;1.0]

### An analytical solution to the following 1 qubit model
### using the AS_CIRCULAR annealing schedule

one_spin_model = Dict((1,) => 1)

function one_spin_H(s)
return cos(s*π/2)*X + sin(s*π/2)*Z
end

function single_spin_ψ(s; T=1.0)
function one_spin_ρ(T; s=1.0)
r = 2.0 * T
ω0 = π/2
ω1 = sqrt(4.0 * T^2 + π^2/4.0)

a = -((r^2.0) + (ω0^2.0)*cos(ω1*s))*cos(ω0*s) - ω0*ω1*sin(ω0*s)*sin(ω1*s)
b = -r*ω0*(1.0 - cos(ω1*s))
c = -((r^2.0) + (ω0^2.0)*cos(ω1*s))*sin(ω0*s) + ω0*ω1*cos(ω0*s)*sin(ω1*s)
return [a; b; c;] ./ (ω1^2.0)

ψs = [a; b; c;] ./ (ω1^2.0)

return (I + ψs[1]*X + ψs[2]*Y + ψs[3]*Z)/2.0
end

function single_spin_H(s)


### An analytical solution to the following 2 qubit model
### using the AS_CIRCULAR annealing schedule

two_spin_model = Dict((1,2) => 2)

function two_spin_H(s)
X = Complex{Float64}[0.0 1.0 1.0 0.0; 1.0 0.0 0.0 1.0; 1.0 0.0 0.0 1.0; 0.0 1.0 1.0 0.0]
Z = Complex{Float64}[2.0 0.0 0.0 0.0; 0.0 -2.0 0.0 0.0; 0.0 0.0 -2.0 0.0; 0.0 0.0 0.0 2.0]
return cos(s*π/2)*X + sin(s*π/2)*Z
end

function single_spin_ρ(s; T=1.0)
ψs = single_spin_ψ(s, T=T)
return (I + ψs[1]*X + ψs[2]*Y + ψs[3]*Z)/2.0
function two_spin_ρ(t; s=1.0)
s0 = 1/2*cos/4*s*sqrt(1+64*t^2/π^2))*sqrt(1-sin/2*s)) +
(8im*t*sqrt(1-sin/2*s)) + sqrt(1+sin/2*s)))*sin/4*s*sqrt(1+64*t^2/π^2))/(2*sqrt(1+64*t^2/π^2))
s1 = -(cos/4*s*sqrt(1+64*t^2/π^2))*(1+sin/2*s)) +
((-cos/2*s) + 8im*t*(1+sin/2*s))/π)*(sin/4*s*sqrt(1+64*t^2/π^2))))/(sqrt(1+64*t^2/π^2))
)/(2*sqrt(1+sin/2*s)))
s2 = s1
s3 = s0

sv = [s0, s1, s2, s3]

return sv*sv'
end



s_100 = range(0, 1, length=100)
s_10000 = range(0, 1, length=10000)

AS_CIRCULAR_pwc_csv_100 = parse_dwave_annealing_schedule("data/trig_sched_100.csv", interpolation=:none, initial_state=default_initial_state)
AS_CIRCULAR_pwc_csv_1000 = parse_dwave_annealing_schedule("data/trig_sched_1000.csv", interpolation=:none, initial_state=default_initial_state)

Expand Down
Loading

0 comments on commit 9b8dab0

Please sign in to comment.