def test_state_tomography(): num_qubits = len(BELL_STATE_PROGRAM.get_qubits()) dimension = 2 ** num_qubits tomo_seq = list(state_tomography_programs(BELL_STATE_PROGRAM)) num_samples = 3000 np.random.seed(SEED) qubits = [qubit for qubit in range(num_qubits)] tomo_preps = basis_state_preps(*qubits) state_prep_hists = [] for i, tomo_prep in enumerate(tomo_preps): readout_result = sample_bad_readout(tomo_prep, num_samples, BAD_2Q_READOUT, cxn) state_prep_hists.append(make_histogram(readout_result, dimension)) assignment_probs = estimate_assignment_probs(state_prep_hists) histograms = np.zeros((len(tomo_seq), dimension)) for i, tomo_prog in enumerate(tomo_seq): readout_result = sample_bad_readout(tomo_prog, num_samples, BAD_2Q_READOUT, cxn) histograms[i] = make_histogram(readout_result, dimension) povm = make_diagonal_povm(POVM_PI_BASIS ** num_qubits, assignment_probs) channel_ops = list(default_channel_ops(num_qubits)) for settings in [DEFAULT_STATE_TOMO_SETTINGS, DEFAULT_STATE_TOMO_SETTINGS._replace(constraints={UNIT_TRACE, POSITIVE, TRACE_PRESERVING})]: state_tomo = StateTomography.estimate_from_ssr(histograms, povm, channel_ops, settings) amplitudes = np.array([1, 0, 0, 1]) / np.sqrt(2.) state = qt.Qobj(amplitudes, dims=[[2, 2], [1, 1]]) rho_ideal = state * state.dag() assert abs(1 - state_tomo.fidelity(rho_ideal)) < EPS with patch("grove.tomography.utils.state_histogram"), patch( "grove.tomography.state_tomography.plt"): state_tomo.plot()
def test_sample_bad_readout(): np.random.seed(234) assignment_probs = .3 * np.random.rand(4, 4) + np.eye(4) assignment_probs /= assignment_probs.sum(axis=0)[np.newaxis, :] cxn = Mock() cxn.wavefunction.return_value.amplitudes = 0.5j * np.ones(4) with patch("grove.tomography.utils.sample_outcomes") as so: ut.sample_bad_readout(Program(X(0), X(1), X(0), X(1)), 10000, assignment_probs, cxn) assert np.allclose(so.call_args[0][0], 0.25 * assignment_probs.sum(axis=1))
def test_process_tomography(): num_qubits = len(CNOT_PROGRAM.get_qubits()) dimension = 2 ** num_qubits tomo_seq = list(process_tomography_programs(CNOT_PROGRAM)) nsamples = 3000 np.random.seed(SEED) # We need more samples on the readout to ensure convergence. state_prep_hists = [make_histogram(sample_bad_readout(p, 2 * nsamples, BAD_2Q_READOUT, cxn), dimension) for p in basis_state_preps(*range(num_qubits))] assignment_probs = estimate_assignment_probs(state_prep_hists) histograms = np.zeros((len(tomo_seq), dimension)) for jj, p in enumerate(tomo_seq): histograms[jj] = make_histogram(sample_bad_readout(p, nsamples, BAD_2Q_READOUT, cxn), dimension) channel_ops = list(default_channel_ops(num_qubits)) histograms = histograms.reshape((len(channel_ops), len(channel_ops), dimension)) povm = make_diagonal_povm(POVM_PI_BASIS ** num_qubits, assignment_probs) cnot_ideal = qt.cnot() for settings in [ DEFAULT_PROCESS_TOMO_SETTINGS, DEFAULT_PROCESS_TOMO_SETTINGS._replace(constraints={TRACE_PRESERVING}), DEFAULT_PROCESS_TOMO_SETTINGS._replace(constraints={TRACE_PRESERVING, COMPLETELY_POSITIVE}), ]: process_tomo = ProcessTomography.estimate_from_ssr(histograms, povm, channel_ops, channel_ops, settings) assert abs(1 - process_tomo.avg_gate_fidelity(cnot_ideal)) < EPS transfer_matrix = process_tomo.pauli_basis.transfer_matrix(qt.to_super(cnot_ideal)) assert abs(1 - process_tomo.avg_gate_fidelity(transfer_matrix)) < EPS chi_rep = process_tomo.to_chi().data.toarray() # When comparing to the identity, the chi representation is quadratically larger than the # Hilbert space representation, so we take a square root. probabilty_scale = np.sqrt(chi_rep.shape[0]) super_op_from_chi = np.zeros(process_tomo.pauli_basis.ops[0].shape, dtype=np.complex128) for i, si in enumerate(process_tomo.pauli_basis.ops): for j, sj in enumerate(process_tomo.pauli_basis.ops): contribution = chi_rep[i][j] * si.data.toarray().conj().T.dot(sj.data.toarray()) super_op_from_chi += contribution / probabilty_scale assert np.isclose(np.eye(process_tomo.pauli_basis.ops[0].shape[0]), super_op_from_chi, atol=EPS).all() choi_rep = process_tomo.to_choi() # Choi matrix should be a valid density matrix, scaled by the dimension of the system. assert np.isclose(np.trace(choi_rep.data.toarray()) / probabilty_scale, 1, atol=EPS) super_op = process_tomo.to_super() # The map should be trace preserving. assert np.isclose(np.sum(super_op[0]), 1, atol=EPS) assert abs(1 - process_tomo.avg_gate_fidelity(qt.to_super(cnot_ideal))) < EPS with patch("grove.tomography.utils.plot_pauli_transfer_matrix"), \ patch("grove.tomography.process_tomography.plt") as mplt: mplt.subplots.return_value = Mock(), Mock() process_tomo.plot()