Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed fulltomography #308

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ examples/data/
test/data/
data/
Manifest.toml
.vscode
3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ version = "0.1.0"

[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
Convex = "f65535da-76fb-5f13-bab9-19810c17039a"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5"
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Observers = "338f10d5-c7f1-4033-a7d1-f9dec39bcaa0"
Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
SCS = "c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"

[compat]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ PastaQ.jl is a Julia software toolbox providing a range of computational methods

---
## Install
The PastaQ package can be installed with the Julia package manager. From the Julia REPL, type ] to enter the Pkg REPL mode and run:
The PastaQ package can be installed with the Julia package manager. From the Julia REPL, type `]` to enter the Pkg REPL mode and run:

```julia
julia> ]
Expand Down
19 changes: 11 additions & 8 deletions src/PastaQ.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,23 @@ include("optimizers.jl")
include("productstates.jl")
include("randomstates.jl")
include("measurements.jl")
# included the file and added SCS and Convex to the manifest. Module importing `SCS.MathOptInterface` also does not work, and it needs to be installed and imported separately. This has also been implemented.
# fixed relevant tests as well.
include("tomography/fulltomography.jl")
include("tomography/tensornetwork-statetomography.jl")
include("tomography/tensornetwork-processtomography.jl")
include("tomography/quantumtomography.jl")
include("io.jl")
include("array.jl")
include("utils.jl")

using Requires
function __init__()
@require SCS = "c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13" begin
@require Convex = "f65535da-76fb-5f13-bab9-19810c17039a" include(
"tomography/fulltomography.jl"
)
end
end
# using Requires
# function __init__()
# @require SCS = "c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13" begin
# @require Convex = "f65535da-76fb-5f13-bab9-19810c17039a" include(
# "tomography/fulltomography.jl"
# )
# end
# end

end # module
14 changes: 11 additions & 3 deletions src/tomography/fulltomography.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
const MOI = SCS.MathOptInterface
using Convex
using SCS
import MathOptInterface
const MOI = MathOptInterface

# Added a specific import statement for Convex, SCS and MathOptInterface.
# The earlier implementation ran into a ModuleError here.

function tomography(
probabilities::Dict{Tuple,<:Dict},
Expand Down Expand Up @@ -34,14 +40,16 @@ function tomography(
if (method == "LS" || method == "least_squares")
# Minimize the cost function C = ||A ρ⃗ - p̂||²
cost_function = Convex.norm(A * vec(ρ) - p)
elseif (method == "MLE" || method == "maximum_likelihood")
elseif (method == "ML" || method == "maximum_likelihood")
# Minimize the negative log likelihood:
# Ensured uniformity in documentation and implementation of the maximum_likelihood case.
# the keyword was implemented as "MLS" in some places, "MLE" in some places. Now everything is consistent and two-lettered.
cost_function = -p' * Convex.log(real(A * vec(ρ)) + 1e-10)
else
error("Tomography method not recognized
Currently available methods: - LI : linear inversion
LS : least squares
MLS : maximum likelihood")
ML : maximum likelihood")
end

# Contrained the trace and enforce positivity and hermitianity
Expand Down
55 changes: 33 additions & 22 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,43 @@ using Test
# However this seems to cause some issues with some process
# tomography tests, it seems to be sensitive to the ordering
# they are called.
filenames = [
"test_array.jl",
"test_autodiff.jl",
"test_circuits.jl",
"test_distances.jl",
"test_fulltomography.jl",
"test_gates.jl",
"test_getsamples.jl",
"test_io.jl",
"test_noise.jl",
"test_optimizers.jl",
"test_processtomography.jl",
"test_productstates.jl",
"test_qubitarrays.jl",
"test_randomstates.jl",
"test_runcircuit.jl",
"test_statetomography.jl",
"test_utils.jl",
"test_gpu.jl",
]
# filenames = [
# "test_array.jl",
# "test_autodiff.jl",
# "test_circuits.jl",
# "test_distances.jl",
# "test_fulltomography.jl",
# "test_gates.jl",
# "test_getsamples.jl",
# "test_io.jl",
# "test_noise.jl",
# "test_optimizers.jl",
# "test_processtomography.jl",
# "test_productstates.jl",
# "test_qubitarrays.jl",
# "test_randomstates.jl",
# "test_runcircuit.jl",
# "test_statetomography.jl",
# "test_utils.jl",
# "test_gpu.jl",
# ]

# Implement a single function to read all files with a filter
# all tests now pass, at least with a single thread.
# Also, removed the condition to check if filename starts with "test_" as it is guaranteed by the filter used in searchDir().
# Can upgrade filter to broadcast

searchDir(path, key) = filter(x->(all([ occursin(k,x) for k in key ]) ), readdir(path))
filenames = searchDir("./",["test_",".jl"])

@testset "PastaQ.jl" begin
@testset "$filename" for filename in filenames
if startswith(filename, "test_") && endswith(filename, ".jl")
# if endswith(filename, ".jl") #&& startswith(filename, "test_")
println("Running $filename")
@time include(filename)
end
# end
end

#@time include("test_io.jl")

end
Binary file removed test/simulation_state.h5
Binary file not shown.
Binary file removed test/test_data_writesamples.h5
Binary file not shown.
4 changes: 2 additions & 2 deletions test/test_fulltomography.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ end
λ = first(eigen(ρ))
@test all(real(λ) .≥ -1e-3)

ρ = PastaQ.array(tomography(samples; method="MLE"))
ρ = PastaQ.array(tomography(samples; method="ML")) # Ensured method keyword consistency
λ = first(eigen(ρ))
@test all(real(λ) .≥ -1e-2)
end
Expand All @@ -111,7 +111,7 @@ end
@test tr(ρ) ≈ 2.0
ρ = PastaQ.array(tomography(samples; method="LS", trρ=2.0))
@test tr(ρ) ≈ 2.0 atol = 1e-4
ρ = PastaQ.array(tomography(samples; method="MLE", trρ=2.0))
ρ = PastaQ.array(tomography(samples; method="ML", trρ=2.0)) # Ensured method keyword consistency
@test tr(ρ) ≈ 2.0 atol = 1e-4
end

Expand Down
23 changes: 20 additions & 3 deletions test/test_gpu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ const devices = (

const full_representations = (false, true)

const noises = (nothing, ("amplitude_damping", (γ=0.1,)))
const noises = (nothing,
("amplitude_damping", (γ=0.1,)),
("phase_damping", (γ=0.1,))
)

const processes = (false, true)

@testset "runcircuit with eltype $eltype, device $device, full_representation $full_representation, noise $noise" for eltype in
eltypes,
@testset "runcircuit with eltype $eltype, device $device, full_representation $full_representation, noise $noise" for eltype in eltypes,
device in devices,
full_representation in full_representations,
noise in noises,
Expand All @@ -29,3 +31,18 @@ const processes = (false, true)
@test Base.eltype(ψ[1]) === eltype
end
end

# Added a new test set for depolarizing noise. Since the

@testset "runcircuit with eltype $eltype, device $device, full_representation $full_representation, noise depolarizing" for eltype in (nothing, ComplexF32, ComplexF64),
device in devices,
full_representation in full_representations,
process in processes

ψ = runcircuit([("X", 1)]; eltype, device, full_representation, noise=("depolarizing",(p=0.1,)), process)
if isnothing(eltype)
@test Base.eltype(ψ[1]) === ComplexF64
else
@test Base.eltype(ψ[1]) === eltype
end
end
33 changes: 19 additions & 14 deletions test/test_io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ using JLD2
using HDF5
using Optimisers

# create a data/ directory to store results of testing, so they are not accidentally included in the git.
# This repo is already excluded in the gitignore

Base.mkpath("data/")
prefix = "data"

@testset "write and read samples" begin
N = 4
depth = 2
nshots = 100
circuit = randomcircuit(N; depth=depth, twoqubitgates="CX", onequbitgates="Rx")
path = "test_data_writesamples.h5"
path = prefix*"/"*"test_data_writesamples.h5"

X = runcircuit(circuit)
data = getsamples(X, nshots)
Expand Down Expand Up @@ -107,8 +113,7 @@ end
circuit = randomcircuit(N; depth=depth)
layer = Tuple[]
sites = siteinds("Qubit", N)

outputpath = "simulation"
outputpath = prefix*"/"*"simulation"
ϕ = randomstate(sites; χ=10, normalize=true)
ψ = runcircuit(sites, circuit)
Ftest = fidelity(ψ, ϕ)
Expand All @@ -132,7 +137,7 @@ end
## @test last(v) ≈ obs[!, k]
## end

fin = h5open("simulation_state.h5", "r")
fin = h5open(prefix*"/"*"simulation_state.h5", "r")
M = read(fin, "state", MPS)
close(fin)
@test M ≈ ψ
Expand All @@ -152,7 +157,7 @@ end
Ftest = fidelity(ϱ, ρ)
g(ρ::MPO; kwargs...) = fidelity(ρ, ϱ)#; kwargs...) = fidelity(ψ, ϕ)
obs = observer(["g" => g])
outputpath = "simulation"
outputpath = prefix*"/"*"simulation"
ρ₀ = projector(productstate(sites))
ρ = runcircuit(
ρ₀,
Expand All @@ -174,7 +179,7 @@ end
## @test last(v) ≈ obs[!, k]
## end

fin = h5open("simulation_state.h5", "r")
fin = h5open(prefix*"/"*"simulation_state.h5", "r")
M = read(fin, "state", MPO)
close(fin)
@test M ≈ ρ
Expand Down Expand Up @@ -203,7 +208,7 @@ end
batchsize = 10
observe_step = 3

outputpath = "simulation"
outputpath = prefix*"/"*"simulation"
ψ = tomography(
data,
ψ0;
Expand All @@ -224,7 +229,7 @@ end
## @test last(v) ≈ obs[!, k]
## end

fin = h5open("simulation_state.h5", "r")
fin = h5open(prefix*"/"*"simulation_state.h5", "r")
M = read(fin, "state", MPS)
close(fin)
@test M ≈ ψ
Expand Down Expand Up @@ -253,7 +258,7 @@ end
batchsize = 10
observe_step = 3

outputpath = "simulation"
outputpath = prefix*"/"*"simulation"
ρ = tomography(
data,
ρ;
Expand All @@ -274,7 +279,7 @@ end
## @test last(v) ≈ obs[!, k]
## end

fin = h5open("simulation_state.h5", "r")
fin = h5open(prefix*"/"*"simulation_state.h5", "r")
M = read(fin, "state", LPDO{MPO})
close(fin)
@test M.X ≈ ρ.X
Expand Down Expand Up @@ -303,7 +308,7 @@ end
batchsize = 10
observe_step = 3

outputpath = "simulation"
outputpath = prefix*"/"*"simulation"
U = tomography(
data,
U0;
Expand All @@ -325,7 +330,7 @@ end
## @test last(v) ≈ obs[!, k]
## end

fin = h5open("simulation_state.h5", "r")
fin = h5open(prefix*"/"*"simulation_state.h5", "r")
M = read(fin, "state", MPO)
close(fin)
@test M ≈ U
Expand Down Expand Up @@ -355,7 +360,7 @@ end
batchsize = 10
observe_step = 3

outputpath = "simulation"
outputpath = prefix*"/"*"simulation"
Λ = tomography(
data,
Λ;
Expand All @@ -376,7 +381,7 @@ end
## @test last(v) ≈ obs[!, k]
## end

fin = h5open("simulation_state.h5", "r")
fin = h5open(prefix*"/"*"simulation_state.h5", "r")
M = read(fin, "state", LPDO{MPO})
close(fin)
@test M.X ≈ Λ.X
Expand Down