-
Notifications
You must be signed in to change notification settings - Fork 15
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
Added Superdense endcoding and decoding circuits to CircuitZoo #34
Conversation
Codecov Report
@@ Coverage Diff @@
## master #34 +/- ##
==========================================
- Coverage 65.15% 64.11% -1.04%
==========================================
Files 23 23
Lines 927 981 +54
==========================================
+ Hits 604 629 +25
- Misses 323 352 +29
... and 2 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
Running the circuits from this PR is somehow returning inconsistent results with multiple runs: using QuantumSavory
using QuantumSavory.CircuitZoo: SDEncode, SDDecode
##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)
message = [1, 1]
SDEncode()(ra, message)
rec = SDDecode()(ra, rb) versus when simply running a program without using any registers: using QuantumSavory
using QuantumClifford, QuantumOpticsBase
function alice_node1()
message = rand(0:1, 2)
println("Sending message: $message")
state = S"XX
ZZ"
if message[1] == 1
state = P"ZI"*state
end
if message[2] == 1
state = P"XI"*state
end
return state
end
function bob_node2()
state = alice_node1()
apply!(state, tCNOT, [2,1])
apply!(state, tHadamard,[2])
msg = Ket(state)
println("Message Received by Bob: $msg")
end
bob_node2() Does there seem to be any mistake with the encoding or decoding circuit or could there be a bug somewhere? |
could you try to investigate what is happening step by step the register has a staterefs property which you can use to see what state is being stored in it
You can also try the clifford representation given that you already have a related test
I will not always be able to review quickly after you submit a pull request. Please proceed with trying to investigate and fix even if I have not reviewed. |
|
||
function (circuit::SDDecode)(regA, regB) | ||
apply!((regB[1], regA[1]), CNOT) | ||
apply!(regB[1], H) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything works fine upto this line, but when we apply H to Bob's qubit, the result is the same as what we would get if we applied H to Alice's qubit on paper, i.e., something like
Ket(dim=4)
basis: [Spin(1/2) ⊗ Spin(1/2)]
0.49999999999999994 + 0.0im
-0.49999999999999994 + 0.0im
-0.49999999999999994 + 0.0im
0.49999999999999994 + 0.0im
which gives us the random results.
But if we apply H to regA[1]
, which is Alice's qubit here, it returns the correct results. I am not sure why it behaves this way, opposite to what we get when we solve it on paper, but it resolves the issue here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate a bit? What is the state before the wrong step, what is the step that seems to break things, and what is the state after that step (and what should it be)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the final part of the decoder circuit, we want to apply H to the second qubit (Bob's qubit), and H is a 1 qubit operator. But under the hood our register stores a 4 element ket vector which (if the classical message is 1 1
) would be:
Ket(dim=4)
basis: [Spin(1/2) ⊗ Spin(1/2)]
0.0 + 0.0im
0.0 + 0.0im
0.7071067811865475 + 0.0im
-0.7071067811865475 + 0.0im
To apply the symbolic H to the second qubit, we call the apply!
method at
QuantumSavory.jl/src/baseops/apply.jl
Line 12 in 09fe3aa
function apply!(regs::Vector{Register}, indices::Vector{Int}, operation; time=nothing) |
Here(
QuantumSavory.jl/src/baseops/apply.jl
Line 21 in 09fe3aa
state_indices = [r.stateindices[i] for (r,i) in zip(regs, indices)] |
state_indices
parameter of our ket determines whether the final operator would be I⊗H
(correct) or H⊗I
(wrong) given state_indices is 1 or 2 respectively. Since, Bob's qubit is the 2nd qubit of the subsystem state_indices
is set to 2 and it finally hits the apply!
methods in QuantumOpticsBase.jl. So, because of state_indices
being 2, the final operator here (in QuantumOpticsBase.jl) becomes H⊗I
which gives us the wrong answer in my previous comment.
So, [sorry for the huge description : ) ] to be short, the embed
method here expects to be provided with the index where we want to put the identity operator(index 1) instead of the index of the qubit on which we're performing the single qubit operation(index 2), as described by its docstring here
Hence, I think we have a bug in this line
QuantumSavory.jl/src/baseops/apply.jl
Line 21 in 09fe3aa
state_indices = [r.stateindices[i] for (r,i) in zip(regs, indices)] |
and
state_indices
should be a vector of all the indices of the state excluding the index of our qubit, so that embed could put identity for all those indices
Needs the next QOBase release |
No description provided.