def test_reset_act_on(): with pytest.raises(TypeError, match="Failed to act"): cirq.act_on(cirq.ResetChannel(), object()) args = cirq.ActOnStateVectorArgs( target_tensor=cirq.one_hot(index=(1, 1, 1, 1, 1), shape=(2, 2, 2, 2, 2), dtype=np.complex64), available_buffer=np.empty(shape=(2, 2, 2, 2, 2)), axes=[1], prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(cirq.ResetChannel(), args) assert args.log_of_measurement_results == {} np.testing.assert_allclose( args.target_tensor, cirq.one_hot(index=(1, 0, 1, 1, 1), shape=(2, 2, 2, 2, 2), dtype=np.complex64), ) cirq.act_on(cirq.ResetChannel(), args) assert args.log_of_measurement_results == {} np.testing.assert_allclose( args.target_tensor, cirq.one_hot(index=(1, 0, 1, 1, 1), shape=(2, 2, 2, 2, 2), dtype=np.complex64), )
def test_reset_act_on(): with pytest.raises(TypeError, match="Failed to act"): cirq.act_on(cirq.ResetChannel(), DummyActOnArgs(), qubits=()) args = cirq.ActOnStateVectorArgs( available_buffer=np.empty(shape=(2, 2, 2, 2, 2), dtype=np.complex64), qubits=cirq.LineQubit.range(5), prng=np.random.RandomState(), log_of_measurement_results={}, initial_state=cirq.one_hot(index=(1, 1, 1, 1, 1), shape=(2, 2, 2, 2, 2), dtype=np.complex64), dtype=np.complex64, ) cirq.act_on(cirq.ResetChannel(), args, [cirq.LineQubit(1)]) assert args.log_of_measurement_results == {} np.testing.assert_allclose( args.target_tensor, cirq.one_hot(index=(1, 0, 1, 1, 1), shape=(2, 2, 2, 2, 2), dtype=np.complex64), ) cirq.act_on(cirq.ResetChannel(), args, [cirq.LineQubit(1)]) assert args.log_of_measurement_results == {} np.testing.assert_allclose( args.target_tensor, cirq.one_hot(index=(1, 0, 1, 1, 1), shape=(2, 2, 2, 2, 2), dtype=np.complex64), )
def test_reset_channel_text_diagram(): assert cirq.circuit_diagram_info(cirq.ResetChannel()) == cirq.CircuitDiagramInfo( wire_symbols=('R',) ) assert cirq.circuit_diagram_info(cirq.ResetChannel(3)) == cirq.CircuitDiagramInfo( wire_symbols=('R',) )
def test_stim_circuit_to_cirq_circuit(): circuit = stimcirq.stim_circuit_to_cirq_circuit( stim.Circuit(""" X 0 CNOT 0 1 X_ERROR(0.125) 0 1 CORRELATED_ERROR(0.25) X0 Y1 Z2 M 1 M !1 MR 0 !1 """)) a, b, c = cirq.LineQubit.range(3) assert circuit == cirq.Circuit( cirq.X(a), cirq.CNOT(a, b), cirq.X.with_probability(0.125).on(a), cirq.X.with_probability(0.125).on(b), cirq.PauliString({ a: cirq.X, b: cirq.Y, c: cirq.Z }).with_probability(0.25), cirq.measure(b, key="0"), cirq.measure(b, key="1", invert_mask=(True, )), cirq.measure(a, key="2"), cirq.ResetChannel().on(a), cirq.measure(b, key="3", invert_mask=(True, )), cirq.ResetChannel().on(b), )
def get_supported_channels(): """A helper to get the channels that are supported in TFQ. Returns a dictionary mapping from supported channel types to number of qubits. """ # Add new channels here whenever additional support is needed. channel_mapping = dict() channel_mapping[cirq.DepolarizingChannel(0.01)] = 1 channel_mapping[cirq.AsymmetricDepolarizingChannel(0.01, 0.02, 0.03)] = 1 channel_mapping[cirq.AmplitudeDampingChannel(0.01)] = 1 channel_mapping[cirq.ResetChannel()] = 1 return channel_mapping
def test_entangled_reset_does_not_break_randomness(): """ A previous version of cirq made the mistake of assuming that it was okay to cache the wavefunction produced by general channels on unrelated qubits before repeatedly sampling measurements. This test checks for that mistake. """ a, b = cirq.LineQubit.range(2) circuit = cirq.Circuit( cirq.H(a), cirq.CNOT(a, b), cirq.ResetChannel().on(a), cirq.measure(b, key='out') ) samples = cirq.Simulator().sample(circuit, repetitions=100)['out'] counts = samples.value_counts() assert len(counts) == 2 assert 10 <= counts[0] <= 90 assert 10 <= counts[1] <= 90
def _translate_flattened_operation( op: Tuple[str, List, float], get_next_measure_id: Callable[[], int]) -> Iterator[cirq.Operation]: name, targets, arg = op handler = stim_to_cirq_gate_table().get(name) if handler is not None: if isinstance(handler, cirq.Gate): gate = handler elif handler == (): return else: gate = handler(arg) for q in targets: if isinstance(q, tuple) and q[0] == "rec": raise NotImplementedError("Measurement record.") m = gate.num_qubits() for k in range(0, len(targets), m): yield gate(*[cirq.LineQubit(q) for q in targets[k:k + m]]) return if name == "M" or name == "MR": for t in targets: if isinstance(t, int): q = t inv = False elif t[0] == "inv": q = t[1] inv = True else: raise NotImplementedError("Unrecognized measurement target.") q = cirq.LineQubit(q) yield cirq.measure(q, key=str(get_next_measure_id()), invert_mask=(True, ) if inv else ()) if name == "MR": yield cirq.ResetChannel().on(q) return if name == "E": yield cirq.PauliString({cirq.LineQubit(q): k for k, q in targets}).with_probability(arg) return raise NotImplementedError(f"Unsupported gate: {name}")
def test_reset_channel_str(): assert str(cirq.ResetChannel()) == 'reset' assert str(cirq.ResetChannel(3)) == 'reset'
def test_reset_channel_repr(): cirq.testing.assert_equivalent_repr(cirq.ResetChannel()) cirq.testing.assert_equivalent_repr(cirq.ResetChannel(3))
def test_reset_channel_equality(): assert cirq.reset(cirq.LineQubit(0)).gate == cirq.ResetChannel() assert cirq.reset(cirq.LineQid(0, 3)).gate == cirq.ResetChannel(3)
'PhaseDampingChannel': cirq.PhaseDampingChannel(0.5), 'PhaseFlipChannel': cirq.PhaseFlipChannel(0.5), 'PhaseGradientGate': cirq.PhaseGradientGate(num_qubits=3, exponent=0.235), 'PhasedISwapPowGate': cirq.PhasedISwapPowGate(phase_exponent=0.1, exponent=0.2), 'PhasedXPowGate': cirq.PhasedXPowGate(phase_exponent=0.123, exponent=0.456, global_shift=0.789), 'QuantumFourierTransformGate': cirq.QuantumFourierTransformGate(num_qubits=2, without_reverse=True), 'ResetChannel': cirq.ResetChannel(), 'X': cirq.X, 'Y': cirq.Y, 'Z': cirq.Z, 'S': cirq.S, 'SWAP': cirq.SWAP, 'SingleQubitPauliStringGateOperation': cirq.X(Q0), 'SwapPowGate': [cirq.SwapPowGate(), cirq.SWAP**0.5], 'SYC': cirq.google.SYC,
def gate_to_stim_append_func( ) -> Dict[cirq.Gate, Callable[[stim.Circuit, List[int]], None]]: """A dictionary mapping specific gate instances to stim circuit appending functions.""" x = (cirq.X, False) y = (cirq.Y, False) z = (cirq.Z, False) nx = (cirq.X, True) ny = (cirq.Y, True) nz = (cirq.Z, True) def do_nothing(c, t): pass def use( *gates: str, individuals: Sequence[Tuple[str, int]] = () ) -> Callable[[stim.Circuit, List[int]], None]: if len(gates) == 1 and not individuals: (g, ) = gates return lambda c, t: c.append_operation(g, t) if not individuals: def do(c, t): for g in gates: c.append_operation(g, t) else: def do(c, t): for g in gates: c.append_operation(g, t) for g, k in individuals: c.append_operation(g, [t[k]]) return do sqcg = cirq.SingleQubitCliffordGate.from_xz_map paulis = cast(List[cirq.Pauli], [cirq.X, cirq.Y, cirq.Z]) return { cirq.ResetChannel(): use("R"), # Identities. cirq.I: do_nothing, cirq.H**0: do_nothing, cirq.X**0: do_nothing, cirq.Y**0: do_nothing, cirq.Z**0: do_nothing, cirq.ISWAP**0: do_nothing, cirq.SWAP**0: do_nothing, # Common named gates. cirq.H: use("H"), cirq.X: use("X"), cirq.Y: use("Y"), cirq.Z: use("Z"), cirq.X**0.5: use("SQRT_X"), cirq.X**-0.5: use("SQRT_X_DAG"), cirq.Y**0.5: use("SQRT_Y"), cirq.Y**-0.5: use("SQRT_Y_DAG"), cirq.Z**0.5: use("SQRT_Z"), cirq.Z**-0.5: use("SQRT_Z_DAG"), cirq.CNOT: use("CNOT"), cirq.CZ: use("CZ"), cirq.ISWAP: use("ISWAP"), cirq.ISWAP**-1: use("ISWAP_DAG"), cirq.ISWAP**2: use("Z"), cirq.SWAP: use("SWAP"), cirq.X.controlled(1): use("CX"), cirq.Y.controlled(1): use("CY"), cirq.Z.controlled(1): use("CZ"), # All 24 cirq.SingleQubitCliffordGate instances. sqcg(x, y): use("SQRT_X_DAG"), sqcg(x, ny): use("SQRT_X"), sqcg(nx, y): use("H_YZ"), sqcg(nx, ny): use("H_YZ", "X"), sqcg(x, z): do_nothing, sqcg(x, nz): use("X"), sqcg(nx, z): use("Z"), sqcg(nx, nz): use("Y"), sqcg(y, x): use("S", "SQRT_Y"), sqcg(y, nx): use("S", "SQRT_Y_DAG"), sqcg(ny, x): use("S_DAG", "SQRT_Y"), sqcg(ny, nx): use("S_DAG", "SQRT_Y_DAG"), sqcg(y, z): use("S"), sqcg(y, nz): use("H_XY"), sqcg(ny, z): use("S_DAG"), sqcg(ny, nz): use("H_XY", "Z"), sqcg(z, x): use("H"), sqcg(z, nx): use("SQRT_Y_DAG"), sqcg(nz, x): use("SQRT_Y"), sqcg(nz, nx): use("H", "Y"), sqcg(z, y): use("SQRT_Y_DAG", "S_DAG"), sqcg(z, ny): use("SQRT_Y_DAG", "S"), sqcg(nz, y): use("SQRT_Y", "S"), sqcg(nz, ny): use("SQRT_Y", "S_DAG"), # All 36 cirq.PauliInteractionGate instances. **{ cirq.PauliInteractionGate(p0, s0, p1, s1): use(f"{p0}C{p1}", individuals=[(str(p1), 1)] * s0 + [(str(p0), 0)] * s1) for p0, s0, p1, s1 in itertools.product(paulis, [False, True], repeat=2) }, }
def test_reset_channel_equality(): assert cirq.RESET == cirq.ResetChannel()
def stim_to_cirq_gate_table( ) -> Dict[str, Union[Tuple, cirq.Gate, Callable[[float], cirq.Gate]]]: return { "R": cirq.ResetChannel(), "I": cirq.I, "X": cirq.X, "Y": cirq.Y, "Z": cirq.Z, "H_XY": cirq.SingleQubitCliffordGate.from_xz_map(x_to=(cirq.Y, False), z_to=(cirq.Z, True)), "H": cirq.H, "H_YZ": cirq.SingleQubitCliffordGate.from_xz_map(x_to=(cirq.X, True), z_to=(cirq.Y, False)), "SQRT_X": cirq.X**0.5, "SQRT_X_DAG": cirq.X**-0.5, "SQRT_Y": cirq.Y**0.5, "SQRT_Y_DAG": cirq.Y**-0.5, "S": cirq.S, "S_DAG": cirq.S**-1, "SWAP": cirq.SWAP, "ISWAP": cirq.ISWAP, "ISWAP_DAG": cirq.ISWAP**-1, "XCX": cirq.PauliInteractionGate(cirq.X, False, cirq.X, False), "XCY": cirq.PauliInteractionGate(cirq.X, False, cirq.Y, False), "XCZ": cirq.PauliInteractionGate(cirq.X, False, cirq.Z, False), "YCX": cirq.PauliInteractionGate(cirq.Y, False, cirq.X, False), "YCY": cirq.PauliInteractionGate(cirq.Y, False, cirq.Y, False), "YCZ": cirq.PauliInteractionGate(cirq.Y, False, cirq.Z, False), "CX": cirq.CNOT, "CY": cirq.Y.controlled(1), "CZ": cirq.CZ, "DEPOLARIZE1": lambda arg: cirq.DepolarizingChannel(arg, 1), "DEPOLARIZE2": lambda arg: cirq.DepolarizingChannel(arg, 2), "X_ERROR": lambda arg: cirq.X.with_probability(arg), "Y_ERROR": lambda arg: cirq.Y.with_probability(arg), "Z_ERROR": lambda arg: cirq.Z.with_probability(arg), "DETECTOR": (), "OBSERVABLE_INCLUDE": (), "TICK": (), }