From fd2f47190dbe57721583e68d973144af5de773de Mon Sep 17 00:00:00 2001 From: Abhishek Bhatt <46929125+Abhishek-1Bhatt@users.noreply.github.com> Date: Mon, 18 Sep 2023 00:26:55 -0400 Subject: [PATCH] Added Superdense endcoding and decoding circuits to CircuitZoo (#34) --------- Co-authored-by: Stefan Krastanov --- Project.toml | 2 +- src/CircuitZoo/CircuitZoo.jl | 71 +++++++++++++++++++++ src/backends/quantumoptics/quantumoptics.jl | 1 + test/runtests.jl | 1 + test/test_circuitzoo_superdense.jl | 22 +++++++ 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 test/test_circuitzoo_superdense.jl diff --git a/Project.toml b/Project.toml index b505d9d4..61ec073c 100644 --- a/Project.toml +++ b/Project.toml @@ -39,7 +39,7 @@ PrecompileTools = "1" QuantumClifford = "0.8" QuantumInterface = "0.3.0" QuantumOptics = "1.0.5" -QuantumOpticsBase = "0.4" +QuantumOpticsBase = "0.4.14" QuantumSymbolics = "0.2.4" Reexport = "1.2.2" ResumableFunctions = "0.6.1" diff --git a/src/CircuitZoo/CircuitZoo.jl b/src/CircuitZoo/CircuitZoo.jl index 0e0b91a7..1e6133a3 100644 --- a/src/CircuitZoo/CircuitZoo.jl +++ b/src/CircuitZoo/CircuitZoo.jl @@ -851,4 +851,75 @@ function (circuit::PurifyExpedientNode)(purified,sacrificed...) [a..., b..., c..., d...] end +""" +$TYPEDEF + +Fields: + +$FIELDS + +The circuit for Superdense Coding to encode the 2 (classical) bit message +to its corresponding bell pair representation. `reg` is a single qubit register containing +Alice's half of the entangled bell pair and message is the 2 bit message Alice intends to send to Bob. +Based on the 2 bit message the state of the qubit in the register is mutated in place with `apply!` + +```jldoctest +julia> reg = Register(1) + +julia> initialize!(reg[1], Z1) + +julia> message = [1, 1] + +julia> SDEncode()(reg, message) +``` +""" + +struct SDEncode <: AbstractCircuit +end + +function (circuit::SDEncode)(reg, message) + if message[1] == 1 + apply!(reg[1], Z) + end + if message[2] == 1 + apply!(reg[1], X) + end +end + + +""" +$TYPEDEF + +Fields: + +$FIELDS + +The circuit for Superdense Coding to decode the 2 (classical) bit message +using the entangled bell pair stored in the registers regA and regB after Alice's encoding of the first qubit. +Returns a Tuple of the decoded message. + +```jldoctest +julia> regA = Register(1) + +julia> regB = Register(1) + +julia> initalize!(regA[1], Z1) + +julia> initalize!(regB[1], Z1) + +julia> SDDecode()(regA, regB) +``` +""" + +struct SDDecode <: AbstractCircuit +end + +function (circuit::SDDecode)(regA, regB) + apply!((regB[1], regA[1]), CNOT) + apply!(regB[1], H) + b1 = project_traceout!(regA, 1, Z) + b2 = project_traceout!(regB, 1, Z) + return b1-1, b2-1 +end + end # module diff --git a/src/backends/quantumoptics/quantumoptics.jl b/src/backends/quantumoptics/quantumoptics.jl index 6ec699f6..d2b081b6 100644 --- a/src/backends/quantumoptics/quantumoptics.jl +++ b/src/backends/quantumoptics/quantumoptics.jl @@ -37,6 +37,7 @@ function observable(state::Union{<:Ket,<:Operator}, indices, operation) expect(op, state) end + function project_traceout!(state::Union{Ket,Operator},stateindex,psis::Base.AbstractVecOrTuple{<:Ket}) if nsubsystems(state) == 1 # TODO is there a way to do this in a single function, instead of _overlap vs _project_and_drop _overlaps = [_overlap(psi,state) for psi in psis] diff --git a/test/runtests.jl b/test/runtests.jl index 1b1e3c0a..9bc2c8f0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -28,6 +28,7 @@ println("Starting tests with $(Threads.nthreads()) threads out of `Sys.CPU_THREA @doset "observable" @doset "noninstant_and_backgrounds_qubit" @doset "noninstant_and_backgrounds_qumode" +@doset "circuitzoo_superdense" @doset "circuitzoo_purification" @doset "examples" get(ENV,"QUANTUMSAVORY_PLOT_TEST","")=="true" && @doset "plotting_cairo" diff --git a/test/test_circuitzoo_superdense.jl b/test/test_circuitzoo_superdense.jl new file mode 100644 index 00000000..c1ac0e77 --- /dev/null +++ b/test/test_circuitzoo_superdense.jl @@ -0,0 +1,22 @@ +using QuantumSavory +using QuantumSavory.CircuitZoo: SDEncode, SDDecode +using Test + +## Set up an entangled bell pair +ra = Register(1) +rb = Register(1) + +initialize!(ra[1], Z1) +initialize!(rb[1], Z1) + +apply!(ra[1], H) +apply!((ra[1], rb[1]), CNOT) + +# Random 2 bit classical message +message = Tuple(rand(0:1, 2)) + +# Use the circuits to encode and decode the message +SDEncode()(ra, message) +rec = SDDecode()(ra, rb) + +@test message == rec