def test_protocols(): for p in [1, 1j, -1]: cirq.testing.assert_implements_consistent_protocols(cirq.global_phase_operation(p)) np.testing.assert_allclose( cirq.unitary(cirq.global_phase_operation(1j)), np.array([[1j]]), atol=1e-8 )
def test_init(): op = cirq.global_phase_operation(1j) assert op.gate.coefficient == 1j assert op.qubits == () assert op.with_qubits() == op assert cirq.has_stabilizer_effect(op) with pytest.raises(ValueError, match='not unitary'): _ = cirq.global_phase_operation(2) with pytest.raises(ValueError, match='0 qubits'): _ = cirq.global_phase_operation(1j).with_qubits(cirq.LineQubit(0))
def test_valid_check_raises(): q0 = cirq.LineQubit(0) with pytest.raises(AssertionError, match='Unitaries are completely different'): assert_valid_decomp( np.eye(4), [cirq.X(q0)], single_qubit_gate_types=(cirq.XPowGate, ), ) with pytest.raises(AssertionError, match='Unitaries do not match closely enough'): assert_valid_decomp( np.eye(4), [cirq.rx(0.01)(q0)], single_qubit_gate_types=(cirq.Rx, ), ) with pytest.raises( AssertionError, match='Global phase operation was output when it should not'): assert_valid_decomp(np.eye(4), [cirq.global_phase_operation(np.exp(1j * 0.01))]) with pytest.raises(AssertionError, match='Disallowed operation was output'): assert_valid_decomp( np.eye(4), [cirq.X(q0)], single_qubit_gate_types=(cirq.IdentityGate, ), )
def test_act_on_ch_form(phase): state = cirq.StabilizerStateChForm(0) args = cirq.StabilizerChFormSimulationState( qubits=[], prng=np.random.RandomState(), initial_state=state ) cirq.act_on(cirq.global_phase_operation(phase), args, allow_decompose=False) assert state.state_vector() == [[phase]]
def test_is_supported_operation(): class MultiQubitOp(cirq.Operation): """Multi-qubit operation with unitary. Used to verify that `is_supported_operation` does not attempt to allocate the unitary for multi-qubit operations. """ @property def qubits(self): return cirq.LineQubit.range(100) def with_qubits(self, *new_qubits): raise NotImplementedError() def _has_unitary_(self): return True def _unitary_(self): assert False q1, q2 = cirq.LineQubit.range(2) assert cirq.CliffordSimulator.is_supported_operation(cirq.X(q1)) assert cirq.CliffordSimulator.is_supported_operation(cirq.H(q1)) assert cirq.CliffordSimulator.is_supported_operation(cirq.CNOT(q1, q2)) assert cirq.CliffordSimulator.is_supported_operation(cirq.measure(q1)) assert cirq.CliffordSimulator.is_supported_operation(cirq.global_phase_operation(1j)) assert not cirq.CliffordSimulator.is_supported_operation(cirq.T(q1)) assert not cirq.CliffordSimulator.is_supported_operation(MultiQubitOp())
def test_simulate_global_phase_operation(): q1, q2 = cirq.LineQubit.range(2) circuit = cirq.Circuit([cirq.I(q1), cirq.I(q2), cirq.global_phase_operation(-1j)]) simulator = cirq.CliffordSimulator() result = simulator.simulate(circuit).final_state.state_vector() assert np.allclose(result, [-1j, 0, 0, 0])
def test_act_on_tableau(phase): original_tableau = cirq.CliffordTableau(0) args = cirq.ActOnCliffordTableauArgs(original_tableau.copy(), np.random.RandomState(), {}) cirq.act_on(cirq.global_phase_operation(phase), args, allow_decompose=False) assert args.tableau == original_tableau
def test_scalar_operations(): assert_url_to_circuit_returns('{"cols":[["…"]]}', cirq.Circuit()) assert_url_to_circuit_returns( '{"cols":[["NeGate"]]}', cirq.Circuit(cirq.global_phase_operation(-1))) assert_url_to_circuit_returns( '{"cols":[["i"]]}', cirq.Circuit(cirq.global_phase_operation(1j))) assert_url_to_circuit_returns( '{"cols":[["-i"]]}', cirq.Circuit(cirq.global_phase_operation(-1j))) assert_url_to_circuit_returns( '{"cols":[["√i"]]}', cirq.Circuit(cirq.global_phase_operation(1j**0.5))) assert_url_to_circuit_returns( '{"cols":[["√-i"]]}', cirq.Circuit(cirq.global_phase_operation(1j**-0.5)))
def test_ideal_sqrt_iswap_simulates_correctly_invalid_circuit_fails(): engine_simulator = PhasedFSimEngineSimulator.create_with_ideal_sqrt_iswap() with pytest.raises(IncompatibleMomentError): a, b = cirq.LineQubit.range(2) circuit = cirq.Circuit([cirq.CZ.on(a, b)]) engine_simulator.simulate(circuit) with pytest.raises(IncompatibleMomentError): circuit = cirq.Circuit(cirq.global_phase_operation(coefficient=1.0)) engine_simulator.simulate(circuit)
def test_sampler_sample_expectation_values_complex_param(): a = cirq.LineQubit(0) t = sympy.Symbol('t') sampler = cirq.Simulator(seed=1) circuit = cirq.Circuit(cirq.global_phase_operation(t)) obs = cirq.Z(a) results = sampler.sample_expectation_values( circuit, [obs], num_samples=5, params=cirq.Points('t', [1, 1j, (1 + 1j) / np.sqrt(2)])) assert np.allclose(results, [[1], [1], [1]])
def test_act_on_ch_form(phase): state = cirq.StabilizerStateChForm(0) args = cirq.ActOnStabilizerCHFormArgs( qubits=[], prng=np.random.RandomState(), log_of_measurement_results={}, initial_state=state, ) cirq.act_on(cirq.global_phase_operation(phase), args, allow_decompose=False) assert state.state_vector() == [[phase]]
def test_tagged_measurement(): assert not cirq.is_measurement( cirq.global_phase_operation(coefficient=-1.0).with_tags('tag0')) a = cirq.LineQubit(0) op = cirq.measure(a, key='m').with_tags('tag') assert cirq.is_measurement(op) remap_op = cirq.with_measurement_key_mapping(op, {'m': 'k'}) assert remap_op.tags == ('tag', ) assert cirq.is_measurement(remap_op) assert cirq.measurement_key_names(remap_op) == {'k'} assert cirq.with_measurement_key_mapping(op, {'x': 'k'}) == op
def test_unseparated_states_str(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit( cirq.measure(q0), cirq.measure(q1), cirq.H(q0), cirq.global_phase_operation(0 + 1j), ) result = cirq.Simulator(split_untangled_states=False).simulate(circuit) assert ( str(result) == """measurements: 0=0 1=0 qubits: (cirq.LineQubit(0), cirq.LineQubit(1)) output vector: 0.707j|00⟩ + 0.707j|10⟩""" )
def test_merge_operations_nothing_to_merge(): def fail_if_called_func(*_): assert False # Empty Circuit. c = cirq.Circuit() assert cirq.merge_operations(c, fail_if_called_func) == c # Single moment q = cirq.LineQubit.range(3) c += cirq.Moment(cirq.CZ(*q[:2])) assert cirq.merge_operations(c, fail_if_called_func) == c # Multi moment with disjoint operations + global phase operation. c += cirq.Moment(cirq.X(q[2]), cirq.global_phase_operation(1j)) assert cirq.merge_operations(c, fail_if_called_func) == c # Tagged operations to be ignored. c += cirq.Moment(cirq.CNOT(*q[:2]).with_tags("ignore")) assert cirq.merge_operations(c, fail_if_called_func, tags_to_ignore=["ignore"]) == c
def cphase_to_sqrt_iswap(a, b, turns): """Implement a C-Phase gate using two sqrt ISWAP gates and single-qubit operations. The circuit is equivalent to cirq.CZPowGate(exponent=turns). Output unitary: [1 0 0 0], [0 1 0 0], [0 0 1 0], [0 0 0 e^{i turns pi}]. Args: a: the first qubit b: the second qubit turns: Exponent specifying the evolution time in number of rotations. """ theta = (turns % 2) * np.pi if 0 <= theta <= np.pi: sign = 1.0 theta_prime = theta elif np.pi < theta < 2 * np.pi: sign = -1.0 theta_prime = 2 * np.pi - theta if np.isclose(theta, np.pi): # If we are close to pi, just set values manually to avoid possible # numerical errors with arcsin of greater than 1.0 (Ahem, Windows). phi = np.pi / 2 xi = np.pi / 2 else: phi = np.arcsin(np.sqrt(2) * np.sin(theta_prime / 4)) xi = np.arctan(np.tan(phi) / np.sqrt(2)) yield cirq.rz(sign * 0.5 * theta_prime).on(a) yield cirq.rz(sign * 0.5 * theta_prime).on(b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(-sign * 0.5) yield cirq.SQRT_ISWAP_INV(a, b) yield cirq.rx(-2 * phi).on(a) yield cirq.SQRT_ISWAP(a, b) yield cirq.rx(xi).on(a) yield cirq.X(b)**(sign * 0.5) # Corrects global phase yield cirq.global_phase_operation(np.exp(sign * theta_prime * 0.25j))
def test_separated_states_str_does_not_merge(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit( cirq.measure(q0), cirq.measure(q1), cirq.H(q0), cirq.global_phase_operation(0 + 1j), ) result = cirq.Simulator().simulate(circuit) assert ( str(result) == """measurements: 0=0 1=0 qubits: (cirq.LineQubit(0),) output vector: 0.707|0⟩ + 0.707|1⟩ qubits: (cirq.LineQubit(1),) output vector: |0⟩ phase: output vector: 1j|⟩""" )
def get_ops(use_circuit_op, use_global_phase): q = cirq.LineQubit.range(3) yield [ CustomX(q[0]).with_tags('custom tags'), CustomX(q[1])**2, CustomX(q[2])**3 ] yield [CustomX(q[0])**0.5, cirq.testing.TwoQubitGate()(*q[:2])] if use_circuit_op: circuit_op = cirq.CircuitOperation( cirq.FrozenCircuit(get_ops(False, False)), repetitions=10).with_tags('circuit op tags') recursive_circuit_op = cirq.CircuitOperation( cirq.FrozenCircuit([circuit_op, CustomX(q[2])**0.5]), repetitions=10, qubit_map={ q[0]: q[1], q[1]: q[2], q[2]: q[0] }, ) yield [circuit_op, recursive_circuit_op] if use_global_phase: yield cirq.global_phase_operation(1j)
def test_circuit_diagram_tagged_global_phase(): # Tests global phase operation q = cirq.NamedQubit('a') global_phase = cirq.global_phase_operation( coefficient=-1.0).with_tags('tag0') # Just global phase in a circuit assert cirq.circuit_diagram_info(global_phase, default='default') == 'default' cirq.testing.assert_has_diagram(cirq.Circuit(global_phase), "\n\nglobal phase: π['tag0']", use_unicode_characters=True) cirq.testing.assert_has_diagram( cirq.Circuit(global_phase), "\n\nglobal phase: π", use_unicode_characters=True, include_tags=False, ) expected = cirq.CircuitDiagramInfo( wire_symbols=(), exponent=1.0, connected=True, exponent_qubit_index=None, auto_exponent_parens=True, ) # Operation with no qubits and returns diagram info with no wire symbols class NoWireSymbols(cirq.GlobalPhaseGate): def _circuit_diagram_info_( self, args: 'cirq.CircuitDiagramInfoArgs' ) -> 'cirq.CircuitDiagramInfo': return expected no_wire_symbol_op = NoWireSymbols(coefficient=-1.0)().with_tags('tag0') assert cirq.circuit_diagram_info(no_wire_symbol_op, default='default') == expected cirq.testing.assert_has_diagram( cirq.Circuit(no_wire_symbol_op), "\n\nglobal phase: π['tag0']", use_unicode_characters=True, ) # Two global phases in one moment tag1 = cirq.global_phase_operation(coefficient=1j).with_tags('tag1') tag2 = cirq.global_phase_operation(coefficient=1j).with_tags('tag2') c = cirq.Circuit([cirq.X(q), tag1, tag2]) cirq.testing.assert_has_diagram( c, """\ a: ─────────────X─────────────────── global phase: π['tag1', 'tag2']""", use_unicode_characters=True, precision=2, ) # Two moments with global phase, one with another tagged gate c = cirq.Circuit([cirq.X(q).with_tags('x_tag'), tag1]) c.append(cirq.Moment([cirq.X(q), tag2])) cirq.testing.assert_has_diagram( c, """\ a: ─────────────X['x_tag']─────X────────────── global phase: 0.5π['tag1'] 0.5π['tag2'] """, use_unicode_characters=True, include_tags=True, )
def test_string_format(): x, y, z = cirq.LineQubit.range(3) fc0 = cirq.FrozenCircuit() op0 = cirq.CircuitOperation(fc0) assert str(op0) == f"[ ]" fc0_global_phase_inner = cirq.FrozenCircuit( cirq.global_phase_operation(1j), cirq.global_phase_operation(1j)) op0_global_phase_inner = cirq.CircuitOperation(fc0_global_phase_inner) fc0_global_phase_outer = cirq.FrozenCircuit( op0_global_phase_inner, cirq.global_phase_operation(1j)) op0_global_phase_outer = cirq.CircuitOperation(fc0_global_phase_outer) assert (str(op0_global_phase_outer) == f"""\ [ ] [ ] [ global phase: -0.5π ]""") fc1 = cirq.FrozenCircuit(cirq.X(x), cirq.H(y), cirq.CX(y, z), cirq.measure(x, y, z, key='m')) op1 = cirq.CircuitOperation(fc1) assert (str(op1) == f"""\ [ 0: ───X───────M('m')─── ] [ │ ] [ 1: ───H───@───M──────── ] [ │ │ ] [ 2: ───────X───M──────── ]""") assert (repr(op1) == """\ cirq.CircuitOperation( circuit=cirq.FrozenCircuit([ cirq.Moment( cirq.X(cirq.LineQubit(0)), cirq.H(cirq.LineQubit(1)), ), cirq.Moment( cirq.CNOT(cirq.LineQubit(1), cirq.LineQubit(2)), ), cirq.Moment( cirq.measure(cirq.LineQubit(0), cirq.LineQubit(1), cirq.LineQubit(2), key=cirq.MeasurementKey(name='m')), ), ]), )""") fc2 = cirq.FrozenCircuit(cirq.X(x), cirq.H(y), cirq.CX(y, x)) op2 = cirq.CircuitOperation( circuit=fc2, qubit_map=({ y: z }), repetitions=3, parent_path=('outer', 'inner'), repetition_ids=['a', 'b', 'c'], ) assert (str(op2) == f"""\ [ 0: ───X───X─── ] [ │ ] [ 1: ───H───@─── ](qubit_map={{1: 2}}, parent_path=('outer', 'inner'),\ repetition_ids=['a', 'b', 'c'])""") assert (repr(op2) == """\ cirq.CircuitOperation( circuit=cirq.FrozenCircuit([ cirq.Moment( cirq.X(cirq.LineQubit(0)), cirq.H(cirq.LineQubit(1)), ), cirq.Moment( cirq.CNOT(cirq.LineQubit(1), cirq.LineQubit(0)), ), ]), repetitions=3, qubit_map={cirq.LineQubit(1): cirq.LineQubit(2)}, parent_path=('outer', 'inner'), repetition_ids=['a', 'b', 'c'], )""") fc3 = cirq.FrozenCircuit( cirq.X(x)**sympy.Symbol('b'), cirq.measure(x, key='m'), ) op3 = cirq.CircuitOperation( circuit=fc3, qubit_map={x: y}, measurement_key_map={'m': 'p'}, param_resolver={sympy.Symbol('b'): 2}, ) indented_fc3_repr = repr(fc3).replace('\n', '\n ') assert (str(op3) == f"""\ [ 0: ───X^b───M('m')─── ](qubit_map={{0: 1}}, \ key_map={{m: p}}, params={{b: 2}})""") assert (repr(op3) == f"""\ cirq.CircuitOperation( circuit={indented_fc3_repr}, qubit_map={{cirq.LineQubit(0): cirq.LineQubit(1)}}, measurement_key_map={{'m': 'p'}}, param_resolver=cirq.ParamResolver({{sympy.Symbol('b'): 2}}), )""") fc4 = cirq.FrozenCircuit(cirq.X(y)) op4 = cirq.CircuitOperation(fc4) fc5 = cirq.FrozenCircuit(cirq.X(x), op4) op5 = cirq.CircuitOperation(fc5) assert (repr(op5) == """\ cirq.CircuitOperation( circuit=cirq.FrozenCircuit([ cirq.Moment( cirq.X(cirq.LineQubit(0)), cirq.CircuitOperation( circuit=cirq.FrozenCircuit([ cirq.Moment( cirq.X(cirq.LineQubit(1)), ), ]), ), ), ]), )""") op6 = cirq.CircuitOperation(fc5, use_repetition_ids=False) assert (repr(op6) == """\ cirq.CircuitOperation( circuit=cirq.FrozenCircuit([ cirq.Moment( cirq.X(cirq.LineQubit(0)), cirq.CircuitOperation( circuit=cirq.FrozenCircuit([ cirq.Moment( cirq.X(cirq.LineQubit(1)), ), ]), ), ), ]), use_repetition_ids=False, )""") op7 = cirq.CircuitOperation( cirq.FrozenCircuit(cirq.measure(x, key='a')), use_repetition_ids=False, repeat_until=cirq.KeyCondition(cirq.MeasurementKey('a')), ) assert (repr(op7) == """\ cirq.CircuitOperation( circuit=cirq.FrozenCircuit([ cirq.Moment( cirq.measure(cirq.LineQubit(0), key=cirq.MeasurementKey(name='a')), ), ]), use_repetition_ids=False, repeat_until=cirq.KeyCondition(cirq.MeasurementKey(name='a')), )""")
@pytest.mark.parametrize( 'gate_family, gates_to_check', [ ( cirq.GateFamily(CustomXPowGate), [ (CustomX, True), (CustomX**0.5, True), (CustomX**sympy.Symbol('theta'), True), (CustomXPowGate(exponent=0.25, global_shift=0.15), True), (cirq.testing.SingleQubitGate(), False), (cirq.X**0.5, False), (None, False), (cirq.global_phase_operation(1j), False), ], ), ( cirq.GateFamily(CustomX), [ (CustomX, True), (CustomXPowGate(exponent=1, global_shift=0.15), True), (CustomX**2, False), (CustomX**3, True), (CustomX**sympy.Symbol('theta'), False), (None, False), (cirq.global_phase_operation(1j), False), ], ), (
def test_str(): assert str(cirq.global_phase_operation(1j)) == '1j'
def test_repr(): op = cirq.global_phase_operation(1j) cirq.testing.assert_equivalent_repr(op)
def test_diagram(): a, b = cirq.LineQubit.range(2) x, y = cirq.LineQubit.range(10, 12) cirq.testing.assert_has_diagram( cirq.Circuit( [cirq.Moment([cirq.CNOT(a, x), cirq.CNOT(b, y), cirq.global_phase_operation(-1)])] ), """ ┌──┐ 0: ──────────────@───── │ 1: ──────────────┼@──── ││ 10: ─────────────X┼──── │ 11: ──────────────X──── global phase: π └──┘ """, ) cirq.testing.assert_has_diagram( cirq.Circuit( [ cirq.Moment( [ cirq.CNOT(a, x), cirq.CNOT(b, y), cirq.global_phase_operation(-1), cirq.global_phase_operation(-1), ] ) ] ), """ ┌──┐ 0: ──────────────@───── │ 1: ──────────────┼@──── ││ 10: ─────────────X┼──── │ 11: ──────────────X──── global phase: └──┘ """, ) cirq.testing.assert_has_diagram( cirq.Circuit( [ cirq.Moment( [ cirq.CNOT(a, x), cirq.CNOT(b, y), cirq.global_phase_operation(-1), cirq.global_phase_operation(-1), ] ), cirq.Moment([cirq.global_phase_operation(1j)]), cirq.Moment([cirq.X(a)]), ] ), """ ┌──┐ 0: ──────────────@────────────X─── │ 1: ──────────────┼@─────────────── ││ 10: ─────────────X┼─────────────── │ 11: ──────────────X─────────────── global phase: 0.5π └──┘ """, ) cirq.testing.assert_has_diagram( cirq.Circuit([cirq.Moment([cirq.X(a)]), cirq.Moment([cirq.global_phase_operation(-1j)])]), """ 0: ─────────────X─────────── global phase: -0.5π """, ) cirq.testing.assert_has_diagram( cirq.Circuit([cirq.Moment([cirq.X(a), cirq.global_phase_operation(np.exp(1j))])]), """ 0: ─────────────X──────── global phase: 0.318π """, ) cirq.testing.assert_has_diagram( cirq.Circuit([cirq.Moment([cirq.X(a), cirq.global_phase_operation(np.exp(1j))])]), """ 0: ─────────────X────────── global phase: 0.31831π """, precision=5, ) cirq.testing.assert_has_diagram( cirq.Circuit( [ cirq.Moment([cirq.X(a), cirq.global_phase_operation(1j)]), cirq.Moment([cirq.global_phase_operation(-1j)]), ] ), """ 0: -------------X---------------- global phase: 0.5pi -0.5pi """, use_unicode_characters=False, ) cirq.testing.assert_has_diagram( cirq.Circuit([cirq.Moment([cirq.global_phase_operation(-1j)])]), """ global phase: -0.5π """, )