Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call cirq.testing.assert_equivalent_repr for cirq.SingleQubitCliffordGate and cirq.CliffordTableau #5664

Merged
merged 13 commits into from
Jul 7, 2022
11 changes: 1 addition & 10 deletions cirq-core/cirq/ops/clifford_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,16 +879,7 @@ def equivalent_gate_before(self, after: 'SingleQubitCliffordGate') -> 'SingleQub
return self.merged_with(after).merged_with(self**-1)

def __repr__(self) -> str:
x = self.pauli_tuple(pauli_gates.X)
y = self.pauli_tuple(pauli_gates.Y)
z = self.pauli_tuple(pauli_gates.Z)
x_sign = '-' if x[1] else '+'
y_sign = '-' if y[1] else '+'
z_sign = '-' if z[1] else '+'
return (
f'cirq.SingleQubitCliffordGate(X:{x_sign}{x[0]!s}, '
f'Y:{y_sign}{y[0]!s}, Z:{z_sign}{z[0]!s})'
)
return f'cirq.SingleQubitCliffordGate(_clifford_tableau={self._clifford_tableau!r})'
vtomole marked this conversation as resolved.
Show resolved Hide resolved

def _circuit_diagram_info_(
self, args: 'cirq.CircuitDiagramInfoArgs'
Expand Down
20 changes: 13 additions & 7 deletions cirq-core/cirq/ops/clifford_gate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,16 +329,22 @@ def test_eq_ne_and_hash():


@pytest.mark.parametrize(
'gate,rep',
'gate',
(
(cirq.SingleQubitCliffordGate.I, 'cirq.SingleQubitCliffordGate(X:+X, Y:+Y, Z:+Z)'),
(cirq.SingleQubitCliffordGate.H, 'cirq.SingleQubitCliffordGate(X:+Z, Y:-Y, Z:+X)'),
(cirq.SingleQubitCliffordGate.X, 'cirq.SingleQubitCliffordGate(X:+X, Y:-Y, Z:-Z)'),
(cirq.SingleQubitCliffordGate.X_sqrt, 'cirq.SingleQubitCliffordGate(X:+X, Y:+Z, Z:-Y)'),
cirq.SingleQubitCliffordGate.I,
cirq.SingleQubitCliffordGate.H,
cirq.SingleQubitCliffordGate.X,
cirq.SingleQubitCliffordGate.X_sqrt,
),
)
def test_repr(gate, rep):
assert repr(gate) == rep
def test_repr_gate(gate):
cirq.testing.assert_equivalent_repr(gate)


def test_repr_operation():
cirq.testing.assert_equivalent_repr(
cirq.SingleQubitCliffordGate.from_pauli(cirq.Z).on(cirq.LineQubit(2))
)


@pytest.mark.parametrize(
Expand Down
61 changes: 42 additions & 19 deletions cirq-core/cirq/qis/clifford_tableau.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
# limitations under the License.

import abc
from typing import Any, Dict, List, Sequence, TYPE_CHECKING
from typing import Any, Dict, List, Optional, Sequence, TYPE_CHECKING
import numpy as np

from cirq import protocols
from cirq._compat import proper_repr
from cirq.qis import quantum_state_representation
from cirq.value import big_endian_int_to_digits, linear_dict

Expand Down Expand Up @@ -137,30 +138,47 @@ class CliffordTableau(StabilizerState):
an eigenoperator of the state vector with eigenvalue one: P|psi> = |psi>.
"""

def __init__(self, num_qubits, initial_state: int = 0):
def __init__(
self,
num_qubits,
initial_state: int = 0,
rs: Optional[np.ndarray] = None,
xs: Optional[np.ndarray] = None,
zs: Optional[np.ndarray] = None,
):
"""Initializes CliffordTableau
Args:
num_qubits: The number of qubits in the system.
initial_state: The computational basis representation of the
state as a big endian int.
"""
self.n = num_qubits
self.initial_state = initial_state

if rs is None:
# The last row (`2n+1`-th row) is the scratch row used in _measurement
# computation process only. It should not be exposed to external usage.
self._rs = np.zeros(2 * self.n + 1, dtype=bool)
for (i, val) in enumerate(
big_endian_int_to_digits(self.initial_state, digit_count=num_qubits, base=2)
):
self._rs[self.n + i] = bool(val)
else:
self._rs = rs
vtomole marked this conversation as resolved.
Show resolved Hide resolved

if xs is None:
self._xs = np.zeros((2 * self.n + 1, self.n), dtype=bool)
for i in range(self.n):
self._xs[i, i] = True
else:
self._xs = xs

# The last row (`2n+1`-th row) is the scratch row used in _measurement
# computation process only. It should not be exposed to external usage.
self._rs = np.zeros(2 * self.n + 1, dtype=bool)

for (i, val) in enumerate(
big_endian_int_to_digits(initial_state, digit_count=num_qubits, base=2)
):
self._rs[self.n + i] = bool(val)

self._xs = np.zeros((2 * self.n + 1, self.n), dtype=bool)
self._zs = np.zeros((2 * self.n + 1, self.n), dtype=bool)

for i in range(self.n):
self._xs[i, i] = True
self._zs[self.n + i, i] = True
if xs is None:
self._zs = np.zeros((2 * self.n + 1, self.n), dtype=bool)
for i in range(self.n):
self._zs[self.n + i, i] = True
else:
self._zs = zs

@property
def xs(self) -> np.ndarray:
Expand Down Expand Up @@ -233,8 +251,13 @@ def copy(self, deep_copy_buffers: bool = True) -> 'CliffordTableau':
return state

def __repr__(self) -> str:
stabilizers = ", ".join([repr(stab) for stab in self.stabilizers()])
return f'stabilizers: [{stabilizers}]'
return (
f"cirq.CliffordTableau({self.n},"
f"rs={proper_repr(self._rs)}, "
f"xs={proper_repr(self._xs)},"
f"zs={proper_repr(self._zs)}, "
f"initial_state={self.initial_state})"
)

def __str__(self) -> str:
string = ''
Expand Down
3 changes: 1 addition & 2 deletions cirq-core/cirq/qis/clifford_tableau_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,7 @@ def test_str():


def test_repr():
t = cirq.CliffordTableau(num_qubits=1)
assert repr(t) == "stabilizers: [cirq.DensePauliString('Z', coefficient=(1+0j))]"
cirq.testing.assert_equivalent_repr(cirq.CliffordTableau(num_qubits=1))


def test_str_full():
Expand Down