-
Notifications
You must be signed in to change notification settings - Fork 47
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
noncliff: define _proj
subroutine for projectrand!
#355
base: nonclif
Are you sure you want to change the base?
Conversation
I think the PR is ready for review. I hope it's not awkward. Thank you! |
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.
Thanks for starting this, it is incredibly helpful to have someone tackle it.
I left a few comments in, but I think there is a bigger thing that is currently unclear to me: in _proj₊
you access only the base tableau out of which all terms in the weighted sum are generated, but you do not access any of those terms themselves, nor are their relative weights taken into account. And it seems that you are returning a pure state, not a GeneralizedStabilizer
. But one single measurement is not enough to turn a mixed state into a pure state, so there must be an issue with the current code.
@@ -50,3 +50,18 @@ qo_tgate.data[2,2] = exp(im*pi/4) | |||
end | |||
end | |||
end | |||
|
|||
@testset "project!" begin |
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.
These tests do not really check the projection operation results. They just run some projection operation and make sure that errors are not raised, but do not do verification.
We also should try something that is not exclusively single-qubit.
Something like this maybe:
for n in 1:4
for repetition in 1:5
s = random_stabilizer(n)
p = random_pauli(n)
gs = GeneralizedStabilizer(s)
for i in 1:rand(1:3)
apply!(gs, appropriately_padded_pcT) # this might need an `embed` or `tensor`
end
qo_state = Operator(gs)
projectrand!(gs)
qo_state_after_proj = Operator(gs)
# finally, compute the projected result with QuantumOptics and compare
qo_pauli = Operator(p)
qo_proj1 = (Identity - qo_pauli)/2
qo_proj2 = (Identity - qo_pauli)/2
result1 = qo_proj1*qo_state*qo_proj1'
result2 = qo_proj2*qo_state*qo_proj2'
@test qo_state_after_proj ≈ result2 || qo_state_after_proj ≈ result1
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.
Thanks a lot for this! That is really appreciated.
Thanks for your pertinent observation. Indeed, something was wrong as I was only considering the tableau, not the catering This is why Ted says that 'trace Tr [τ′] = Tr [χ′] is the probability of measuring 0' when talking about the case of measuring 0. My bad... Now, we have deterministic |
18a3b7b
to
b367530
Compare
The PR is ready for review, Thank you! |
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.
Thanks for continuing with this. It seems there are a few mistakes in the tests. Could you look into them?
src/nonclifford.jl
Outdated
function _proj₊(sm::GeneralizedStabilizer, p::PauliOperator) | ||
newstab, res = projectrand!(sm.stab, p) | ||
χ′ = expect(p, sm) | ||
n = nqubits(newstab) | ||
newsm = GeneralizedStabilizer(newstab, DefaultDict(0.0im, (falses(n),falses(n))=>χ′)) | ||
return newsm, res | ||
end | ||
|
||
function _proj₋(sm::GeneralizedStabilizer, p::PauliOperator) | ||
newstab, res = projectrand!(sm.stab, -p) | ||
χ′ = expect(p, sm) | ||
n = nqubits(newstab) | ||
newsm = GeneralizedStabilizer(newstab, DefaultDict(0.0im, (falses(n),falses(n))=>χ′)) | ||
return newsm, res | ||
end |
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.
there is a lot of code repetition here. It seems it would be simpler if on line 224
we just change the sign of p
-- then we do not need separate proj+
and proj-
functions.
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.
Addressed with the latest commit a6c5fed
src/nonclifford.jl
Outdated
newstab, res = projectrand!(sm.stab, -p) | ||
χ′ = expect(p, sm) |
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.
It seems you are modifying an internal detail of sm
before you are calling expect
on it. Is sm
still a valid object after this operation?
src/nonclifford.jl
Outdated
newstab, res = projectrand!(sm.stab, -p) | ||
χ′ = expect(p, sm) | ||
n = nqubits(newstab) | ||
newsm = GeneralizedStabilizer(newstab, DefaultDict(0.0im, (falses(n),falses(n))=>χ′)) |
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 this to be a valid object we need χ′==1
, right? Is that always the case (e.g. you can use this to check for bugs)? If this is always the case (i.e. no bugs detected), then we can presumably just skip the computation of χ′
.
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.
χ′ is the updated density matrix which is not necessarily be 1
as this is observed when we apply a non-clifford op to sm
, and them find expectation value of a given pauli operator using expect
as done in the doctest. In that particular case, χ′ = 0.7071067811865475
as seen in doctest whose probability is ~0.85.
Thank you for your feedback. I've removed This PR focuses solely on implementing I’ll address I attempted to use the suggested test (shown below) from this comment: discussion link, but I encountered an error when testing with While the test may be basic, I would appreciate your feedback on its conceptual correctness. I hope it doesn't fall into the trap of being tautologically true. The tests pass for Thank you again for your guidance, and I look forward to your thoughts.
|
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.
Thanks for working on this. There are some issues on semantics in terms of what project!
and projectrand!
are supposed to mean and the tests seem to be missing a lot of cases.
@@ -50,3 +50,20 @@ qo_tgate.data[2,2] = exp(im*pi/4) | |||
end | |||
end | |||
end | |||
|
|||
@testset "project!" begin | |||
checks = [(S"X",P"X"),(S"Y",P"Y"),(S"Z",P"Z"),(S"-X",P"-X"),(S"-Y",P"-Y"),(S"-Z",P"-Z")] |
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.
This tests only very specific simple states. Right now I do not believe this is actually correct for more complicated states like:
- multi-qubit states
- non-stabilizer states
Using random_stabilizer
and applying a few non-Clifford gates at random qubits would make this much more believable. It can be in a separate testset to help readability, so no need to necessarily modify what is already 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.
and multiqubit pauli operators
qo_proj2 = (identityoperator(qo_pauli) + qo_pauli)/2 | ||
result1 = qo_proj1*qo_state*qo_proj1' | ||
result2 = qo_proj2*qo_state*qo_proj2' | ||
@test qo_state_after_proj ≈ result2 || qo_state_after_proj ≈ result1 |
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.
it would also be nice to check that one of result1 or result2 is the zero matrix given that you are working stabilizer states only 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.
This has been now implemented with projectrand!
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.
The condition where result1 or result2 is zero is probabilistic, particularly when the test is repeated multiple times. This holds true even for Stabilizer
and MixedDestabilizer
projections, particularly when using multi-qubit random_stabilizer
states and multi-qubit random_pauli
operators
src/nonclifford.jl
Outdated
Base.copy(sm::GeneralizedStabilizer) = GeneralizedStabilizer(copy(sm.stab),copy(sm.destabweights)) | ||
|
||
Base.:(==)(sm₁::GeneralizedStabilizer, sm₂::GeneralizedStabilizer) = sm₁.stab==sm₂.stab && sm₁.destabweights==sm₂.destabweights | ||
|
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.
these would be nice to add (maybe closer to where struct GeneralizedStabilizer
is defined), so if this PR gets protracted feel free to add them in a separate PR (which probably will get merged faster). Just make sure to add some consistency tests for them.
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.
Thanks for the suggestion, implemented in #419
src/nonclifford.jl
Outdated
0.707107+0.0im | + _ | + _ | ||
``` | ||
""" | ||
function project!(sm::GeneralizedStabilizer, p::PauliOperator) |
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.
I do not think I understand what this project!
function is meant to mean.
- It is not a simulation of a (potentially nondeterministic) projective measurement (that would be
projectrand!
and it would involve some randomness in the output) - It is not what
project!
usually means in this library (a deterministic operation that tells you whether your measurement operator commutes with your stabilizers, and depending on whether it commutes it performs a variety of extra steps to tell you what the state would be after projection). I actually do not believe one can even defineproject!
consistenly forGeneralizedStabilizer
. After all, what would be the meaning ofanticom
andres
in that case.
In short: I think this needs projectrand!
and not project!
. I think earlier in a related PR there was already a discussion of that semantic issue. Maybe we should even define project!(::GeneralizedStabilizer, ::Pauli) = error(...)
with an explanation why projectrand!
needs to be used.
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.
Thank you! I’ve consolidated _proj+
and proj-
into a single _proj,
and added a detailed explanation in #416 with definition of project!(::GeneralizedStabilizer, ::Pauli) = error(...)
.
projectrand!
_proj
subroutine for projectrand!
810fc91
to
9e2ef48
Compare
Thank you for your valuable feedback! This PR builds upon the scaffolding introduced in #420, addresses #418, and includes a test for Edit: The graph TD
subgraph NittyGritty [ ]
direction TB
D--> D1[define_proj]
end
subgraph Tests [ ]
direction TB
E[Consistency Tests] --> E1[random_stabilizer, *done* <br>random_pauli, *done* <br> random_clifford, *done* <br> non-stabilizer **remaining**]
end
subgraph ScaffoldingBranch [ ]
direction TB
B[Scaffolding] --> B1[completed]
end
subgraph ErrorBranch [Unrelated Errors, <br> Issue #418]
direction TB
C[Unrelated Errors, <br> Issue #418] --> C1[Resolve projection inconsistencies for multi-qubit Stabilizer/MixedDestabilizer]
end
A[projectrand!] --> C
A[projectrand!] --> B
A[projectrand!] --> E
A --> D[Nitty Gritty]
|
…dStabilizer states for stabilizer simulation
This PR is ready for review, Thank you! |
PR implements
project!
fornoncliff.
Basic tests are added as well.