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

[non-Clifford] In-place Pauli measurements (projectrand!) for GeneralizedStabilizer with expanded test suite #427

Open
wants to merge 26 commits into
base: nonclif
Choose a base branch
from

Conversation

Fe-r-oz
Copy link
Contributor

@Fe-r-oz Fe-r-oz commented Nov 17, 2024

This PR implements the original approach for the Pauli Measurements algorithm as described in Ted’s paper. The algorithm is in-place and closely translates the algorithm/proof outlined on page 8 of the paper. It incorporates the details from pages 6 to 8 and equations (14) through (26) to fully capture the aspects of working with this weird stabilizer basis given in the paper.

Previously, I had considered this approach but avoided it due to some confusion, which led me to overlook the method explicitly given on page 8. The manual approach implemented in #355 missed some details of the algorithm in the special stabilizer basis constructed by Ted. In retrospect, it feels like manually building the wall brick by brick, even though the blueprint for the wall was already provided in Algorithm 2.

Thoughts: The approach in #355 relied on expect to advance the computation. However, this method diverges from the original algorithm described in the paper, especially in the elsecase of the algorithm. 2) The original algorithm includes several parameters and functionalities that were not fully captured. This PR aims to rectify that by directly implementing the specific details and behaviors as outlined in the paper.

Thanks so much for your feedback. I now realize that faithfully translating the paper into code requires revisiting and challenging both my initial assumptions and any new assumptions I may be making. Hopefully, I aim to get on the right track.

An initial demonstration shows that it addresses the initial pain points highlighted in #355. I am currently working on adding more tests to enhance its validation. In the if case, we don't need to update the stabilizer basis (equation 17), so I returned nothing as second argument.

julia> state = projectrand!(apply!(GeneralizedStabilizer(S"X"), pcT), P"X")[1]
A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
𝒟ℯ𝓈𝓉𝒶𝒷
+ Z
𝒮𝓉𝒶𝒷
+ X
with ϕᵢⱼ | Pᵢ | Pⱼ:
 0.853553+0.0im | + _ | + _

julia> Operator(state)/tr(Operator(state)) # normalization
Operator(dim=2x2)
  basis: Spin(1/2)
 0.5+0.0im  0.5+0.0im
 0.5+0.0im  0.5+0.0im

julia> state = GeneralizedStabilizer(S"XX ZZ");

julia> op = embed(2, 1, pcT);

julia> apply!(state, op);

julia> projectrand!(state, P"XX")
(A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
MixedDestablizer 2×2
with ϕᵢⱼ | Pᵢ | Pⱼ:
 0.853553+0.0im | + __ | + __, nothing)

julia> state
A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
𝒟ℯ𝓈𝓉𝒶𝒷
+ Z_
+ _X
𝒮𝓉𝒶𝒷
+ XX
+ ZZ
with ϕᵢⱼ | Pᵢ | Pⱼ:
 0.853553+0.0im | + __ | + __

julia> Operator(state)/tr(Operator(state))
Operator(dim=4x4)
  basis: [Spin(1/2) ⊗ Spin(1/2)]
 0.5+0.0im  0.0+0.0im  0.0+0.0im  0.5+0.0im
 0.0+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.5+0.0im  0.0+0.0im  0.0+0.0im  0.5+0.0im

julia> projectrand!(state, P"ZZ"); # normalization

julia> state
A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
𝒟ℯ𝓈𝓉𝒶𝒷
+ Z_
+ _X
𝒮𝓉𝒶𝒷
+ XX
+ ZZ
with ϕᵢⱼ | Pᵢ | Pⱼ:
 0.853553+0.0im | + __ | + __

julia> Operator(state)/tr(Operator(state)) # normalization
Operator(dim=4x4)
  basis: [Spin(1/2) ⊗ Spin(1/2)]
 0.5+0.0im  0.0+0.0im  0.0+0.0im  0.5+0.0im
 0.0+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.5+0.0im  0.0+0.0im  0.0+0.0im  0.5+0.0im

@Fe-r-oz Fe-r-oz marked this pull request as ready for review November 19, 2024 11:50
@Fe-r-oz
Copy link
Contributor Author

Fe-r-oz commented Nov 19, 2024

Please help review this PR, @Krastanov, thank you!

Edit: Commenting for reference: #309, #199, #259

@Fe-r-oz Fe-r-oz changed the title noncliff: in-place Pauli measurement algorithm noncliff: in-place Pauli Measurements (projectrand!) for GeneralizedStabilizer Nov 23, 2024
@Fe-r-oz
Copy link
Contributor Author

Fe-r-oz commented Nov 29, 2024

Hi, @Krastanov! Just a friendly bump on this. Thanks!

@Fe-r-oz Fe-r-oz changed the title noncliff: in-place Pauli Measurements (projectrand!) for GeneralizedStabilizer [non-Clifford] In-place Pauli measurements (projectrand!) for GeneralizedStabilizer with expanded test suite Nov 30, 2024
@Krastanov
Copy link
Member

