Beispiel #1
0
def collect_heavy_outputs(wfn_sim: NumpyWavefunctionSimulator,
                          permutations: np.ndarray,
                          gates: np.ndarray) -> List[int]:
    """
    Collects and returns those 'heavy' bitstrings which are output with greater than median
    probability among all possible bitstrings on the given qubits.

    The method uses the provided wfn_sim to calculate the probability of measuring each bitstring
    from the output of the circuit comprised of the given permutations and gates.

    :param wfn_sim: a NumpyWavefunctionSimulator that can simulate the provided program
    :param permutations: array of depth-many arrays of size n_qubits indicating a qubit permutation
    :param gates: depth by num_gates_per_layer many matrix representations of 2q gates.
            The first row of matrices is the earliest-time layer of 2q gates applied.
    :return: a list of the heavy outputs of the circuit, represented as ints
    """
    wfn_sim.reset()

    for layer_idx, (perm, layer) in enumerate(zip(permutations, gates)):
        for gate_idx, gate in enumerate(layer):
            wfn_sim.do_gate_matrix(gate, (perm[gate_idx], perm[gate_idx + 1]))

    # Note that probabilities are ordered lexicographically with qubit 0 leftmost.
    probabilities = np.abs(wfn_sim.wf.reshape(-1))**2

    median_prob = median(probabilities)

    # store the integer indices, which implicitly represent the bitstring outcome.
    heavy_outputs = [
        idx for idx, prob in enumerate(probabilities) if prob > median_prob
    ]

    return heavy_outputs
def test_exhaustive_state_dfe_run(benchmarker: BenchmarkConnection):
    wfnsim = NumpyWavefunctionSimulator(n_qubits=1)
    process = Program(X(0))
    texpt = generate_exhaustive_state_dfe_experiment(program=process,
                                                     qubits=[0],
                                                     benchmarker=benchmarker)
    for setting in texpt:
        setting = setting[0]
        prog = Program()
        for oneq_state in setting.in_state.states:
            prog += _one_q_state_prep(oneq_state)
        prog += process

        expectation = wfnsim.reset().do_program(prog).expectation(
            setting.out_operator)
        assert expectation == 1.
def wfn_measure_observables(n_qubits, tomo_expt: TomographyExperiment):
    if len(tomo_expt.program.defined_gates) > 0:
        raise pytest.skip("Can't do wfn on defined gates yet")
    wfn = NumpyWavefunctionSimulator(n_qubits)
    for settings in tomo_expt:
        for setting in settings:
            prog = Program()
            for oneq_state in setting.in_state.states:
                prog += _one_q_state_prep(oneq_state)
            prog += tomo_expt.program

            yield ExperimentResult(
                setting=setting,
                expectation=wfn.reset().do_program(prog).expectation(setting.out_operator),
                stddev=0.,
                total_counts=1,  # don't set to zero unless you want nans
            )
def test_monte_carlo_process_dfe(benchmarker: BenchmarkConnection):
    process = Program(CNOT(0, 1))
    texpt = generate_monte_carlo_process_dfe_experiment(
        program=process, qubits=[0, 1], n_terms=10, benchmarker=benchmarker)
    assert len(texpt) == 10

    wfnsim = NumpyWavefunctionSimulator(n_qubits=2)
    for setting in texpt:
        setting = setting[0]
        prog = Program()
        for oneq_state in setting.in_state.states:
            prog += _one_q_state_prep(oneq_state)
        prog += process

        expectation = wfnsim.reset().do_program(prog).expectation(
            setting.out_operator)
        assert_almost_equal(expectation, 1., decimal=7)