def test_depolarizing_representation_with_choi(gate: Gate, noise: float): """Tests the representation by comparing exact Choi matrices.""" qreg = LineQubit.range(gate.num_qubits()) ideal_choi = _operation_to_choi(gate.on(*qreg)) op_rep = represent_operation_with_global_depolarizing_noise( Circuit(gate.on(*qreg)), noise, ) choi_components = [] for noisy_op, coeff in op_rep.basis_expansion.items(): implementable_circ = noisy_op.circuit() # Apply noise after each sequence. # NOTE: noise is not applied after each operation. depolarizing_op = DepolarizingChannel(noise, len(qreg))(*qreg) implementable_circ.append(depolarizing_op) sequence_choi = _circuit_to_choi(implementable_circ) choi_components.append(coeff * sequence_choi) combination_choi = np.sum(choi_components, axis=0) assert np.allclose(ideal_choi, combination_choi, atol=10**-6)
def test_sample_circuit_choi(): """Tests the sample_circuit by comparing the exact Choi matrices.""" # A simple 2-qubit circuit qreg = cirq.LineQubit.range(2) ideal_circ = cirq.Circuit( cirq.X.on(qreg[0]), cirq.I.on(qreg[1]), cirq.CNOT.on(*qreg), ) noisy_circuit = ideal_circ.with_noise(cirq.depolarize(BASE_NOISE)) ideal_choi = _circuit_to_choi(ideal_circ) noisy_choi = _operation_to_choi(noisy_circuit) rep_list = represent_operations_in_circuit_with_local_depolarizing_noise( ideal_circuit=ideal_circ, noise_level=BASE_NOISE, ) choi_unbiased_estimates = [] rng = np.random.RandomState(1) for _ in range(500): imp_circs, signs, norm = sample_circuit(ideal_circ, rep_list, random_state=rng) noisy_imp_circ = imp_circs[0].with_noise(cirq.depolarize(BASE_NOISE)) sequence_choi = _circuit_to_choi(noisy_imp_circ) choi_unbiased_estimates.append(norm * signs[0] * sequence_choi) choi_pec_estimate = np.average(choi_unbiased_estimates, axis=0) noise_error = np.linalg.norm(ideal_choi - noisy_choi) pec_error = np.linalg.norm(ideal_choi - choi_pec_estimate) assert pec_error < noise_error assert np.allclose(ideal_choi, choi_pec_estimate, atol=0.05)