예제 #1
0
def measurement_func(request, test_qc):
    if request.param == 'wfn':
        return lambda expt: list(wfn_estimate_observables(n_qubits=2, tomo_expt=expt))
    elif request.param == 'sampling':
        return lambda expt: list(estimate_observables(qc=test_qc, obs_expt=expt, num_shots=500))
    else:
        raise ValueError()
def acquire_rb_data(qc: QuantumComputer, experiments: Iterable[ObservablesExperiment],
                    num_shots: int = 500, active_reset: bool = False,
                    show_progress_bar: bool = False) \
        -> List[List[ExperimentResult]]:
    """
    Runs each ObservablesExperiment and returns each group of resulting ExperimentResults

    :param qc: a quantum computer, e.g. QVM or QPU, that runs the experiments
    :param experiments: a list of Observables experiments
    :param num_shots: the number of shots to run each group of simultaneous ExperimentSettings
    :param active_reset: Boolean flag indicating whether experiments should begin with an
        active reset instruction (this can make the collection of experiments run a lot faster).
    :param show_progress_bar: displays a progress bar via tqdm if true.
    :return: a list of ExperimentResults for each ObservablesExperiment
    """
    results = []
    for expt in tqdm(experiments, disable=not show_progress_bar):
        results.append(list(estimate_observables(qc, expt, num_shots, active_reset=active_reset)))
    return results
def single_q_tomo_fixture(test_qc):
    qubits = [0]

    # Generate random unitary
    u_rand = haar_rand_unitary(2 ** 1, rs=np.random.RandomState(52))
    state_prep = Program().defgate("RandUnitary", u_rand)
    state_prep.inst([("RandUnitary", qubits[0])])

    # True state
    wfn = NumpyWavefunctionSimulator(n_qubits=1)
    psi = wfn.do_gate_matrix(u_rand, qubits=[0]).wf.reshape(-1)
    rho_true = np.outer(psi, psi.T.conj())

    # Get data from QVM
    tomo_expt = generate_state_tomography_experiment(state_prep, qubits)
    results = list(estimate_observables(qc=test_qc, obs_expt=tomo_expt, num_shots=1000,
                                        symm_type=-1))
    results = list(calibrate_observable_estimates(test_qc, results))

    return results, rho_true
예제 #4
0
def test_expectations_at_depth(qvm):
    qvm.qam.random_seed = 5
    q = 0
    qubits = (q, )
    expected_outcomes = [1., 0, -1., 0]
    for depth in [0, 1, 2, 3, 4]:
        prep, meas, settings = rpe.all_eigenvector_prep_meas_settings(
            qubits, I(q))
        depth_many_rot = [RZ(pi / 2, q) for _ in range(depth)]
        program = Program(prep) + sum(depth_many_rot,
                                      Program()) + Program(meas)
        expt = ObservablesExperiment(list(settings), program)

        results = list(estimate_observables(qvm, expt))

        for res in results:
            meas_dir = res.setting.observable[q]
            idx = ((depth - 1) if meas_dir == 'Y' else depth) % 4
            expected = expected_outcomes[idx]
            exp = res.expectation
            assert np.allclose(expected, exp, atol=.05)
예제 #5
0
def acquire_qubit_spectroscopy_data(qc: QuantumComputer,
                                    experiments: Sequence[ObservablesExperiment],
                                    num_shots: int = 500, show_progress_bar: bool = False) \
        -> List[List[ExperimentResult]]:
    """
    A standard data acquisition method for all experiments in this module.

    Each input ObservablesExperiment is simply run in series, and a list of results are returned
    for each experiment in the corresponding order.

    :param qc: a quantum computer on which to run the experiments
    :param experiments: the ObservablesExperiments to run on the given qc
    :param num_shots: the number of shots to collect for each experiment.
    :param show_progress_bar: displays a progress bar via tqdm if true.
    :return: a list of ExperimentResults for each ObservablesExperiment, returned in order of the
        input sequence of experiments.
    """
    results = []
    for expt in tqdm(experiments, disable=not show_progress_bar):
        results.append(list(estimate_observables(qc, expt, num_shots)))
    return results
        * 0 -- no symmetrization
        * 1 -- symmetrization using an OA with strength 1
        * 2 -- symmetrization using an OA with strength 2
        * 3 -- symmetrization using an OA with strength 3

    :param calibrate_observables: boolean flag indicating whether observable estimates are
        calibrated using the same level of symmetrization as exhaustive_symmetrization.
        Likely, for the best (although slowest) results, symmetrization type should accommodate the
        maximum weight of any observable estimated.
    :param show_progress_bar: displays a progress bar via tqdm if true.
    :return: results from running the given DFE experiment. These can be passed to estimate_dfe
    """
    res = list(
        estimate_observables(qc,
                             expt,
                             num_shots=num_shots,
                             symm_type=symm_type,
                             active_reset=active_reset,
                             show_progress_bar=show_progress_bar))
    if calibrate_observables:
        res = list(
            calibrate_observable_estimates(qc,
                                           res,
                                           num_shots=num_shots,
                                           symm_type=symm_type,
                                           active_reset=active_reset))

    return res


def estimate_dfe(results: List[ExperimentResult],
                 kind: str) -> Tuple[float, float]:
예제 #7
0
def acquire_rpe_data(qc: QuantumComputer,
                     experiments: Sequence[ObservablesExperiment],
                     multiplicative_factor: float = 1.0, additive_error: Optional[float] = None,
                     min_shots: int = 500, active_reset: bool = False,
                     mitigate_readout_errors: bool = False, show_progress_bar: bool = False) \
        -> List[List[ExperimentResult]]:
    """
    Run each experiment in the sequence of experiments.

    The number of shots run at each depth can be modified indirectly by adjusting
    multiplicative_factor and additive_error.

    :param experiments:
    :param qc: a quantum computer, e.g. QVM or QPU, that runs the experiments
    :param multiplicative_factor: ad-hoc factor to multiply the number of shots per iteration. See
        num_trials() which computes the optimal number of shots per iteration.
    :param additive_error: estimate of the max additive error in the experiment, see num_trials()
    :param min_shots: the minimum number of shots used to estimate a particular observable;
        in contrast to the theoretical assumption that shot-rate is independent of number of shots,
        in practice the shot-rate is approximately proportional to the number of shots up to about
        500 so taking fewer shots is sub-optimal.
    :param active_reset: Boolean flag indicating whether experiments should begin with an
        active reset instruction (this can make the collection of experiments run a lot faster).
    :param mitigate_readout_errors: Boolean flag indicating whether bias due to imperfect
        readout should be corrected
    :param show_progress_bar: displays a progress bar via tqdm if true.
    :return: a copy of the input experiments populated with results in each layer.
    """
    depths = [2**idx for idx in range(len(experiments))]
    max_depth = max(depths)

    results = []
    for depth, expt in zip(tqdm(depths, disable=not show_progress_bar),
                           experiments):
        theoretical_optimum = num_trials(depth, max_depth,
                                         multiplicative_factor, additive_error)
        num_shots = max(min_shots, theoretical_optimum)

        # TODO: fix up mitigate_readout_errors.
        if mitigate_readout_errors:
            res = list(
                estimate_observables(qc,
                                     expt,
                                     num_shots=num_shots,
                                     active_reset=active_reset,
                                     symm_type=-1))

            results.append(
                list(
                    calibrate_observable_estimates(qc,
                                                   res,
                                                   num_shots=num_shots)))
        else:
            results.append(
                list(
                    estimate_observables(qc,
                                         expt,
                                         num_shots=num_shots,
                                         active_reset=active_reset)))

    return results