def test_kak_decomposes_unknown_two_qubit_gate(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit.from_ops(cirq.ISWAP(q0, q1)) c_orig = cirq.Circuit(circuit) cirq.ConvertToCzAndSingleGates().optimize_circuit(circuit) assert sum(1 for op in circuit.all_operations() if len(op.qubits) > 1) == 2 assert sum(1 for op in circuit.all_operations() if cirq.op_gate_of_type(op, cirq.CZPowGate)) == 2 assert all(op.gate.exponent == 1 for op in circuit.all_operations() if cirq.op_gate_of_type(op, cirq.CZPowGate)) cirq.testing.assert_allclose_up_to_global_phase( circuit.to_unitary_matrix(), c_orig.to_unitary_matrix(), atol=1e-7)
def test_op_gate_of_type(): a = cirq.NamedQubit('a') op = cirq.X(a) assert cirq.op_gate_of_type(op, cirq.XPowGate) == op.gate assert cirq.op_gate_of_type(op, cirq.YPowGate) is None class NonGateOperation(cirq.Operation): def qubits(self): pass def with_qubits(self, *new_qubits): pass assert cirq.op_gate_of_type(NonGateOperation(), cirq.XPowGate) is None
def test_dont_allow_partial_czs(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit.from_ops(cirq.CZ(q0, q1)**0.5, ) c_orig = cirq.Circuit(circuit) cirq.ConvertToCzAndSingleGates( ignore_failures=True).optimize_circuit(circuit) assert sum(1 for op in circuit.all_operations() if len(op.qubits) > 1) == 2 assert sum(1 for op in circuit.all_operations() if cirq.op_gate_of_type(op, cirq.CZPowGate)) == 2 assert all(op.gate.exponent % 2 == 1 for op in circuit.all_operations() if cirq.op_gate_of_type(op, cirq.CZPowGate)) cirq.testing.assert_allclose_up_to_global_phase( circuit.to_unitary_matrix(), c_orig.to_unitary_matrix(), atol=1e-7)
def test_compile_single_qubit_gates(): q = cirq.LineQubit(0) c1 = cirq.Circuit() for _ in range(10): c1.append(random.choice([cirq.X, cirq.Y, cirq.Z])(q)**random.random()) c2 = compile_single_qubit_gates(c1) assert c1 != c2 assert len(c2) == 2 assert cirq.op_gate_of_type(c2[0].operations[0], cirq.PhasedXPowGate) assert cirq.op_gate_of_type(c2[1].operations[0], cirq.ZPowGate) u1 = c1.unitary() u2 = c2.unitary() cirq.testing.assert_allclose_up_to_global_phase(u1, u2, atol=1e-8)
def check_if_cz_adjacent(self, cz_op: cirq.Operation, other_op: cirq.Operation): if cirq.op_gate_of_type(other_op, cirq.HPowGate): return False return any( cast(cirq.LineQubit, q).is_adjacent(cast(cirq.LineQubit, p)) for q in cz_op.qubits for p in other_op.qubits)
def _simulate_reset(op, state, indices): reset = cirq.op_gate_of_type(op, cirq.ResetChannel) if reset: meas = state.apply_measurement(indices)[0] if meas != 0: # Reset to 0 unitary = cirq.unitary(qudit.FlipGate(meas+1, 0, meas)) state.apply_unitary(indices, unitary)
def _simulate_measurement(self, op, state, indices, measurements): meas = cirq.op_gate_of_type(op, cirq.MeasurementGate) if meas: invert_mask = meas.full_invert_mask() bits = state.apply_measurement(indices) corrected = [bit ^ (bit < 2 and mask) for bit, mask in zip(bits, invert_mask)] key = cirq.measurement_key(meas) measurements[key].extend(corrected)
def validate_scheduled_operation( self, schedule: cirq.Schedule, scheduled_operation: cirq.ScheduledOperation): op = scheduled_operation.operation self.validate_operation(op) if cirq.op_gate_of_type(op, cirq.CZPowGate): for other in schedule.operations_happening_at_same_time_as( scheduled_operation): if self.check_if_cz_adjacent(op, other.operation): raise ValueError('Adjacent CZ operations: {} vs {}'.format( scheduled_operation, other))
def test_gate_on_operation_besides_gate_operation(): a, b = cirq.LineQubit.range(2) assert cirq.op_gate_of_type( -1j * cirq.X(a) * cirq.Y(b), cirq.DensePauliString) == -1j * cirq.DensePauliString('XY') assert cirq.op_gate_isinstance(-1j * cirq.X(a) * cirq.Y(b), cirq.DensePauliString) assert not cirq.op_gate_isinstance(-1j * cirq.X(a) * cirq.Y(b), cirq.XPowGate)
def test_depol_noise(): noise_model = ccn.DepolarizingNoiseModel(depol_prob=0.005) qubits = cirq.LineQubit.range(2) moment = cirq.Moment([ cirq.X(qubits[0]), cirq.Y(qubits[1]), ]) noisy_mom = noise_model.noisy_moment(moment, system_qubits=qubits) assert len(noisy_mom) == 2 assert noisy_mom[0] == moment for g in noisy_mom[1]: assert cirq.op_gate_of_type(g, cirq.DepolarizingChannel)
def assert_cz_depth_below(operations, threshold, must_be_full): total_cz = 0 for op in operations: assert len(op.qubits) <= 2 if len(op.qubits) == 2: assert cirq.op_gate_of_type(op, cirq.CZPowGate) e = value.canonicalize_half_turns(op.gate.exponent) if must_be_full: assert e == 1 total_cz += abs(e) assert total_cz <= threshold
def measure_with_final_permutation( circuit: cirq.Circuit, qubits: List[cirq.Qid], *, mutate=False) -> Tuple[cirq.Circuit, List[cirq.Qid]]: """Apply a measurement gate at the end of a circuit and classically permute qubit indices. If the circuit contains a permutation gate at its end, the input argument `qubits` will be permuted and returned as the second return value. Args: circuit: The circuit qubits: Which qubits to measure mutate: By default, return a copy of the circuit. Otherwise, mutate in place. Returns: circuit: The output circuit with measurement final_qubits: The input list of qubits permuted according to the final permutation gate. """ if mutate: c2 = circuit else: c2 = circuit.copy() mom_classes, stats = validate_well_structured( c2, allow_terminal_permutations=True) if stats.has_measurement: raise ValueError("Circuit already has measurements") mapping = {} if stats.has_permutation: for op in c2.moments[-1].operations: if cirq.op_gate_of_type(op, QuirkQubitPermutationGate): # do something with it permuted_qs = op.qubits gate = op.gate # type: QuirkQubitPermutationGate for i, q in enumerate(permuted_qs): mapping[q] = permuted_qs[gate.permutation[i]] c2.moments.pop(-1) final_qubits = [mapping.get(q, q) for q in qubits] c2.append(cirq.measure(*qubits, key='z')) return c2, final_qubits
def duration_of(self, operation: cirq.Operation) -> cirq.Duration: if cirq.op_gate_of_type(operation, cirq.HPowGate): return cirq.Duration(nanos=20) if cirq.op_gate_of_type(operation, cirq.CZPowGate): return cirq.Duration(nanos=40) raise ValueError('Unsupported operation: {!r}'.format(operation))
def _simulate_reset(op, state, indices): reset = cirq.op_gate_of_type(op, cirq.ResetChannel) if reset: for i in indices: state[i] = 0