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

noncliff: define _proj subroutine for projectrand! and test multi-qubit projection for stabilizer and non-stabilizer states #355

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ed0c0ba
implement project! for genstab
Fe-r-oz Sep 8, 2024
3642472
Merge branch 'nonclif' into project
Fe-r-oz Sep 21, 2024
22df2fb
improve documentation and code quality
Fe-r-oz Sep 26, 2024
434ba32
Merge branch 'nonclif' into project
Fe-r-oz Sep 27, 2024
dd48b53
fix misc errors
Fe-r-oz Sep 27, 2024
8047c52
add codereview suggestions: project! and projectrand!
Fe-r-oz Oct 1, 2024
9bb0e1a
improve code quality and add tests for project! and projectrand!
Fe-r-oz Oct 1, 2024
b1901cb
remove projectrand!
Fe-r-oz Oct 25, 2024
3fc78cc
Merge branch 'nonclif' into project
Fe-r-oz Oct 25, 2024
d4a5800
improve code quality of project!
Fe-r-oz Oct 28, 2024
ba879f8
add test to show result1 == zero or result2 == zero for stabilizer st…
Fe-r-oz Nov 3, 2024
a6c5fed
implement projectrand! method and add tests for single-qubit base as …
Fe-r-oz Nov 3, 2024
306423b
Merge branch 'nonclif' into project
Fe-r-oz Nov 8, 2024
6966d11
Multi-qubit projections using GeneralizedStabilizer for stabilizer st…
Fe-r-oz Nov 8, 2024
1afdf8a
use random_clifford in the multi-qubit projection test and normalize …
Fe-r-oz Nov 8, 2024
7ed7033
show consistent comparison by using MixedDestabilizer, and Generalize…
Fe-r-oz Nov 9, 2024
e6e21fd
Merge branch 'nonclif' into project
Fe-r-oz Nov 9, 2024
6fe89f7
improve code quality and formatting
Fe-r-oz Nov 9, 2024
4da6a81
pardon - added remaining task: probabilistic non-stabilizer simulatio…
Fe-r-oz Nov 11, 2024
875f0b6
enhance comments for _proj
Fe-r-oz Nov 12, 2024
854e5c5
apply code review suggestion
Fe-r-oz Nov 16, 2024
1d50d06
remove redundant code
Fe-r-oz Nov 16, 2024
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
20 changes: 18 additions & 2 deletions src/nonclifford.jl
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,23 @@ function projectrand!(sm::GeneralizedStabilizer, p::PauliOperator)
end

function _proj(sm::GeneralizedStabilizer, p::PauliOperator)
error("This functionality is not implemented yet")
# As detailed in https://www.scottaaronson.com/showcase2/report/ted-yoder.pdf, "A generalized
# stabilizer (χ, B(S, D)) separates the “classical” part of the quantum state from the quantum
# state." In this framework, the quasi-classical tableau T = (S, D) is updated through Clifford
# gates and measurements, while the χ-matrix is updated solely by non-Clifford operations.

# In this divided simulation approach:
# 1) When encountering a Clifford gate or measurement, we update the tableau as per usual.
# 2) For a non-Clifford gate or channel, the Kraus operator decompositions and operator-sum
# coefficients are stored for use with apply!(::GeneralizedStabilizer, ::AbstractPauliChannel).

# This function returns an updated `GeneralizedStabilizer` state sm' = (χ', B(S', D')), where
# (S', D') is derived from (S, D) through traditional stabilizer update. The χ' matrix is
# updated whenever a non-Clifford gate is applied via apply!(sm, appropriately_padded_pcT).
updated_state, res = projectrand!(sm.stab, p)
# sm'.stab' is derived from sm.stab through the traditional stabilizer update.
sm.stab = updated_state # in-place
return sm, res
Fe-r-oz marked this conversation as resolved.
Show resolved Hide resolved
end

