1+ # Some documentation for myself:
2+ # In line with the existing definition
3+ # - `projectrand!(gs::GraphState, m::sMX)` doesn't care about the register/classical bit
4+ # - `apply!(state::Register, m::sMX)` does, and it depends on `projectrand!`
5+ # And these should be the only public facing APIs for now
6+
7+ function remove_neighbors! (g, qubit:: Int )
8+ for nghbr in copy (inneighbors (g, qubit))
9+ rem_edge! (g, qubit, nghbr)
10+ end
11+ end
12+
13+ """
14+ Project a pure graph state (all VOPs are identity) onto eigenspaces of the Z observable.
15+ """
16+ function _projectZ_pure_graph! (state:: GraphState , qubit:: Int , res:: Bool )
17+ # For a = qubit to measure, b ∈ nghbrs(a)
18+ # Cₐ -> Cₐ * Xₐ^res * Hₐ
19+ # Cᵦ -> Cᵦ * Zᵦ^res
20+ # And remove all edeges between a and its neighbors
21+ g = graph (state)
22+ v = vops (state)
23+
24+ # Tweak VOPs
25+ if res
26+ _apply_vop_right! (v, sX (qubit))
27+ end
28+ _apply_vop_right! (v, sHadamard (qubit))
29+ for nghbr in inneighbors (g, qubit)
30+ if res
31+ _apply_vop_right! (v, sZ (nghbr))
32+ end
33+ end
34+
35+ # Modify graph
36+ remove_neighbors! (g, qubit)
37+
38+ return state
39+ end
40+
41+ """
42+ Project a pure graph state onto eigenspaces of the Y observable.
43+ """
44+ function _projectY_pure_graph! (state:: GraphState , qubit:: Int , res:: Bool )
45+ g = graph (state)
46+ v = vops (state)
47+
48+ function tweak_vop (q)
49+ if res
50+ _apply_vop_right! (v, sInvPhase (q))
51+ else
52+ _apply_vop_right! (v, sPhase (q))
53+ end
54+ end
55+
56+ # Tweak VOPs of target qubit and its neighbors
57+ tweak_vop (qubit)
58+ for b in inneighbors (g, qubit)
59+ tweak_vop (b)
60+ end
61+
62+ # perform local complementation on edge
63+ local_comp! (g, qubit)
64+
65+ # remove the neighbors of the target qubit, this step is missing in the paper
66+ remove_neighbors! (g, qubit)
67+
68+ return state
69+ end
70+
71+ """
72+ Project a pure graph state onto eigenspaces of X observable.
73+ """
74+ function _projectX_pure_graph! (state:: GraphState , qubit:: Int , res:: Bool )
75+ g = graph (state)
76+ v = vops (state)
77+ a = qubit
78+
79+ # Cₐ -> Cₐ Z^res
80+ if res
81+ _apply_vop_right! (v, sZ (a))
82+ end
83+
84+ nghbrs_a = copy (inneighbors (g, a))
85+ if ! isempty (nghbrs_a)
86+ b = nghbrs_a[1 ]
87+ nghbrs_b = copy (inneighbors (g, b))
88+ nghbr_a_and_b = intersect (nghbrs_a, nghbrs_b)
89+
90+ # tweak the VOPs first
91+ # C_b -> C_b (sInvSQRTY)(†) where † is applied only if res is true
92+ if res
93+ _apply_vop_right! (v, sSQRTY (b))
94+ else
95+ _apply_vop_right! (v, sInvSQRTY (b))
96+ end
97+
98+ if res
99+ # nghbr(b) \ nghbr(a) \ {a}
100+ for c in setdiff (nghbrs_b, nghbrs_a, a)
101+ _apply_vop_right! (v, sZ (c))
102+ end
103+ else
104+ # nghbr(a) \ nghbr(b) \ {b}
105+ for c in setdiff (nghbrs_a, nghbrs_b, b)
106+ _apply_vop_right! (v, sZ (c))
107+ end
108+ end
109+
110+ # complementation on edges {{c, d} | c ∈ nghbr(a), d ∈ nghbr(b)}
111+ for (c, d) in Iterators. product (nghbrs_a, nghbrs_b)
112+ if (c ∈ nghbrs_b) && (d ∈ nghbrs_a)
113+ if c < d
114+ toggle_edge! (g, c, d)
115+ end
116+ else
117+ toggle_edge! (g, c, d)
118+ end
119+ end
120+
121+ # complementation on edges {{c, d} | c, d ∈ nghbr(a) ∩ nghbr(b)}
122+ for c in eachindex (nghbr_a_and_b)
123+ for d in c+ 1 : length (nghbr_a_and_b)
124+ toggle_edge! (g, nghbr_a_and_b[c], nghbr_a_and_b[d])
125+ end
126+ end
127+
128+ # complement on edges {{b, d} | d ∈ nghbr(a) \ {b}}
129+ for d in nghbrs_a[2 : end ]
130+ toggle_edge! (g, b, d)
131+ end
132+
133+ remove_neighbors! (g, a)
134+ end
135+ return state
136+ end
137+
138+ function _project_graph! (state:: GraphState , qubit:: Int , op:: Stabilizer , res:: Bool )
139+ # Cₐ† opₐ Cₐ
140+ op_prime = apply! (op, inv (vops (state)[qubit]))
141+
142+ ispositive = (phases (op_prime)[1 ]) != 0x02
143+ # normalize the phase to match later
144+ phases (op_prime)[1 ] = 0x00
145+ res_tilde = ispositive ? res : ! res
146+
147+ if op_prime == S " Z"
148+ _projectZ_pure_graph! (state, qubit, res_tilde)
149+ elseif op_prime == S " X"
150+ _projectX_pure_graph! (state, qubit, res_tilde)
151+ elseif op_prime == S " Y"
152+ _projectY_pure_graph! (state, qubit, res_tilde)
153+ end
154+
155+ return state
156+ end
0 commit comments