def test_assert_new_device_deprecated(): u = cirq.testing.random_special_unitary(2) q = cirq.LineQubit(0) circuit0 = cirq.Circuit(cirq.MatrixGate(u).on(q)) _ = cg.optimized_for_sycamore(circuit0, optimizer_type='sqrt_iswap') with cirq.testing.assert_deprecated( cirq.circuits.circuit._DEVICE_DEP_MESSAGE, deadline='v0.15'): _ = cg.optimized_for_sycamore(circuit0, optimizer_type='sqrt_iswap', new_device=cg.Foxtail)
def test_decompose_single_qubit_matrix_gate(): q = cirq.LineQubit(0) for _ in range(100): gate = cirq.MatrixGate(cirq.testing.random_unitary(2)) circuit = cirq.Circuit(gate(q)) decomposed_circuit = cirq.Circuit(*ionq.decompose_to_device(gate(q))) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, decomposed_circuit, atol=1e-8 ) assert VALID_DECOMPOSED_GATES.validate(decomposed_circuit)
def test_tensor_density_matrix_2(): q = cirq.LineQubit.range(2) rs = np.random.RandomState(52) for _ in range(10): g = cirq.MatrixGate( cirq.testing.random_unitary(dim=2**len(q), random_state=rs)) c = cirq.Circuit(g.on(*q)) rho1 = cirq.final_density_matrix(c, dtype=np.complex128) rho2 = ccq.tensor_density_matrix(c, q) np.testing.assert_allclose(rho1, rho2, atol=1e-8)
def test_decompose_two_qubit_matrix_gate(): q0, q1 = cirq.LineQubit.range(2) for _ in range(10): gate = cirq.MatrixGate(cirq.testing.random_unitary(4)) circuit = cirq.Circuit(gate(q0, q1)) decomposed_circuit = cirq.optimize_for_target_gateset( circuit, gateset=ionq_target_gateset, ignore_failures=False) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, decomposed_circuit, atol=1e-8) assert VALID_DECOMPOSED_GATES.validate(decomposed_circuit)
def test_decompose_to_diagonal_and_circuit(v): b, c = cirq.LineQubit.range(2) diagonal, ops = two_qubit_matrix_to_diagonal_and_cz_operations(b, c, v) assert cirq.is_diagonal(diagonal) combined_circuit = cirq.Circuit(cirq.MatrixGate(diagonal)(b, c), ops) circuit_unitary = combined_circuit.unitary( qubits_that_should_be_present=[b, c]) cirq.testing.assert_allclose_up_to_global_phase(circuit_unitary, v, atol=2e-6)
def test_controlled_matrix_gates(): qubits = cirq.LineQubit.range(4) m1 = np.array([[1, 1j], [1j, 1]]) * np.sqrt(0.5) m2 = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) cirq_circuit = cirq.Circuit( cirq.MatrixGate(m1).on(qubits[0]).controlled_by(qubits[3]), cirq.MatrixGate(m2).on(*qubits[1:3]).controlled_by(qubits[0]), cirq.MatrixGate(m1).on(qubits[2]).controlled_by( qubits[0], qubits[1], qubits[3]), cirq.MatrixGate(m2).on(qubits[0], qubits[3]).controlled_by(*qubits[1:3]), ) qsimSim = qsimcirq.QSimSimulator() result = qsimSim.simulate(cirq_circuit, qubit_order=qubits) assert result.state_vector().shape == (16, ) cirqSim = cirq.Simulator() cirq_result = cirqSim.simulate(cirq_circuit, qubit_order=qubits) assert cirq.linalg.allclose_up_to_global_phase(result.state_vector(), cirq_result.state_vector())
def test_QulacsSimulator_TwoQubitMatrixGate(self): qubits = [cirq.LineQubit(i) for i in range(self.qubit_n)] circuit = cirq.Circuit() all_indices = np.arange(self.qubit_n) for _ in range(self.test_repeat): np.random.shuffle(all_indices) index = all_indices[:2] mat = unitary_group.rvs(4) circuit.append( cirq.MatrixGate(mat).on(qubits[index[0]], qubits[index[1]])) self.check_result(circuit)
def test_random_same_matrix(circuit): a, b = cirq.LineQubit.range(2) same = cirq.Circuit( cirq.MatrixGate(circuit.unitary(qubits_that_should_be_present=[a, b])).on(a, b) ) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(circuit, same) circuit.append(cirq.measure(a)) same.append(cirq.measure(a)) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent(circuit, same)
def test_custom_matrix_gate(): a, b = cirq.LineQubit.range(2) # Without name. assert_url_to_circuit_returns( '{"cols":[["~cv0d"]],"gates":[{"id":"~cv0d","matrix":"{{0,1},{1,0}}"}]}', cirq.Circuit(cirq.MatrixGate(np.array([[0, 1], [1, 0]])).on(a)), ) # With name. assert_url_to_circuit_returns( '{"cols":[["~cv0d"]],"gates":[{"id":"~cv0d","name":"test","matrix":"{{0,i},{1,0}}"}]}', cirq.Circuit(cirq.MatrixGate(np.array([[0, 1j], [1, 0]])).on(a)), ) # Multi-qubit. Reversed qubit order to account for endian-ness difference. assert_url_to_circuit_returns( '{"cols":[["X"],["~2hj0"]],' '"gates":[{"id":"~2hj0",' '"matrix":"{{-1,0,0,0},{0,i,0,0},{0,0,1,0},{0,0,0,-i}}"}]}', cirq.Circuit(cirq.X(a), cirq.MatrixGate(np.diag([-1, 1j, 1, -1j])).on(b, a)), output_amplitudes_from_quirk=[ { "r": 0, "i": 0 }, { "r": 0, "i": 1 }, { "r": 0, "i": 0 }, { "r": 0, "i": 0 }, ], )
def test_decompose_two_qubit_matrix_gate_deprecated(): q0, q1 = cirq.LineQubit.range(2) device = ionq.IonQAPIDevice(qubits=[q0, q1]) for _ in range(10): gate = cirq.MatrixGate(cirq.testing.random_unitary(4)) circuit = cirq.Circuit(gate(q0, q1)) with cirq.testing.assert_deprecated('decompose_to_device', deadline='v0.15'): decomposed_circuit = cirq.Circuit(*device.decompose_operation(gate(q0, q1))) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, decomposed_circuit, atol=1e-8 ) assert VALID_DECOMPOSED_GATES.validate(decomposed_circuit)
def _test_decompose(matrix, controls_count): qubits = cirq.LineQubit.range(controls_count + 1) operations = cirq.decompose_multi_controlled_rotation( matrix, qubits[:-1], qubits[-1]) _count_operations(operations) result_matrix = cirq.Circuit(operations).unitary() expected_matrix = cirq.Circuit([ cirq.MatrixGate(matrix).on(qubits[-1]).controlled_by(*qubits[:-1]) ]).unitary() assert np.allclose(expected_matrix, result_matrix)
def test_matrix2_gate(self): qubits = cirq.LineQubit.range(2) m = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) cirq_circuit = cirq.Circuit(cirq.MatrixGate(m).on(*qubits)) qsimSim = qsimcirq.QSimSimulator() result = qsimSim.simulate(cirq_circuit, qubit_order=qubits) assert result.state_vector().shape == (4, ) cirqSim = cirq.Simulator() cirq_result = cirqSim.simulate(cirq_circuit, qubit_order=qubits) assert cirq.linalg.allclose_up_to_global_phase( result.state_vector(), cirq_result.state_vector())
def test_convert_to_sycamore_tabulation(): # A tabulation for the sycamore gate with an infidelity of .1. sycamore_tabulation = gate_product_tabulation( cirq.unitary(cirq_google.SYC), 0.1, random_state=_rng ) qubits = [cirq.NamedQubit('a'), cirq.NamedQubit('b')] operation = cirq.MatrixGate(cirq.unitary(cirq.CX), qid_shape=(2, 2)).on(qubits[0], qubits[1]) converted = cgoc.ConvertToSycamoreGates(sycamore_tabulation).convert(operation) u1 = cirq.unitary(cirq.Circuit(converted)) u2 = cirq.unitary(operation) overlap = abs(np.trace(u1.conj().T @ u2)) assert np.isclose(overlap, 4.0, 0.1)
def test_single_qubit_gate(): q = cirq.LineQubit(0) mat = cirq.testing.random_unitary(2) gate = cirq.MatrixGate(mat, qid_shape=(2, )) circuit = cirq.Circuit(gate(q)) compiled_circuit = cirq.optimize_for_target_gateset( circuit, gateset=cirq_google.SycamoreTargetGateset()) ops = list(compiled_circuit.all_operations()) assert len(ops) == 1 assert isinstance(ops[0].gate, cirq.PhasedXZGate) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, compiled_circuit, atol=1e-8)
def test_single_qubit_gate(): q = cirq.LineQubit(0) mat = cirq.testing.random_unitary(2) gate = cirq.MatrixGate(mat, qid_shape=(2,)) circuit = cirq.Circuit(gate(q)) converted_circuit = circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(converted_circuit) for op in converted_circuit.all_operations(): gate = op.gate assert isinstance(gate, (cirq.PhasedXPowGate, cirq.ZPowGate)) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, converted_circuit, atol=1e-8)
def test_matrix1_gate(self): q = cirq.LineQubit(0) m = np.array([[1, 1j], [1j, 1]]) * np.sqrt(0.5) cirq_circuit = cirq.Circuit(cirq.MatrixGate(m).on(q)) qsimSim = qsimcirq.QSimSimulator() result = qsimSim.simulate(cirq_circuit) assert result.state_vector().shape == (2, ) cirqSim = cirq.Simulator() cirq_result = cirqSim.simulate(cirq_circuit) assert cirq.linalg.allclose_up_to_global_phase( result.state_vector(), cirq_result.state_vector())
def test_unitary_matrix_gate_controlled_by(backend, nqubits, ntargets, ndevices): """Check arbitrary unitary gate controlled on arbitrary number of qubits.""" original_backend = qibo.get_backend() qibo.set_backend(backend) all_qubits = np.arange(nqubits) for _ in range(10): activeq = random_active_qubits(nqubits, nactive=5) matrix = random_unitary_matrix(ntargets) qibo_gate = gates.Unitary(matrix, *activeq[-ntargets:]).controlled_by(*activeq[:-ntargets]) cirq_gate = [(cirq.MatrixGate(matrix).controlled(len(activeq) - ntargets), activeq)] assert_gates_equivalent(qibo_gate, cirq_gate, nqubits, ndevices) qibo.set_backend(original_backend)
def test_matrixgate_unitary_tolerance(): ## non-unitary matrix with pytest.raises(ValueError): _ = cirq.MatrixGate(np.array([[1, 0], [0, -0.6]]), unitary_check_atol=0.5) # very high atol -> check converges quickly _ = cirq.MatrixGate(np.array([[1, 0], [0, 1]]), unitary_check_atol=1) # very high rtol -> check converges quickly _ = cirq.MatrixGate(np.array([[1, 0], [0, -0.6]]), unitary_check_rtol=1) ## unitary matrix _ = cirq.MatrixGate(np.array([[0.707, 0.707], [-0.707, 0.707]]), unitary_check_atol=0.5) # very low atol -> the check never converges with pytest.raises(ValueError): _ = cirq.MatrixGate(np.array([[0.707, 0.707], [-0.707, 0.707]]), unitary_check_atol=1e-10) # very low atol -> the check never converges with pytest.raises(ValueError): _ = cirq.MatrixGate(np.array([[0.707, 0.707], [-0.707, 0.707]]), unitary_check_rtol=1e-10)
def test_convert_to_sycamore_tabulation(): # A tabulation for the sycamore gate with an infidelity of .1. sycamore_tabulation = cirq.two_qubit_gate_product_tabulation( cirq.unitary(cirq_google.SYC), 0.1, random_state=cirq.value.parse_random_state(11) ) circuit = cirq.Circuit(cirq.MatrixGate(cirq.unitary(cirq.CX)).on(*cirq.LineQubit.range(2))) converted_circuit = cirq.optimize_for_target_gateset( circuit, gateset=cirq_google.SycamoreTargetGateset(tabulation=sycamore_tabulation) ) u1 = cirq.unitary(circuit) u2 = cirq.unitary(converted_circuit) overlap = abs(np.trace(u1.conj().T @ u2)) assert np.isclose(overlap, 4.0, 0.1)
def test_QulacsSimulator_SingleQubitMatrixGate(self): qubits = [cirq.LineQubit(i) for i in range(self.qubit_n)] circuit = cirq.Circuit() for _ in range(self.test_repeat): for index in range(self.qubit_n): angle = np.random.rand(3) * np.pi * 2 circuit.append( cirq.circuits.qasm_output.QasmUGate( angle[0], angle[1], angle[2]).on(qubits[index])) index = np.random.randint(self.qubit_n) mat = unitary_group.rvs(2) circuit.append(cirq.MatrixGate(mat).on(qubits[index])) self.check_result(circuit)
def test_phase_by(): # Single qubit case. x = cirq.MatrixGate(cirq.unitary(cirq.X)) y = cirq.phase_by(x, 0.25, 0) cirq.testing.assert_allclose_up_to_global_phase( cirq.unitary(y), cirq.unitary(cirq.Y), atol=1e-8 ) # Two qubit case. Commutes with control. cx = cirq.MatrixGate(cirq.unitary(cirq.X.controlled(1))) cx2 = cirq.phase_by(cx, 0.25, 0) cirq.testing.assert_allclose_up_to_global_phase(cirq.unitary(cx2), cirq.unitary(cx), atol=1e-8) # Two qubit case. Doesn't commute with target. cy = cirq.phase_by(cx, 0.25, 1) cirq.testing.assert_allclose_up_to_global_phase( cirq.unitary(cy), cirq.unitary(cirq.Y.controlled(1)), atol=1e-8 ) m = cirq.MatrixGate(np.eye(3), qid_shape=[3]) with pytest.raises(TypeError, match='returned NotImplemented'): _ = cirq.phase_by(m, 0.25, 0)
def test_single_qubit_gate(): q = cirq.LineQubit(0) mat = cirq.testing.random_unitary(2) gate = cirq.MatrixGate(mat, qid_shape=(2,)) circuit = cirq.Circuit(gate(q)) converted_circuit = circuit.copy() with cirq.testing.assert_deprecated("Use cirq.optimize_for_target_gateset", deadline='v1.0'): cgoc.ConvertToSycamoreGates().optimize_circuit(converted_circuit) ops = list(converted_circuit.all_operations()) assert len(ops) == 1 assert isinstance(ops[0].gate, cirq.PhasedXZGate) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, converted_circuit, atol=1e-8 )
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_trace_distance_bound(): class NoMethod: pass class ReturnsNotImplemented: def _trace_distance_bound_(self): return NotImplemented class ReturnsTwo: def _trace_distance_bound_(self) -> float: return 2.0 class ReturnsConstant: def __init__(self, bound): self.bound = bound def _trace_distance_bound_(self) -> float: return self.bound x = cirq.MatrixGate(cirq.unitary(cirq.X)) cx = cirq.MatrixGate(cirq.unitary(cirq.CX)) cxh = cirq.MatrixGate(cirq.unitary(cirq.CX**0.5)) assert np.isclose(cirq.trace_distance_bound(x), cirq.trace_distance_bound(cirq.X)) assert np.isclose(cirq.trace_distance_bound(cx), cirq.trace_distance_bound(cirq.CX)) assert np.isclose(cirq.trace_distance_bound(cxh), cirq.trace_distance_bound(cirq.CX**0.5)) assert cirq.trace_distance_bound(NoMethod()) == 1.0 assert cirq.trace_distance_bound(ReturnsNotImplemented()) == 1.0 assert cirq.trace_distance_bound(ReturnsTwo()) == 1.0 assert cirq.trace_distance_bound(ReturnsConstant(0.1)) == 0.1 assert cirq.trace_distance_bound(ReturnsConstant(0.5)) == 0.5 assert cirq.trace_distance_bound(ReturnsConstant(1.0)) == 1.0 assert cirq.trace_distance_bound(ReturnsConstant(2.0)) == 1.0
def test_svg(): a, b, c = cirq.LineQubit.range(3) svg_text = circuit_to_svg( cirq.Circuit( cirq.CNOT(a, b), cirq.CZ(b, c), cirq.SWAP(a, c), cirq.PhasedXPowGate(exponent=0.123, phase_exponent=0.456).on(c), cirq.Z(a), cirq.measure(a, b, c, key='z'), cirq.MatrixGate(np.eye(2)).on(a), )) assert '<svg' in svg_text assert '</svg>' in svg_text
def Ux(x,N): k=1 while(N>2**k): k=k+1 u = np.zeros([2**k, 2**k], dtype = int) for i in range(N): u[x*i%N][i]=1 for i in range(N,2**k): u[i][i]=1 XU = cirq.MatrixGate(u).controlled() return XU
def test_tabulation(): q0, q1 = cirq.LineQubit.range(2) u = cirq.testing.random_special_unitary(4, random_state=np.random.RandomState(52)) circuit = cirq.Circuit(cirq.MatrixGate(u).on(q0, q1)) np.testing.assert_allclose(u, cirq.unitary(circuit)) circuit2 = cg.optimized_for_sycamore(circuit, optimizer_type='sycamore') cirq.testing.assert_allclose_up_to_global_phase(u, cirq.unitary(circuit2), atol=1e-5) assert len(circuit2) == 13 # Note this is run on every commit, so it needs to be relatively quick. # This requires us to use relatively loose tolerances circuit3 = cg.optimized_for_sycamore( circuit, optimizer_type='sycamore', tabulation_resolution=0.1 ) cirq.testing.assert_allclose_up_to_global_phase(u, cirq.unitary(circuit3), rtol=1e-1, atol=1e-1) assert len(circuit3) == 7
def generate_model_circuit( num_qubits: int, depth: int, *, random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None) -> cirq.Circuit: """Generates a model circuit with the given number of qubits and depth. The generated circuit consists of `depth` layers of random qubit permutations followed by random two-qubit gates that are sampled from the Haar measure on SU(4). Args: num_qubits: The number of qubits in the generated circuit. depth: The number of layers in the circuit. random_state: Random state or random state seed. Returns: The generated circuit. """ # Setup the circuit and its qubits. qubits = cirq.LineQubit.range(num_qubits) circuit = cirq.Circuit() random_state = cirq.value.parse_random_state(random_state) # For each layer. for _ in range(depth): # Generate uniformly random permutation Pj of [0...n-1] perm = random_state.permutation(num_qubits) # For each consecutive pair in Pj, generate Haar random SU(4) # Decompose each SU(4) into CNOT + SU(2) and add to Ci for k in range(0, num_qubits - 1, 2): permuted_indices = [int(perm[k]), int(perm[k + 1])] special_unitary = cirq.testing.random_special_unitary( 4, random_state=random_state) # Convert the decomposed unitary to Cirq operations and add them to # the circuit. circuit.append( cirq.MatrixGate(special_unitary).on( qubits[permuted_indices[0]], qubits[permuted_indices[1]])) # Don't measure all of the qubits at the end of the circuit because we will # need to classically simulate it to compute its heavy set. return circuit
def optimization_at( self, circuit: cirq.Circuit, index: int, op: cirq.Operation) -> Optional[cirq.PointOptimizationSummary]: if len(op.qubits) != self.n_qubits: return None frontier = {q: index for q in op.qubits} op_list = circuit.findall_operations_until_blocked( frontier, is_blocker=lambda next_op: next_op.qubits != op.qubits) if len(op_list) <= 1: return None operations = [op for idx, op in op_list] indices = [idx for idx, op in op_list] matrix = cirq.linalg.dot(*(cirq.unitary(op) for op in operations[::-1])) return cirq.PointOptimizationSummary( clear_span=max(indices) + 1 - index, clear_qubits=op.qubits, new_operations=[cirq.MatrixGate(matrix).on(*op.qubits)])
def test_one_q_matrix_gate(): u = cirq.testing.random_special_unitary(2) q = cirq.LineQubit(0) circuit0 = cirq.Circuit(cirq.MatrixGate(u).on(q)) assert len(circuit0) == 1 circuit_iswap = cg.optimized_for_sycamore(circuit0, optimizer_type='sqrt_iswap') assert len(circuit_iswap) == 1 for moment in circuit_iswap: for op in moment: assert cg.SQRT_ISWAP_GATESET.is_supported_operation(op) # single qubit gates shared between gatesets, so: assert cg.SYC_GATESET.is_supported_operation(op) circuit_syc = cg.optimized_for_sycamore(circuit0, optimizer_type='sycamore') assert len(circuit_syc) == 1 for moment in circuit_iswap: for op in moment: assert cg.SYC_GATESET.is_supported_operation(op) # single qubit gates shared between gatesets, so: assert cg.SQRT_ISWAP_GATESET.is_supported_operation(op)