Skip to content

Commit

Permalink
Split right multiplication into separate methods in StabilizerStateCH…
Browse files Browse the repository at this point in the history
…Form (#3259)

#2423 

This will allow each method to have a definite action which will allow us to move the left multiplication logic to individual gates #2948. Also makes the update_sum method public so that the gates can call it instead of duplicating the logic.
  • Loading branch information
smitsanghavi authored Sep 10, 2020
1 parent ecd5326 commit 55502f1
Showing 1 changed file with 37 additions and 35 deletions.
72 changes: 37 additions & 35 deletions cirq/sim/clifford/stabilizer_state_ch_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,14 @@ def state_vector(self) -> np.ndarray:
def wave_function(self) -> np.ndarray:
return self.state_vector()

def _S(self, q, right=False):
if right:
self.M[:, q] ^= self.F[:, q]
self.gamma[:] = (self.gamma[:] - self.F[:, q]) % 4
else:
self.M[q, :] ^= self.G[q, :]
self.gamma[q] = (self.gamma[q] - 1) % 4
def _S(self, q):
self.M[q, :] ^= self.G[q, :]
self.gamma[q] = (self.gamma[q] - 1) % 4

def _S_right(self, q):
r"""Right multiplication version of S gate."""
self.M[:, q] ^= self.F[:, q]
self.gamma[:] = (self.gamma[:] - self.F[:, q]) % 4

def _Z(self, q):
self._S(q)
Expand All @@ -159,27 +160,28 @@ def _Y(self, q):
self._X(q)
self.omega *= 1j

def _CZ(self, q, r, right=False):
if right:
self.M[:, q] ^= self.F[:, r]
self.M[:, r] ^= self.F[:, q]
self.gamma[:] = (self.gamma[:] +
2 * self.F[:, q] * self.F[:, r]) % 4
else:
self.M[q, :] ^= self.G[r, :]
self.M[r, :] ^= self.G[q, :]

def _CNOT(self, q, r, right=False):
if right:
self.G[:, q] ^= self.G[:, r]
self.F[:, r] ^= self.F[:, q]
self.M[:, q] ^= self.M[:, r]
else:
self.gamma[q] = (self.gamma[q] + self.gamma[r] + 2 *
(sum(self.M[q, :] & self.F[r, :]) % 2)) % 4
self.G[r, :] ^= self.G[q, :]
self.F[q, :] ^= self.F[r, :]
self.M[q, :] ^= self.M[r, :]
def _CZ(self, q, r):
self.M[q, :] ^= self.G[r, :]
self.M[r, :] ^= self.G[q, :]

def _CZ_right(self, q, r):
r"""Right multiplication version of CZ gate."""
self.M[:, q] ^= self.F[:, r]
self.M[:, r] ^= self.F[:, q]
self.gamma[:] = (self.gamma[:] + 2 * self.F[:, q] * self.F[:, r]) % 4

def _CNOT(self, q, r):
self.gamma[q] = (self.gamma[q] + self.gamma[r] + 2 *
(sum(self.M[q, :] & self.F[r, :]) % 2)) % 4
self.G[r, :] ^= self.G[q, :]
self.F[q, :] ^= self.F[r, :]
self.M[q, :] ^= self.M[r, :]

def _CNOT_right(self, q, r):
r"""Right multiplication version of CNOT gate."""
self.G[:, q] ^= self.G[:, r]
self.F[:, r] ^= self.F[:, q]
self.M[:, q] ^= self.M[:, r]

def _H(self, p):
t = self.s ^ (self.G[p, :] & self.v)
Expand All @@ -193,9 +195,9 @@ def _H(self, p):

delta = (self.gamma[p] + 2 * (alpha + beta)) % 4

self._update_sum(t, u, delta=delta, alpha=alpha)
self.update_sum(t, u, delta=delta, alpha=alpha)

def _update_sum(self, t, u, delta=0, alpha=0):
def update_sum(self, t, u, delta=0, alpha=0):
""" Implements the transformation (Proposition 4 in Bravyi et al)
i^alpha U_H (|t> + i^delta |u>) = omega W_C W_H |s'>
Expand All @@ -212,14 +214,14 @@ def _update_sum(self, t, u, delta=0, alpha=0):
q = set0[0]
for i in set0:
if i != q:
self._CNOT(q, i, right=True)
self._CNOT_right(q, i)
for i in set1:
self._CZ(q, i, right=True)
self._CZ_right(q, i)
elif len(set1) > 0:
q = set1[0]
for i in set1:
if i != q:
self._CNOT(i, q, right=True)
self._CNOT_right(i, q)

e = np.zeros(self.n, dtype=bool)
e[q] = True
Expand All @@ -238,7 +240,7 @@ def _update_sum(self, t, u, delta=0, alpha=0):
self.omega *= (-1)**alpha * omega

if a:
self._S(q, right=True)
self._S_right(q)
self.v[q] ^= b ^ self.v[q]

def _H_decompose(self, v, y, z, delta):
Expand Down Expand Up @@ -296,4 +298,4 @@ def project_Z(self, q, z):
if np.all(t == u):
self.omega /= np.sqrt(2)

self._update_sum(t, u, delta=delta)
self.update_sum(t, u, delta=delta)

0 comments on commit 55502f1

Please sign in to comment.