Skip to content

Commit

Permalink
Optimize Clifford.__pow__ by using binary exponentiation (#6581)
Browse files Browse the repository at this point in the history
  • Loading branch information
migueltorrescosta authored May 6, 2024
1 parent 3080d93 commit 69e3de1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
34 changes: 22 additions & 12 deletions cirq-core/cirq/ops/clifford_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,11 @@ def _has_stabilizer_effect_(self) -> Optional[bool]:
# By definition, Clifford Gate should always return True.
return True

def __pow__(self, exponent) -> 'CliffordGate':
def __pow__(self, exponent: float) -> 'CliffordGate':
if exponent != int(exponent):
return NotImplemented
exponent = int(exponent)

if exponent == -1:
return CliffordGate.from_clifford_tableau(self.clifford_tableau.inverse())
if exponent == 0:
Expand All @@ -409,18 +413,24 @@ def __pow__(self, exponent) -> 'CliffordGate':
)
if exponent == 1:
return self
if exponent > 0 and int(exponent) == exponent:
base_tableau = self.clifford_tableau.copy()
for _ in range(int(exponent) - 1):
base_tableau = base_tableau.then(self.clifford_tableau)
return CliffordGate.from_clifford_tableau(base_tableau)
if exponent < 0 and int(exponent) == exponent:
base_tableau = self.clifford_tableau.copy()
for _ in range(int(-exponent) - 1):
base_tableau = base_tableau.then(self.clifford_tableau)
return CliffordGate.from_clifford_tableau(base_tableau.inverse())

return NotImplemented
base_tableau = self.clifford_tableau.copy()
if exponent < 0:
base_tableau = base_tableau.inverse()
exponent = abs(exponent)

# https://cp-algorithms.com/algebra/binary-exp.html
aux = qis.CliffordTableau(
num_qubits=self.clifford_tableau.n
) # this tableau collects the odd terms
while exponent > 1:
if exponent & 1:
aux = aux.then(base_tableau)
base_tableau = base_tableau.then(base_tableau)
exponent >>= 1

base_tableau = base_tableau.then(aux)
return CliffordGate.from_clifford_tableau(base_tableau)

def __repr__(self) -> str:
return f"Clifford Gate with Tableau:\n {self.clifford_tableau._str_full_()}"
Expand Down
4 changes: 3 additions & 1 deletion cirq-core/cirq/qis/clifford_tableau.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ def apply_global_phase(self, coefficient: linear_dict.Scalar):

class CliffordTableau(StabilizerState):
"""Tableau representation of a stabilizer state
(based on Aaronson and Gottesman 2006).
References:
- [Aaronson and Gottesman](https://arxiv.org/abs/quant-ph/0406196)
The tableau stores the stabilizer generators of
the state using three binary arrays: xs, zs, and rs.
Expand Down

0 comments on commit 69e3de1

Please sign in to comment.