def test_unitary_fallback_h(): class UnitaryHGate(cirq.Gate): def num_qubits(self) -> int: return 1 def _unitary_(self): return np.array([[1, 1], [1, -1]]) / (2**0.5) original_state = cirq.StabilizerStateChForm(num_qubits=3) args = cirq.ActOnStabilizerCHFormArgs( state=original_state.copy(), axes=[1], prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(UnitaryHGate(), args) expected_args = cirq.ActOnStabilizerCHFormArgs( state=original_state.copy(), axes=[1], prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(cirq.H, expected_args) np.testing.assert_allclose(args.state.state_vector(), expected_args.state.state_vector())
def test_unitary_fallback_y(): class UnitaryYGate(cirq.Gate): def num_qubits(self) -> int: return 1 def _unitary_(self): return np.array([[0, -1j], [1j, 0]]) original_state = cirq.StabilizerStateChForm(num_qubits=3) args = cirq.ActOnStabilizerCHFormArgs( state=original_state.copy(), qubits=cirq.LineQubit.range(3), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(UnitaryYGate(), args, [cirq.LineQubit(1)]) expected_args = cirq.ActOnStabilizerCHFormArgs( state=original_state.copy(), qubits=cirq.LineQubit.range(3), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(cirq.Y, expected_args, [cirq.LineQubit(1)]) np.testing.assert_allclose(args.state.state_vector(), expected_args.state.state_vector())
def test_init_state(): args = cirq.ActOnStabilizerCHFormArgs( qubits=cirq.LineQubit.range(1), initial_state=1, ) np.testing.assert_allclose(args.state.state_vector(), [0, 1]) with pytest.raises(ValueError, match='Must specify qubits'): _ = cirq.ActOnStabilizerCHFormArgs(initial_state=1)
def test_unitary_fallback_y(): class UnitaryYGate(cirq.Gate): def num_qubits(self) -> int: return 1 def _unitary_(self): return np.array([[0, -1j], [1j, 0]]) original_state = cirq.StabilizerStateChForm(num_qubits=3) args = cirq.ActOnStabilizerCHFormArgs(state=original_state.copy(), axes=[1]) cirq.act_on(UnitaryYGate(), args) expected_args = cirq.ActOnStabilizerCHFormArgs(state=original_state.copy(), axes=[1]) cirq.act_on(cirq.Y, expected_args) np.testing.assert_allclose(args.state.state_vector(), expected_args.state.state_vector())
def test_act_on_ch_form(input_gate_sequence, outcome): original_state = cirq.StabilizerStateChForm(num_qubits=5, initial_state=31) num_qubits = cirq.num_qubits(input_gate_sequence[0]) if num_qubits == 1: axes = [1] else: assert num_qubits == 2 axes = [0, 1] args = cirq.ActOnStabilizerCHFormArgs( state=original_state.copy(), axes=axes, prng=np.random.RandomState(), log_of_measurement_results={}, ) flipped_state = cirq.StabilizerStateChForm(num_qubits=5, initial_state=23) if outcome == 'Error': with pytest.raises(TypeError, match="Failed to act action on state"): for input_gate in input_gate_sequence: cirq.act_on(input_gate, args) return for input_gate in input_gate_sequence: cirq.act_on(input_gate, args) if outcome == 'Original': np.testing.assert_allclose(args.state.state_vector(), original_state.state_vector()) if outcome == 'Flipped': np.testing.assert_allclose(args.state.state_vector(), flipped_state.state_vector())
def test_cannot_act(): class NoDetails(cirq.SingleQubitGate): pass args = cirq.ActOnStabilizerCHFormArgs(state=cirq.StabilizerStateChForm(num_qubits=3), axes=[1]) with pytest.raises(TypeError, match="Failed to act"): cirq.act_on(NoDetails(), args)
def test_act_on_ch_form(phase): state = cirq.StabilizerStateChForm(0) args = cirq.ActOnStabilizerCHFormArgs( state, [], prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(cirq.GlobalPhaseOperation(phase), args, allow_decompose=False) assert state.state_vector() == [[phase]]
def test_cannot_act(): class NoDetails(cirq.SingleQubitGate): pass args = cirq.ActOnStabilizerCHFormArgs( qubits=[], prng=np.random.RandomState(), log_of_measurement_results={}, ) with pytest.raises(TypeError, match="Failed to act"): cirq.act_on(NoDetails(), args, qubits=())
def test_act_on_stabilizer_ch_form(): a, b = [cirq.LineQubit(3), cirq.LineQubit(1)] m = cirq.measure(a, b, key='out', invert_mask=(True, )) # The below assertion does not fail since it ignores non-unitary operations cirq.testing.assert_all_implemented_act_on_effects_match_unitary(m) args = cirq.ActOnStabilizerCHFormArgs( qubits=cirq.LineQubit.range(5), prng=np.random.RandomState(), log_of_measurement_results={}, initial_state=0, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [1, 0]} args = cirq.ActOnStabilizerCHFormArgs( qubits=cirq.LineQubit.range(5), prng=np.random.RandomState(), log_of_measurement_results={}, initial_state=8, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [1, 1]} args = cirq.ActOnStabilizerCHFormArgs( qubits=cirq.LineQubit.range(5), prng=np.random.RandomState(), log_of_measurement_results={}, initial_state=10, ) cirq.act_on(m, args) datastore = cast(cirq.ClassicalDataDictionaryStore, args.classical_data) out = cirq.MeasurementKey('out') assert args.log_of_measurement_results == {'out': [0, 1]} assert datastore.records[out] == [(0, 1)] cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [0, 1]} assert datastore.records[out] == [(0, 1), (0, 1)]
def test_act_on_stabilizer_ch_form(): a, b = cirq.LineQubit.range(2) m = cirq.measure(a, b, key='out', invert_mask=(True,)) # The below assertion does not fail since it ignores non-unitary operations cirq.testing.assert_all_implemented_act_on_effects_match_unitary(m) with pytest.raises(TypeError, match="Failed to act"): cirq.act_on(m, object()) args = cirq.ActOnStabilizerCHFormArgs( state=cirq.StabilizerStateChForm(num_qubits=5, initial_state=0), axes=[3, 1], prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [1, 0]} args = cirq.ActOnStabilizerCHFormArgs( state=cirq.StabilizerStateChForm(num_qubits=5, initial_state=8), axes=[3, 1], prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [1, 1]} args = cirq.ActOnStabilizerCHFormArgs( state=cirq.StabilizerStateChForm(num_qubits=5, initial_state=10), axes=[3, 1], prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(m, args) assert args.log_of_measurement_results == {'out': [0, 1]} with pytest.raises(ValueError, match="already logged to key"): cirq.act_on(m, args)
def test_unitary_fallback_h(): class UnitaryHGate(cirq.Gate): def num_qubits(self) -> int: return 1 def _unitary_(self): return np.array([[1, 1], [1, -1]]) / (2**0.5) args = cirq.ActOnStabilizerCHFormArgs( qubits=cirq.LineQubit.range(3), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(UnitaryHGate(), args, [cirq.LineQubit(1)]) expected_args = cirq.ActOnStabilizerCHFormArgs( qubits=cirq.LineQubit.range(3), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(cirq.H, expected_args, [cirq.LineQubit(1)]) np.testing.assert_allclose(args.state.state_vector(), expected_args.state.state_vector())
def test_gate_with_act_on(): class CustomGate(cirq.SingleQubitGate): def _act_on_(self, args): if isinstance(args, cirq.ActOnStabilizerCHFormArgs): qubit = args.axes[0] args.state.gamma[qubit] += 1 return True state = cirq.StabilizerStateChForm(num_qubits=3) args = cirq.ActOnStabilizerCHFormArgs(state=state, axes=[1]) cirq.act_on(CustomGate(), args) np.testing.assert_allclose(state.gamma, [0, 1, 0])
def test_clifford_gate_act_on_ch_form(): # Although we don't support CH_form from the _act_on_, it will fall back # to the decomposititon method and apply it through decomposed ops. # Here we run it for the coverage only. args = cirq.ActOnStabilizerCHFormArgs( initial_state=cirq.StabilizerStateChForm(num_qubits=2, initial_state=1), qubits=cirq.LineQubit.range(2), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(cirq.CliffordGate.X, args, qubits=cirq.LineQubit.range(1)) np.testing.assert_allclose(args.state.state_vector(), np.array([0, 0, 0, 1]))
def test_copy(): args = cirq.ActOnStabilizerCHFormArgs( state=cirq.StabilizerStateChForm(num_qubits=3), qubits=cirq.LineQubit.range(3), prng=np.random.RandomState(), log_of_measurement_results={}, ) args1 = args.copy() assert isinstance(args1, cirq.ActOnStabilizerCHFormArgs) assert args is not args1 assert args.state is not args1.state np.testing.assert_equal(args.state.state_vector(), args1.state.state_vector()) assert args.qubits == args1.qubits assert args.prng is args1.prng assert args.log_of_measurement_results is not args1.log_of_measurement_results assert args.log_of_measurement_results == args1.log_of_measurement_results
def test_gate_with_act_on(): class CustomGate(cirq.SingleQubitGate): def _act_on_(self, args, qubits): if isinstance(args, cirq.ActOnStabilizerCHFormArgs): qubit = args.qubit_map[qubits[0]] args.state.gamma[qubit] += 1 return True state = cirq.StabilizerStateChForm(num_qubits=3) args = cirq.ActOnStabilizerCHFormArgs( state=state, qubits=cirq.LineQubit.range(3), prng=np.random.RandomState(), log_of_measurement_results={}, ) cirq.act_on(CustomGate(), args, [cirq.LineQubit(1)]) np.testing.assert_allclose(state.gamma, [0, 1, 0])
def test_run(): (q0, q1, q2) = (cirq.LineQubit(0), cirq.LineQubit(1), cirq.LineQubit(2)) qubit_map = {q0: 0, q1: 1, q2: 2} """ 0: ───H───@───────────────X───M─────────── │ 1: ───────X───@───────X───────────X───M─── │ │ 2: ───────────X───M───────────────@─────── After the third moment, before the measurement, the state is |000> + |111>. After measurement of q2, q0 and q1 both get a bit flip, so the q0 measurement always yields opposite of the q2 measurement. q1 has an additional controlled not from q2, making it yield 1 always when measured. If there were no measurements in the circuit, the final state would be |110> + |011>. """ circuit = cirq.Circuit( cirq.H(q0), cirq.CNOT(q0, q1), cirq.CNOT(q1, q2), cirq.measure(q2), cirq.X(q1), cirq.X(q0), cirq.measure(q0), cirq.CNOT(q2, q1), cirq.measure(q1), strategy=cirq.InsertStrategy.NEW, ) for _ in range(10): state = cirq.StabilizerStateChForm(num_qubits=3) measurements = {} for op in circuit.all_operations(): args = cirq.ActOnStabilizerCHFormArgs( state, axes=[qubit_map[i] for i in op.qubits], prng=np.random.RandomState(), log_of_measurement_results=measurements, ) cirq.act_on(op, args) assert measurements['1'] == [1] assert measurements['0'] != measurements['2']
def test_deprecated_warning(): with cirq.testing.assert_deprecated( 'Specify all the arguments with keywords', deadline='v0.15'): cirq.ActOnStabilizerCHFormArgs( cirq.StabilizerStateChForm(num_qubits=3))
def test_act_on_ch_form(phase): state = cirq.StabilizerStateChForm(0) args = cirq.ActOnStabilizerCHFormArgs(state, []) cirq.act_on(cirq.GlobalPhaseOperation(phase), args, allow_decompose=False) assert state.state_vector() == [[phase]]
def test_axes_deprecation(): state = cirq.StabilizerStateChForm(num_qubits=3) rng = np.random.RandomState() qids = tuple(cirq.LineQubit.range(3)) log = {} # No kwargs with cirq.testing.assert_deprecated("axes", deadline="v0.13"): args = cirq.ActOnStabilizerCHFormArgs(state, (1,), rng, log, qids) # type: ignore with cirq.testing.assert_deprecated("axes", deadline="v0.13"): assert args.axes == (1,) assert args.prng is rng assert args.state is state assert args.log_of_measurement_results is log assert args.qubits is qids # kwargs no axes with cirq.testing.assert_deprecated("axes", deadline="v0.13"): args = cirq.ActOnStabilizerCHFormArgs( state, (1,), # type: ignore qubits=qids, prng=rng, log_of_measurement_results=log, ) with cirq.testing.assert_deprecated("axes", deadline="v0.13"): assert args.axes == (1,) assert args.prng is rng assert args.state is state assert args.log_of_measurement_results is log assert args.qubits is qids # kwargs incl axes with cirq.testing.assert_deprecated("axes", deadline="v0.13"): args = cirq.ActOnStabilizerCHFormArgs( state, axes=(1,), qubits=qids, prng=rng, log_of_measurement_results=log, ) with cirq.testing.assert_deprecated("axes", deadline="v0.13"): assert args.axes == (1,) assert args.prng is rng assert args.state is state assert args.log_of_measurement_results is log assert args.qubits is qids # All kwargs with cirq.testing.assert_deprecated("axes", deadline="v0.13"): args = cirq.ActOnStabilizerCHFormArgs( state=state, axes=(1,), qubits=qids, prng=rng, log_of_measurement_results=log, ) with cirq.testing.assert_deprecated("axes", deadline="v0.13"): assert args.axes == (1,) assert args.prng is rng assert args.state is state assert args.log_of_measurement_results is log assert args.qubits is qids