def test_single_qubit_matrix_to_phxz_tolerance_z(): z = np.diag([1, np.exp(1j * 0.01)]) optimized_away = cirq.single_qubit_matrix_to_phxz(z, atol=0.1) assert optimized_away is None kept = cirq.single_qubit_matrix_to_phxz(z, atol=0.0001) assert kept is not None
def test_single_qubit_matrix_to_phxz_tolerance_xy(): c, s = np.cos(0.01), np.sin(0.01) xy = np.array([[c, -s], [s, c]]) optimized_away = cirq.single_qubit_matrix_to_phxz(xy, atol=0.1) assert optimized_away is None kept = cirq.single_qubit_matrix_to_phxz(xy, atol=0.0001) assert kept is not None
def test_single_qubit_matrix_to_phxz_tolerance_half_turn_phasing(): a = np.pi / 2 + 0.01 c, s = np.cos(a), np.sin(a) nearly_x = np.array([[c, -s], [s, c]]) z1 = np.diag([1, np.exp(1j * 1.2)]) z2 = np.diag([1, np.exp(1j * 1.6)]) phased_nearly_x = z1.dot(nearly_x).dot(z2) optimized_away = cirq.single_qubit_matrix_to_phxz(phased_nearly_x, atol=0.1) assert optimized_away.z_exponent == 0 kept = cirq.single_qubit_matrix_to_phxz(phased_nearly_x, atol=0.0001) assert kept.z_exponent != 0
def test_single_qubit_matrix_to_phxz_fuzz_half_turns_always_one_gate( pre_turns, post_turns): atol = 1e-6 aggr_atol = atol * 10.0 intended_effect = cirq.dot(cirq.unitary(cirq.Z**(2 * pre_turns)), cirq.unitary(cirq.X), cirq.unitary(cirq.Z**(2 * post_turns))) gate = cirq.single_qubit_matrix_to_phxz(intended_effect, atol=atol) assert gate.z_exponent == 0 assert_gates_implement_unitary([gate], intended_effect, atol=aggr_atol)
def test_optimize_for_target_gateset_deep(): q0, q1 = cirq.LineQubit.range(2) c_nested = cirq.FrozenCircuit(cirq.CX(q0, q1)) c_orig = cirq.Circuit( cirq.CircuitOperation( cirq.FrozenCircuit( cirq.H(q0), cirq.CircuitOperation(c_nested).repeat(3))).repeat(5)) c_expected = cirq.Circuit( cirq.CircuitOperation( cirq.FrozenCircuit( cirq.single_qubit_matrix_to_phxz(cirq.unitary( cirq.H(q0))).on(q0), cirq.CircuitOperation( cirq.FrozenCircuit( cirq.MatrixGate(c_nested.unitary(qubit_order=[q0, q1]), name="M").on(q0, q1))).repeat(3), )).repeat(5)) gateset = MatrixGateTargetGateset() context = cirq.TransformerContext(deep=True) c_new = cirq.optimize_for_target_gateset(c_orig, gateset=gateset, context=context) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( c_new, c_expected) cirq.testing.assert_has_diagram( c_orig, ''' [ [ 0: ───@─── ] ] [ 0: ───H───[ │ ]──────────── ] 0: ───[ [ 1: ───X─── ](loops=3) ]──────────── [ │ ] [ 1: ───────#2──────────────────────── ](loops=5) │ 1: ───#2────────────────────────────────────────────────── ''', ) cirq.testing.assert_has_diagram( c_new, ''' [ [ 0: ───M[1]─── ] ] [ 0: ───PhXZ(a=-0.5,x=0.5,z=-1)───[ │ ]──────────── ] 0: ───[ [ 1: ───M[2]─── ](loops=3) ]──────────── [ │ ] [ 1: ─────────────────────────────#2─────────────────────────── ](loops=5) │ 1: ───#2─────────────────────────────────────────────────────────────────────────── ''', )
def test_single_qubit_matrix_to_phxz_cases(intended_effect): gate = cirq.single_qubit_matrix_to_phxz(intended_effect, atol=1e-6) assert_gates_implement_unitary([gate], intended_effect, atol=1e-5)
def _phased_x_z_ops(mat: np.ndarray, q: cirq.Qid) -> Iterator[cirq.Operation]: gate = cirq.single_qubit_matrix_to_phxz(mat) if gate: yield gate(q)
def merge_func(m1: cirq.Moment, m2: cirq.Moment): gate = cirq.single_qubit_matrix_to_phxz(cirq.unitary(cirq.Circuit(m1, m2)), atol=1e-8) return cirq.Moment(gate.on(q) if gate else [])
def _phased_x_z_ops(mat: np.ndarray, q: cirq.Qid) -> Iterator[cirq.Operation]: """Yields `cirq.PhasedXZGate` operation implementing `mat` if it is not identity.""" gate = cirq.single_qubit_matrix_to_phxz(mat) if gate: yield gate(q)