Skip to content

Commit 43a697f

Browse files
Fe-r-ozKrastanov
andauthored
tensor product of GeneralizedStabilizer (#345)
Co-authored-by: Stefan Krastanov <[email protected]> Co-authored-by: Stefan Krastanov <[email protected]>
1 parent 268ee47 commit 43a697f

File tree

6 files changed

+177
-9
lines changed

6 files changed

+177
-9
lines changed

docs/src/references.bib

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,13 @@ @article{nahum2017quantum
199199

200200
% non-Clifford formalism
201201
202-
@inproceedings{Yoder2012AGO,
203-
title={A generalization of the stabilizer formalism for simulating arbitrary quantum circuits},
204-
author={Theodore J. Yoder},
205-
year={2012},
206-
url={https://api.semanticscholar.org/CorpusID:18406560}
202+
@misc{Yoder2012AGO,
203+
title = {A Generalization of the Stabilizer Formalism for Simulating Arbitrary Quantum Circuits},
204+
author = {Theodore J. Yoder},
205+
year = {2012},
206+
howpublished = {Semantic Scholar Corpus ID: 18406560},
207+
url = {https://api.semanticscholar.org/CorpusID:18406560},
208+
note = {Also available at \url{http://www.scottaaronson.com/showcase2/report/ted-yoder.pdf}}
207209
}
208210

209211
% codes

src/nonclifford.jl

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,121 @@ function apply!(state::GeneralizedStabilizer, gate::AbstractPauliChannel; prune_
443443
state
444444
end
445445

446+
"""
447+
$(TYPEDSIGNATURES)
448+
449+
Tensor product of [`GeneralizedStabilizer`](@ref) states.
450+
451+
# Stabilizer state
452+
453+
```jldoctest
454+
julia> sm = GeneralizedStabilizer(S"-X")
455+
A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
456+
𝒟ℯ𝓈𝓉𝒶𝒷
457+
+ Z
458+
𝒮𝓉𝒶𝒷
459+
- X
460+
with ϕᵢⱼ | Pᵢ | Pⱼ:
461+
1.0+0.0im | + _ | + _
462+
463+
julia> sm ⊗ sm
464+
A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
465+
𝒟ℯ𝓈𝓉𝒶𝒷
466+
+ Z_
467+
+ _Z
468+
𝒮𝓉𝒶𝒷
469+
- X_
470+
- _X
471+
with ϕᵢⱼ | Pᵢ | Pⱼ:
472+
1.0+0.0im | + __ | + __
473+
```
474+
475+
# Arbitrary state
476+
477+
```jldoctest
478+
julia> using LinearAlgebra; # hide
479+
480+
julia> sm = GeneralizedStabilizer(ghz(2))
481+
A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
482+
𝒟ℯ𝓈𝓉𝒶𝒷
483+
+ Z_
484+
+ _X
485+
𝒮𝓉𝒶𝒷
486+
+ XX
487+
+ ZZ
488+
with ϕᵢⱼ | Pᵢ | Pⱼ:
489+
1.0+0.0im | + __ | + __
490+
491+
julia> apply!(sm, embed(2, 2, pcT))
492+
A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
493+
𝒟ℯ𝓈𝓉𝒶𝒷
494+
+ Z_
495+
+ _X
496+
𝒮𝓉𝒶𝒷
497+
+ XX
498+
+ ZZ
499+
with ϕᵢⱼ | Pᵢ | Pⱼ:
500+
0.853553+0.0im | + __ | + __
501+
0.0+0.353553im | + __ | + Z_
502+
0.0-0.353553im | + Z_ | + __
503+
0.146447+0.0im | + Z_ | + Z_
504+
505+
julia> newsm = sm ⊗ sm
506+
A mixture ∑ ϕᵢⱼ Pᵢ ρ Pⱼ† where ρ is
507+
𝒟ℯ𝓈𝓉𝒶𝒷
508+
+ Z___
509+
+ _X__
510+
+ __Z_
511+
+ ___X
512+
𝒮𝓉𝒶𝒷━━
513+
+ XX__
514+
+ ZZ__
515+
+ __XX
516+
+ __ZZ
517+
with ϕᵢⱼ | Pᵢ | Pⱼ:
518+
0.0-0.301777im | + Z___ | + ____
519+
-0.125+0.0im | + Z_Z_ | + ____
520+
0.125+0.0im | + Z___ | + Z___
521+
0.728553+0.0im | + ____ | + ____
522+
0.0-0.0517767im | + Z_Z_ | + Z___
523+
0.0-0.301777im | + __Z_ | + ____
524+
0.0+0.301777im | + ____ | + Z___
525+
0.125+0.0im | + __Z_ | + Z___
526+
0.125+0.0im | + Z___ | + __Z_
527+
0.0-0.0517767im | + Z_Z_ | + __Z_
528+
0.0+0.0517767im | + Z___ | + Z_Z_
529+
0.0+0.301777im | + ____ | + __Z_
530+
0.0214466+0.0im | + Z_Z_ | + Z_Z_
531+
0.125+0.0im | + __Z_ | + __Z_
532+
-0.125+0.0im | + ____ | + Z_Z_
533+
0.0+0.0517767im | + __Z_ | + Z_Z_
534+
535+
julia> real(tr(newsm))
536+
1.0
537+
```
538+
"""
539+
function ()(state₁::GeneralizedStabilizer, state₂::GeneralizedStabilizer)
540+
dict₁ = state₁.destabweights
541+
dict₂ = state₂.destabweights
542+
dtype = valtype(dict₁)
543+
tzero = zero(dtype)
544+
newdict = DefaultDict{Tuple{BitVector,BitVector},dtype}(tzero)
545+
newstab = state₁.stab state₂.stab
546+
for ((d1_i, d1_j), χ) in dict₁ # χ = ϕᵢⱼ for state₁
547+
for ((d2_i, d2_j), χ′) in dict₂ # χ′ = ϕₖₗ for state₂
548+
# Combine the Pauli operators via tensor product: Pᵢ ⊗ Pₖ
549+
# and Pⱼ ⊗ Pₗ. vcat implements P₁ ⊗ P₂ as bitwise concatenation.
550+
new_key_i = vcat(d1_i, d2_i)
551+
new_key_j = vcat(d1_j, d2_j)
552+
# The new coefficient is ϕᵢⱼ * ϕₖₗ because:
553+
# ∑ϕᵢⱼ*ϕₖₗ(Pᵢρ₁Pⱼ†) ⊗ (Pₖρ₂Pₗ†) = ∑ϕᵢⱼ*ϕₖₗ(Pᵢ ⊗ Pₖ)(ρ₁ ⊗ ρ₂)(Pⱼ ⊗ Pₗ)† and
554+
# thus the combined weight is the product of the individual weights.
555+
newdict[(new_key_i, new_key_j)] += χ * χ′
556+
end
557+
end
558+
return GeneralizedStabilizer(newstab, newdict)
559+
end
560+
446561
"""Decompose a Pauli ``P`` in terms of stabilizer and destabilizer rows from a given tableaux.
447562
448563
For given tableaux of rows destabilizer rows ``\\{d_i\\}`` and stabilizer rows ``\\{s_i\\}``,

test/test_nonclifford.jl

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@testitem "NonClifford" begin
22
using QuantumClifford
3-
using QuantumClifford: GeneralizedStabilizer, rowdecompose, PauliChannel, invsparsity, mul_left!, mul_right!
3+
using QuantumClifford: GeneralizedStabilizer, rowdecompose, PauliChannel, invsparsity, mul_left!, mul_right!, mixed_destab_looks_good, tr
44
using Test
55
using InteractiveUtils
66
using Random
@@ -102,6 +102,27 @@
102102
end
103103
end
104104

105+
@testset "Tensor products over generalized stabilizers" begin
106+
num_trials = 10
107+
num_qubits = [2,3,4,5] # exclusively multi-qubit
108+
for n in num_qubits
109+
for repetition in 1:num_trials
110+
stab = random_stabilizer(n)
111+
pauli = random_pauli(n)
112+
genstab = GeneralizedStabilizer(stab)
113+
# Apply some (repeated) non-Clifford operations
114+
i = rand(1:n)
115+
nc = embed(n, i, pcT)
116+
apply!(genstab, nc) # in-place
117+
apply!(genstab, nc) # in-place
118+
apply!(genstab, nc) # in-place
119+
newsm = genstab genstab
120+
@test mixed_destab_looks_good(newsm.stab)
121+
@test real(tr(newsm)) 1
122+
end
123+
end
124+
end
125+
105126
@test_throws ArgumentError GeneralizedStabilizer(S"XX")
106127
@test_throws ArgumentError PauliChannel(((P"X", P"Z"), (P"X", P"ZZ")), (1,2))
107128
@test_throws ArgumentError PauliChannel(((P"X", P"Z"), (P"X", P"Z")), (1,))

test/test_nonclifford_quantumoptics.jl

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@testitem "Non-Clifford Quantum Optics" begin
22
using QuantumClifford
3-
using QuantumClifford: GeneralizedStabilizer, rowdecompose, PauliChannel, mul_left!, mul_right!, invsparsity, _projectrand_notnorm
3+
using QuantumClifford: GeneralizedStabilizer, rowdecompose, PauliChannel, mul_left!, mul_right!, invsparsity, _projectrand_notnorm, mixed_destab_looks_good, tr
44
using QuantumClifford: @S_str, random_stabilizer
55
using QuantumOpticsBase
66
using LinearAlgebra
@@ -220,6 +220,35 @@
220220
@test any(projectrand!(GeneralizedStabilizer(S"X"), P"Z")[1].stab != s1 for _ in 1:10)
221221
end
222222

223+
@testset "Tensor products of generalized stabilizers" begin
224+
num_trials = 3
225+
num_qubits = [2,3] # exclusively multi-qubit
226+
for n in num_qubits
227+
for repetition in 1:num_trials
228+
stab1 = random_stabilizer(n)
229+
genstab1 = GeneralizedStabilizer(stab1)
230+
stab2 = random_stabilizer(n)
231+
genstab2 = GeneralizedStabilizer(stab2)
232+
# apply some (repeated) non-Clifford operations to genstab1
233+
for _ in 1:rand(1:5)
234+
i = rand(1:n)
235+
nc = embed(n, i, pcT)
236+
apply!(genstab1, nc)
237+
end
238+
# apply some (repeated) non-Clifford operations to genstab2
239+
for _ in 1:rand(1:5)
240+
i = rand(1:n)
241+
nc = embed(n, i, pcT)
242+
apply!(genstab2, nc)
243+
end
244+
@test Operator(genstab1 genstab2) Operator(genstab1) Operator(genstab2)
245+
@test Operator(genstab2 genstab1) Operator(genstab2) Operator(genstab1)
246+
@test Operator(genstab1 genstab1) Operator(genstab1) Operator(genstab1)
247+
@test Operator(genstab2 genstab2) Operator(genstab2) Operator(genstab2)
248+
end
249+
end
250+
end
251+
223252
@testset "smaller test redundant to the ones above" begin
224253
for n in 1:5
225254
for rep in 1:2

test/test_paulis.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@testitem "Pauli Operators" begin
2-
using QuantumClifford: apply_single_x!, apply_single_y!, apply_single_z!
3-
test_sizes = [1,2,10,63,64,65,127,128,129] # Including sizes that would test off-by-one errors in the bit encoding.
2+
using QuantumClifford: apply_single_x!, apply_single_y!, apply_single_z!
3+
test_sizes = [1,2,10,63,64,65,127,128,129] # Including sizes that would test off-by-one errors in the bit encoding.
44

55
@testset "Parsing, constructors, and properties" begin
66
@test P"-iXYZ" == PauliOperator(0x3, 3, vcat(BitArray([1,1,0]).chunks, BitArray([0,1,1]).chunks))

test/test_stabs.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@testitem "Stabilizers" begin
22
using QuantumClifford
3+
using LinearAlgebra
34
using QuantumClifford: stab_looks_good, destab_looks_good, mixed_stab_looks_good, mixed_destab_looks_good
45
test_sizes = [1,2,10,63,64,65,127,128,129] # Including sizes that would test off-by-one errors in the bit encoding.
56
@testset "Pure and Mixed state initialization" begin

0 commit comments

Comments
 (0)