function project!(s::GeneralizedStabilizer, p::PauliOperator)
Expand Down Expand Up @@ -445,7 +461,7 @@ julia> apply!(sm, pcT) |> invsparsity
```

Similarly, it calculates the number of non-zero elements in the density
matrix `ϕᵢⱼ` of a PauliChannel, providing a measure of the channel
matrix `ϕᵢⱼ` of a PauliChannel, providing a measure of the channel
complexity.

```jldoctest heuristic
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ SIMD = "fdea26ae-647d-5447-a871-4b548cad5224"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StridedViews = "4db3bf67-4bd7-4b4e-b153-31dc3fb37143"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2 changes: 1 addition & 1 deletion test/test_jet.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@ end
)
@show rep
@test_broken length(JET.get_reports(rep)) == 0
@test length(JET.get_reports(rep)) <= 24
@test length(JET.get_reports(rep)) <= 29
end
75 changes: 75 additions & 0 deletions test/test_nonclifford_quantumoptics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ using LinearAlgebra
using Test
using InteractiveUtils
using Random
using Statistics

qo_basis = SpinBasis(1//2)
qo_tgate = sparse(identityoperator(qo_basis))
Expand Down Expand Up @@ -86,3 +87,77 @@ end
@test copy(nc) == nc
end
end

function multiqubit_projrand(τ,p)
qo_state = Operator(τ)
projectrand!(τ, p)[1]
qo_state_after_proj = Operator(τ)
qo_pauli = Operator(p)
qo_proj1 = (identityoperator(qo_pauli) - qo_pauli)/2
qo_proj2 = (identityoperator(qo_pauli) + qo_pauli)/2
result1 = qo_proj1*qo_state*qo_proj1'
result2 = qo_proj2*qo_state*qo_proj2'
return qo_state_after_proj, result1, result2
end

@testset "Multi-qubit projections using GeneralizedStabilizer for stabilizer states" begin
for n in 1:10
for repetition in 1:5
for state in [Stabilizer, MixedDestabilizer, GeneralizedStabilizer]
s = random_stabilizer(n)
p = random_pauli(n)
τ = state(s)
apply!(τ, random_clifford(n))
qo_state_after_proj, result1, result2 = multiqubit_projrand(τ,p)
# Normalize to ensure consistent comparison of the projected state, independent of scaling factors
norm_qo_state_after_proj = qo_state_after_proj/tr(qo_state_after_proj)
norm_result1 = result1/tr(result1)
norm_result2 = result2/tr(result2)
@test norm_qo_state_after_proj ≈ norm_result2 || norm_qo_state_after_proj ≈ norm_result1
end
end
end
end

function non_stabilizer_simulator(num_trials,n)
count = 0
for n in 1:n # exponential cost in this term
for _ in 1:num_trials
s = random_stabilizer(n)
p = random_pauli(n)
gs = GeneralizedStabilizer(s)
i = rand(1:n)
nc = embed(n, i, pcT) # multi-qubit random non-Clifford gate
apply!(gs, nc)
qo_state_after_proj, result1, result2 = multiqubit_projrand(gs,p)
# Normalize to ensure consistent comparison of the projected state, independent of scaling factors
norm_qo_state_after_proj = qo_state_after_proj/tr(qo_state_after_proj)
norm_result1 = result1/tr(result1)
norm_result2 = result2/tr(result2)
if norm_qo_state_after_proj ≈ norm_result2 || norm_qo_state_after_proj ≈ norm_result1
count += 1
end
end
end
prob = count/(num_trials*n)
return prob
end

@testset "probabilistic non-stabilizer simulator" begin
# As described in https://www.scottaaronson.com/showcase2/report/ted-yoder.pdf,
# "The set of states that are stabilizer circuit efficient is related to the
# set of magic states, those states that, when combined with stabilizer circuits,
# allow universal quantum computation. The problems are essentially complementary;
# no magic state will be simulatable through every stabilizer circuit (assuming
# BQP is larger than BPP, that is). With qudits of odd prime dimension, it was
# recently found in https://arxiv.org/pdf/1201.1256 that a sufficient condition
# for a state to be efficiently (weakly) simulated through stabilizer circuits is
# that a certain quasi-probability representation of the state be positive."
# Therefore, non-Clifford simulators generally require probabilistic sampling
# techniques.

num_qubits = 10
num_trials = 10
prob = non_stabilizer_simulator(num_trials, num_qubits)
@test prob > 0.5
end
Loading