@@ -400,7 +400,11 @@ def _has_stabilizer_effect_(self) -> Optional[bool]:
400400 # By definition, Clifford Gate should always return True.
401401 return True
402402
403- def __pow__ (self , exponent ) -> 'CliffordGate' :
403+ def __pow__ (self , exponent : float ) -> 'CliffordGate' :
404+ if exponent != int (exponent ):
405+ return NotImplemented
406+ exponent = int (exponent )
407+
404408 if exponent == - 1 :
405409 return CliffordGate .from_clifford_tableau (self .clifford_tableau .inverse ())
406410 if exponent == 0 :
@@ -409,18 +413,24 @@ def __pow__(self, exponent) -> 'CliffordGate':
409413 )
410414 if exponent == 1 :
411415 return self
412- if exponent > 0 and int (exponent ) == exponent :
413- base_tableau = self .clifford_tableau .copy ()
414- for _ in range (int (exponent ) - 1 ):
415- base_tableau = base_tableau .then (self .clifford_tableau )
416- return CliffordGate .from_clifford_tableau (base_tableau )
417- if exponent < 0 and int (exponent ) == exponent :
418- base_tableau = self .clifford_tableau .copy ()
419- for _ in range (int (- exponent ) - 1 ):
420- base_tableau = base_tableau .then (self .clifford_tableau )
421- return CliffordGate .from_clifford_tableau (base_tableau .inverse ())
422416
423- return NotImplemented
417+ base_tableau = self .clifford_tableau .copy ()
418+ if exponent < 0 :
419+ base_tableau = base_tableau .inverse ()
420+ exponent = abs (exponent )
421+
422+ # https://cp-algorithms.com/algebra/binary-exp.html
423+ aux = qis .CliffordTableau (
424+ num_qubits = self .clifford_tableau .n
425+ ) # this tableau collects the odd terms
426+ while exponent > 1 :
427+ if exponent & 1 :
428+ aux = aux .then (base_tableau )
429+ base_tableau = base_tableau .then (base_tableau )
430+ exponent >>= 1
431+
432+ base_tableau = base_tableau .then (aux )
433+ return CliffordGate .from_clifford_tableau (base_tableau )
424434
425435 def __repr__ (self ) -> str :
426436 return f"Clifford Gate with Tableau:\n { self .clifford_tableau ._str_full_ ()} "
0 commit comments