Thanks for continuing with this.

I have not really done much of an in-depth review besides skimming through the new tests to make sure they are not too heavy on the CI system (hence the commit).

The same example that I used on your previous PR still seem to give some issues, but they seem to be API misunderstandings, not correctness issues:

julia> using QuantumClifford

julia> projectrand!(apply!(GeneralizedStabilizer(S"X"), pcT), P"X")
(A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
MixedDestablizer 1×1
with ϕᵢⱼ | Pᵢ | Pⱼ:
 0.853553+0.0im | + _ | + _, nothing)
  1. Why is projectrand! returning nothing as a second entry in the tuple? I would expect that to be either 0x0 or 0x2, just like it does for Stabilizer, representing the measurement result eigenvalue
  2. Why is it not normalized? -- this one is more of a question of convention, unlike the previous question, but projectrand! on other objects returns normalized objects.

The normalization question is a bit difficult to design around -- there are certainly situations where an unnormalized result is preferred. But we also need to keep consistency with pre-existing API.

  • project! and projectrand! exist in QuantumInterface
  • they are not used in QuantumOptics yet
  • in QuantumClifford
    • project! is used in QuantumClifford but with a very non-general API that does not apply to other libraries
    • projectrand! is in the same situation
  • they are not used in QuantumSavory yet

So I guess we can pick any convention we want here... And the closest one to the currently existing projectrand! for stabilizer states is to normalize.

So how about the following:

  • rename the method you have implemented to something private like _projectrand_notnorm
  • use it to create a new normalized projectrand!
  • In the tests, keep what makes sense unnormalized, as that is a more stringent test anyway, but if necessary add normalized tests

I posted the API design issue to the QuantumInterface repo qojulia/QuantumInterface.jl#45

@Fe-r-oz
Copy link
Contributor Author

Fe-r-oz commented Dec 21, 2024

Why is projectrand! returning nothing as a second entry in the tuple? I would expect that to be either 0x0 or 0x2, just like it does for Stabilizer, representing the measurement result eigenvalue

Fixed the convention. Thanks! Originally, in the if case, we don't need to update the stabilizer basis (equation 17), so I returned nothing as second argument. But, as you mentioned, that's a departure from the standard convention.

Why is it not normalized? -- this one is more of a question of convention, unlike the previous question, but projectrand! on other objects returns normalized objects.

This was Ted's design choice/convention. So, I didn't poke his convention at all. Yeah, let's call it _projectrand_notnorm. As you mentioned, we can translate to the desired convention afterwards.

Thank you for the API suggestions. I thought it would be better to discuss the API stuff than to do anything beforehand, so I didn't touch anything API related (didn't added anything irrelevant).

@Fe-r-oz
Copy link
Contributor Author

Fe-r-oz commented Dec 21, 2024

CI related message: The performance tracking CI error is likely due to print function when destabweights are printed

 ERROR: MethodError: no method matching print(::Dict{Symbol, Any})
You may have intended to import Base.print
The applicable method may be too new: running in world age 23725, while current world is 23735.

Closest candidates are:
  print(::Any) (method too new to be called from this world context.)

@Fe-r-oz
Copy link
Contributor Author

Fe-r-oz commented Dec 21, 2024

Thank you for the API suggestions! I have incorporated the three tasks that were suggested.

When the invsparsity is 1, we do normalization. This helps not mess up the behavior of _projectrand_notnorm (Ted's original Pauli measurement algorithm/convention) and we achieve the normalization. I have retained a test that require _projectrand_notnorm as suggested and included it in tests as QuantumClifford: _projectrand_notnorm

julia> projectrand!(apply!(GeneralizedStabilizer(S"X"), pcT), P"X")
(A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
MixedDestablizer 1×1
with ϕᵢⱼ | Pᵢ | Pⱼ:
 1.0+0.0im | + _ | + _, 0x00)

julia> projectrand!(apply!(GeneralizedStabilizer(S"X"), pcT), P"Y")
(A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
MixedDestablizer 1×1
with ϕᵢⱼ | Pᵢ | Pⱼ:
 1.0+0.0im | + _ | + _, 0x00)

julia> projectrand!(apply!(GeneralizedStabilizer(S"X"), pcT), P"Z")
(A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
MixedDestablizer 1×1
with ϕᵢⱼ | Pᵢ | Pⱼ:
 1.0+0.0im | + _ | + _, 0x00)

julia> projectrand!(apply!(GeneralizedStabilizer(S"X"), pcT), P"I")
(A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
MixedDestablizer 1×1
with ϕᵢⱼ | Pᵢ | Pⱼ:
 0.0+0.353553im | + _ | + Z
 0.0-0.353553im | + Z | + _
 0.853553+0.0im | + _ | + _
 0.146447+0.0im | + Z | + Z, 0x00)

Please help review this PR, thank you!

@Krastanov Krastanov self-requested a review December 21, 2024 22:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants