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()
Пример #2
0
def test_estimate_assignment_probs():
    np.random.seed(2345)
    outcomes = np.random.randint(0, 1000, size=(4, 4))
    aprobs = ut.estimate_assignment_probs(outcomes)
    assert np.allclose(aprobs.T * outcomes.sum(axis=1)[:, np.newaxis],
                       outcomes)
Пример #3
0
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()