def test_channel_process_fidelity(self): """Test the process_fidelity function for channel inputs""" depol = Choi(np.eye(4) / 2) iden = Choi(Operator.from_label('I')) # Completely depolarizing channel f_pro = process_fidelity(depol, require_cp=True, require_tp=True) self.assertAlmostEqual(f_pro, 0.25, places=7) # Identity f_pro = process_fidelity(iden, require_cp=True, require_tp=True) self.assertAlmostEqual(f_pro, 1.0, places=7) # Depolarizing channel prob = 0.3 chan = prob * depol + (1 - prob) * iden f_pro = process_fidelity(chan, require_cp=True, require_tp=True) f_target = prob * 0.25 + (1 - prob) self.assertAlmostEqual(f_pro, f_target, places=7) # Depolarizing channel prob = 0.5 op = Operator.from_label('Y') chan = (prob * depol + (1 - prob) * iden) @ op f_pro = process_fidelity(chan, op, require_cp=True, require_tp=True) target = prob * 0.25 + (1 - prob) self.assertAlmostEqual(f_pro, target, places=7)
def test_operator_process_fidelity(self): """Test the process_fidelity function for operator inputs""" # Orthogonal operator op = Operator.from_label('X') f_pro = process_fidelity(op, require_cp=True, require_tp=True) self.assertAlmostEqual(f_pro, 0.0, places=7) # Global phase operator op1 = Operator.from_label('X') op2 = -1j * op1 f_pro = process_fidelity(op1, op2, require_cp=True, require_tp=True) self.assertAlmostEqual(f_pro, 1.0, places=7)
def test_approx_random_unitary_channel_2q(self): noise = Kraus(random_unitary(4, seed=123)) for opstr in ['pauli']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertEqual(new_result, old_result) for opstr in ['reset']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertGreaterEqual(process_fidelity(noise, new_result), process_fidelity(noise, old_result))
def test_process_fidelity(self): Unitary1 = Pauli(label='XI').to_matrix() Unitary2 = np.kron(np.array([[0, 1], [1, 0]]), np.eye(2)) process_fidelity(Unitary1, Unitary2) self.assertAlmostEqual(process_fidelity(Unitary1, Unitary2), 1.0, places=7) theta = 0.2 Unitary1 = expm(-1j * theta * Pauli(label='X').to_matrix() / 2) Unitary2 = np.array([[np.cos(theta / 2), -1j * np.sin(theta / 2)], [-1j * np.sin(theta / 2), np.cos(theta / 2)]]) self.assertAlmostEqual(process_fidelity(Unitary1, Unitary2), 1.0, places=7)
def test_full_qpt(self, num_qubits, fitter): """Test QPT experiment""" backend = AerSimulator(seed_simulator=9000) seed = 1234 f_threshold = 0.94 target = qi.random_unitary(2**num_qubits, seed=seed) qstexp = ProcessTomography(target) if fitter: qstexp.analysis.set_options(fitter=fitter) expdata = qstexp.run(backend) results = expdata.analysis_results() # Check state is density matrix state = filter_results(results, "state").value self.assertTrue(isinstance(state, qi.Choi), msg="fitted state is not a Choi matrix") # Check fit state fidelity fid = filter_results(results, "process_fidelity").value self.assertGreater(fid, f_threshold, msg="fit fidelity is low") # Manually check fidelity target_fid = qi.process_fidelity(state, target, require_tp=False, require_cp=False) self.assertAlmostEqual(fid, target_fid, places=6, msg="result fidelity is incorrect")
def test_nontp_process_fidelity(self): """Test process_fidelity for non-TP channel""" chan = 0.99 * Choi(Operator.from_label('X')) fid = process_fidelity(chan) self.assertLogs('qiskit.quantum_info.operators.measures', level='WARNING') self.assertAlmostEqual(fid, 0, places=15)
def local_fidelity_optimization(channel: Choi, target_op: Operator) -> np.ndarray: """ Find local operation parameters to improve fidelity. Args: channel: Estimated quantum channel of target operation. target_op: Ideal target operator. Returns: Local operation parameters. """ def local_rotations_inv(theta1, phi1, lam1, theta2, phi2, lam2): return Operator(U3Gate(-theta1, -lam1, -phi1)).\ expand(Operator(U3Gate(-theta2, -lam2, -phi2))) def fidelity_objective(params): local_l = local_rotations_inv(*params[:6]) local_r = local_rotations_inv(*params[6:]) opt_oper = local_l.compose(target_op).compose(local_r) return 1 - qi.process_fidelity(channel, opt_oper) def to_favg(val): return (4 * val + 1) / 5 raw_fid = qi.process_fidelity(channel, target_op) print('Original F_avg: %.5f' % to_favg(raw_fid)) res = opt.dual_annealing(fidelity_objective, [(-np.pi, np.pi) for _ in range(12)]) print('Optimized F_avg: %.5f' % to_favg(1 - res.fun)) return res.x
def test_circuit_multi(self): """Test circuit multi regs declared at start.""" qreg0 = QuantumRegister(2, 'q0') creg0 = ClassicalRegister(2, 'c0') qreg1 = QuantumRegister(2, 'q1') creg1 = ClassicalRegister(2, 'c1') circ = QuantumCircuit(qreg0, qreg1) circ.x(qreg0[1]) circ.x(qreg1[0]) meas = QuantumCircuit(qreg0, qreg1, creg0, creg1) meas.measure(qreg0, creg0) meas.measure(qreg1, creg1) qc = circ + meas backend_sim = BasicAer.get_backend('qasm_simulator') result = execute(qc, backend_sim, seed_mapper=34342).result() counts = result.get_counts(qc) target = {'01 10': 1024} backend_sim = BasicAer.get_backend('statevector_simulator') result = execute(circ, backend_sim, seed_mapper=3438).result() state = result.get_statevector(circ) backend_sim = BasicAer.get_backend('unitary_simulator') result = execute(circ, backend_sim, seed_mapper=3438).result() unitary = result.get_unitary(circ) self.assertEqual(counts, target) self.assertAlmostEqual(state_fidelity(basis_state('0110', 4), state), 1.0, places=7) self.assertAlmostEqual(process_fidelity(Pauli(label='IXXI').to_matrix(), unitary), 1.0, places=7)
def test_qpt_teleport(self): """Test subset state tomography generation""" # NOTE: This test breaks transpiler. I think it is a bug with # conditionals in Terra. # Teleport qubit 0 -> 2 backend = AerSimulator(seed_simulator=9000) exp = ProcessTomography(teleport_circuit(), measurement_qubits=[2], preparation_qubits=[0]) expdata = exp.run(backend, shots=10000) results = expdata.analysis_results() # Check result f_threshold = 0.95 # Check state is density matrix state = filter_results(results, "state").value self.assertTrue(isinstance(state, qi.Choi), msg="fitted state is not a Choi matrix") # Manually check fidelity fid = qi.process_fidelity(state, require_tp=False, require_cp=False) self.assertGreater(fid, f_threshold, msg="fitted state fidelity is low")
def test_noncp_process_fidelity(self): """Test process_fidelity for non-CP channel""" u1 = Operator.from_label('X') u2 = Operator.from_label('Z') chan = 1.01 * Choi(u1) - 0.01 * Choi(u2) fid = process_fidelity(chan) self.assertLogs('qiskit.quantum_info.operators.measures', level='WARNING') self.assertAlmostEqual(fid, 0, places=15)
def test_approx_random_mixed_unitary_channel_2q(self): noise1 = UnitaryGate(random_unitary(4, seed=123)) noise2 = UnitaryGate(random_unitary(4, seed=456)) noise = QuantumError([(noise1, 0.7), (noise2, 0.3)]) for opstr in ['pauli']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertEqual(new_result, old_result) for opstr in ['reset']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertGreaterEqual(process_fidelity(noise, new_result), process_fidelity(noise, old_result))
def test_mixed_batch_exp(self): """Test batch state and process tomography experiment""" # Subsystem unitaries state_op = qi.random_unitary(2, seed=321) chan_op = qi.random_unitary(2, seed=123) state_target = qi.Statevector(state_op.to_instruction()) chan_target = qi.Choi(chan_op.to_instruction()) state_exp = StateTomography(state_op) chan_exp = ProcessTomography(chan_op) batch_exp = BatchExperiment([state_exp, chan_exp]) # Run batch experiments backend = AerSimulator(seed_simulator=9000) par_data = batch_exp.run(backend) self.assertExperimentDone(par_data) f_threshold = 0.95 # Check state tomo results state_results = par_data.child_data(0).analysis_results() state = filter_results(state_results, "state").value # Check fit state fidelity state_fid = filter_results(state_results, "state_fidelity").value self.assertGreater(state_fid, f_threshold, msg="fit fidelity is low") # Manually check fidelity target_fid = qi.state_fidelity(state, state_target, validate=False) self.assertAlmostEqual(state_fid, target_fid, places=6, msg="result fidelity is incorrect") # Check process tomo results chan_results = par_data.child_data(1).analysis_results() chan = filter_results(chan_results, "state").value # Check fit process fidelity chan_fid = filter_results(chan_results, "process_fidelity").value self.assertGreater(chan_fid, f_threshold, msg="fit fidelity is low") # Manually check fidelity target_fid = qi.process_fidelity(chan, chan_target, require_cp=False, require_tp=False) self.assertAlmostEqual(chan_fid, target_fid, places=6, msg="result fidelity is incorrect")
def test_batch_exp_with_measurement_qubits(self): """Test batch process tomography experiment with kwargs""" seed = 1111 nq = 3 ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)] # Preparation circuit circuit = QuantumCircuit(nq) for i, op in enumerate(ops): circuit.append(op, [i]) # Component experiments exps = [] targets = [] for i in range(nq): targets.append(ops[i]) exps.append( ProcessTomography(circuit, measurement_qubits=[i], preparation_qubits=[i])) # Run batch experiments backend = AerSimulator(seed_simulator=9000) batch_exp = BatchExperiment(exps) batch_data = batch_exp.run(backend) batch_data.block_for_results() # Check target fidelity of component experiments f_threshold = 0.95 for i in range(batch_exp.num_experiments): results = batch_data.component_experiment_data( i).analysis_results() # Check state is density matrix state = filter_results(results, "state").value self.assertTrue(isinstance(state, qi.Choi), msg="fitted state is not a Choi matrix") # Check fit state fidelity fid = filter_results(results, "process_fidelity").value self.assertGreater(fid, f_threshold, msg="fit fidelity is low") # Manually check fidelity target_fid = qi.process_fidelity(state, targets[i], require_tp=False, require_cp=False) self.assertAlmostEqual(fid, target_fid, places=6, msg="result fidelity is incorrect")
def test_full_exp_meas_prep_qubits(self, qubits): """Test subset state tomography generation""" # Subsystem unitaries seed = 1111 nq = 3 ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)] # Target state target_circ = QuantumCircuit(len(qubits)) for i, qubit in enumerate(qubits): target_circ.append(ops[qubit], [i]) target = qi.Operator(target_circ) # Preparation circuit circ = QuantumCircuit(nq) for i, op in enumerate(ops): circ.append(op, [i]) # Run backend = AerSimulator(seed_simulator=9000) exp = ProcessTomography(circ, measurement_qubits=qubits, preparation_qubits=qubits) expdata = exp.run(backend) self.assertExperimentDone(expdata) results = expdata.analysis_results() # Check result f_threshold = 0.95 # Check state is density matrix state = filter_results(results, "state").value self.assertTrue(isinstance(state, qi.Choi), msg="fitted state is not a Choi matrix") # Check fit state fidelity fid = filter_results(results, "process_fidelity").value self.assertGreater(fid, f_threshold, msg="fit fidelity is low") # Manually check fidelity target_fid = qi.process_fidelity(state, target, require_tp=False, require_cp=False) self.assertAlmostEqual(fid, target_fid, places=6, msg="result fidelity is incorrect")
def test_circuit_multi_case2(self): """Test circuit multi regs declared at start. """ qreg0 = QuantumRegister(2, 'q0') creg0 = ClassicalRegister(2, 'c0') qreg1 = QuantumRegister(2, 'q1') creg1 = ClassicalRegister(2, 'c1') circ2 = QuantumCircuit() circ2.add_register(qreg0) circ2.add_register(qreg1) circ2.x(qreg0[1]) circ2.x(qreg1[0]) meas2 = QuantumCircuit() meas2.add_register(qreg0) meas2.add_register(qreg1) meas2.add_register(creg0) meas2.add_register(creg1) meas2.measure(qreg0, creg0) meas2.measure(qreg1, creg1) qc2 = circ2 + meas2 backend_sim = Simulators.get_backend('statevector_simulator') result = execute(circ2, backend_sim).result() state = result.get_statevector(circ2) backend_sim = Simulators.get_backend('qasm_simulator') result = execute(qc2, backend_sim).result() counts = result.get_counts(qc2) backend_sim = Simulators.get_backend('unitary_simulator') result = execute(circ2, backend_sim).result() unitary = result.get_unitary(circ2) target = {'01 10': 1024} self.assertEqual(target, counts) self.assertAlmostEqual(state_fidelity(basis_state('0110', 4), state), 1.0, places=7) self.assertAlmostEqual(process_fidelity( Pauli(label='IXXI').to_matrix(), unitary), 1.0, places=7)
def test_parallel_exp(self): """Test parallel process tomography experiment""" # Subsystem unitaries seed = 1221 nq = 4 ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)] # Component experiments exps = [] targets = [] for i in range(nq): exps.append(ProcessTomography(ops[i], qubits=[i])) targets.append(ops[i]) # Run batch experiments backend = AerSimulator(seed_simulator=9000) par_exp = ParallelExperiment(exps) par_data = par_exp.run(backend) self.assertExperimentDone(par_data) # Check target fidelity of component experiments f_threshold = 0.95 for i in range(par_exp.num_experiments): results = par_data.child_data(i).analysis_results() # Check state is density matrix state = filter_results(results, "state").value self.assertTrue(isinstance(state, qi.Choi), msg="fitted state is not a Choi matrix") # Check fit state fidelity fid = filter_results(results, "process_fidelity").value self.assertGreater(fid, f_threshold, msg="fit fidelity is low") # Manually check fidelity target_fid = qi.process_fidelity(state, targets[i], require_tp=False, require_cp=False) self.assertAlmostEqual(fid, target_fid, places=6, msg="result fidelity is incorrect")
def test_circuit_multi(self): """Test circuit multi regs declared at start.""" qreg0 = QuantumRegister(2, "q0") creg0 = ClassicalRegister(2, "c0") qreg1 = QuantumRegister(2, "q1") creg1 = ClassicalRegister(2, "c1") circ = QuantumCircuit(qreg0, qreg1, creg0, creg1) circ.x(qreg0[1]) circ.x(qreg1[0]) meas = QuantumCircuit(qreg0, qreg1, creg0, creg1) meas.measure(qreg0, creg0) meas.measure(qreg1, creg1) qc = circ.compose(meas) backend_sim = BasicAer.get_backend("qasm_simulator") result = execute(qc, backend_sim, seed_transpiler=34342).result() counts = result.get_counts(qc) target = {"01 10": 1024} backend_sim = BasicAer.get_backend("statevector_simulator") result = execute(circ, backend_sim, seed_transpiler=3438).result() state = result.get_statevector(circ) backend_sim = BasicAer.get_backend("unitary_simulator") result = execute(circ, backend_sim, seed_transpiler=3438).result() unitary = Operator(result.get_unitary(circ)) self.assertEqual(counts, target) self.assertAlmostEqual(state_fidelity(Statevector.from_label("0110"), state), 1.0, places=7) self.assertAlmostEqual(process_fidelity(Operator.from_label("IXXI"), unitary), 1.0, places=7)
def test_unitary(self): """Test unitary gate instruction""" num_trials = 10 max_qubits = 3 # Test 1 to max_qubits for random n-qubit unitary gate for i in range(max_qubits): num_qubits = i + 1 unitary_init = Operator(np.eye(2 ** num_qubits)) qr = QuantumRegister(num_qubits, "qr") for _ in range(num_trials): # Create random unitary unitary = random_unitary(2 ** num_qubits) # Compute expected output state unitary_target = unitary.dot(unitary_init) # Simulate output on circuit circuit = QuantumCircuit(qr) circuit.unitary(unitary, qr) job = execute(circuit, self.backend) result = job.result() unitary_out = Operator(result.get_unitary(0)) fidelity = process_fidelity(unitary_target, unitary_out) self.assertGreater(fidelity, 0.999)
def test_exp_measurement_preparation_qubits(self, qubits): """Test subset measurement process tomography generation""" # Subsystem unitaries seed = 1111 nq = 3 ops = [qi.random_unitary(2, seed=seed + i) for i in range(nq)] # Preparation circuit circ = QuantumCircuit(nq) for i, op in enumerate(ops): circ.append(op, [i]) num_meas = len(qubits) exp = ProcessTomography(circ, measurement_qubits=qubits, preparation_qubits=qubits) tomo_circuits = exp.circuits() # Check correct number of circuits are generated size = 3**num_meas * 4**num_meas self.assertEqual(len(tomo_circuits), size) # Check circuit metadata is correct for circ in tomo_circuits: meta = circ.metadata clbits = meta.get("clbits") self.assertEqual(clbits, list(range(num_meas)), msg="metadata clbits is incorrect") # Check experiment target metadata is correct exp_meta = exp._metadata() target_state = exp_meta.get("target") target_circ = QuantumCircuit(num_meas) for i, qubit in enumerate(qubits): target_circ.append(ops[qubit], [i]) fid = qi.process_fidelity(target_state, qi.Operator(target_circ)) self.assertGreater(fid, 0.99, msg="target_state is incorrect")
def get_fidelity_with_qiskit(dag_cir, noisy_position): cir = dag_2_circuit(dag_cir) U = Operator(cir) channel = get_error_channel(dag_cir, noisy_position, 0.001) fide = process_fidelity(channel, U) return fide
def fidelity_objective(params): local_l = local_rotations_inv(*params[:6]) local_r = local_rotations_inv(*params[6:]) opt_oper = local_l.compose(target_op).compose(local_r) return 1 - qi.process_fidelity(channel, opt_oper)