예제 #1
0
def test_run_factory():
    rand_circ = random_identity_circuit(depth=TEST_DEPTH)
    qp = measure(rand_circ, qid=0)
    fac = RichardsonFactory([1.0, 2.0, 3.0])
    fac.run(qp, basic_executor, scale_noise)
    result = fac.reduce()
    assert np.isclose(result, 1.0, atol=1.0e-1)
예제 #2
0
def test_run_factory():
    """Tests qrun of a Richardson Factory."""
    qp = random_one_qubit_identity_circuit(num_cliffords=TEST_DEPTH)
    qp = measure(qp, 0)
    fac = RichardsonFactory([1.0, 2.0, 3.0])
    fac.run(qp, basic_executor, scale_noise)
    result = fac.reduce()
    assert np.isclose(result, 1.0, atol=1.0e-1)
예제 #3
0
def test_richardson_extr(test_f: Callable[[float], float]):
    """Test of the Richardson's extrapolator."""
    seeded_f = apply_seed_to_func(test_f, SEED)
    fac = RichardsonFactory(scale_factors=X_VALS)
    assert not fac._opt_params
    fac.run_classical(seeded_f)
    zne_value = fac.reduce()
    assert np.isclose(zne_value, seeded_f(0, err=0), atol=CLOSE_TOL)
    assert len(fac._opt_params) == len(X_VALS)
    assert np.isclose(fac._opt_params[-1], zne_value)
예제 #4
0
def test_fake_nodes_extrapolation():
    """Test that there exists a regime in which FakeNodesFactory
    is better than RichardsonFactory.
    Note: in many cases RichardsonFactory is better.
    """
    y_vals = [f_runge(x) for x in UNIFORM_X]
    zne_runge = FakeNodesFactory.extrapolate(UNIFORM_X, y_vals)
    zne_richard = RichardsonFactory.extrapolate(UNIFORM_X, y_vals)
    abs_err_runge = np.abs(zne_runge - f_runge(0.0))
    abs_err_richard = np.abs(zne_richard - f_runge(0.0))
    # Test Richardson extrapolation error is much larger
    assert 500 * abs_err_runge < abs_err_richard
예제 #5
0
def execute_with_zne(
    qp: QPROGRAM,
    executor: Callable[[QPROGRAM], float],
    factory: Optional[Factory] = None,
    scale_noise: Callable[[QPROGRAM, float], QPROGRAM] = fold_gates_at_random,
    num_to_average: int = 1,
) -> float:
    """Returns the zero-noise extrapolated expectation value that is computed
    by running the quantum program `qp` with the executor function.

    Args:
        qp: Quantum program to execute with error mitigation.
        executor: Executes a circuit and returns an expectation value.
        factory: Factory object that determines the zero-noise extrapolation
            method.
        scale_noise: Function for scaling the noise of a quantum circuit.
        num_to_average: Number of times expectation values are computed by
            the executor after each call to scale_noise, then averaged.
    """
    if not factory:
        factory = RichardsonFactory(scale_factors=[1.0, 2.0, 3.0])

    if not callable(executor):
        raise TypeError("Argument `executor` must be callable.")

    if not isinstance(factory, Factory):
        raise TypeError(
            f"Argument `factory` must be of type mitiq.factories.Factory "
            f"but type(factory) is {type(factory)}.")

    if not callable(scale_noise):
        raise TypeError("Argument `scale_noise` must be callable.")

    if num_to_average < 1:
        raise ValueError("Argument `num_to_average` must be a positive int.")

    factory.run(qp, executor, scale_noise, int(num_to_average))

    # print(factory.get_scale_factors())
    # print(factory.get_expectation_values())

    zero_lim = factory.reduce()

    plt.plot(factory.get_scale_factors(), factory.get_expectation_values(),
             'bo')
    plt.show()

    return zero_lim
예제 #6
0
파일: zne.py 프로젝트: unitaryfund/mitiq
def execute_with_zne(
    circuit: QPROGRAM,
    executor: Union[Executor, Callable[[QPROGRAM], QuantumResult]],
    observable: Optional[Observable] = None,
    *,
    factory: Optional[Factory] = None,
    scale_noise: Callable[[QPROGRAM, float], QPROGRAM] = fold_gates_at_random,
    num_to_average: int = 1,
) -> float:
    """Estimates the error-mitigated expectation value associated to the
    input circuit, via the application of zero-noise extrapolation (ZNE).

    Args:
        circuit: The input circuit to execute with ZNE.
        executor: A Mitiq executor that executes a circuit and returns the
            unmitigated ``QuantumResult`` (e.g. an expectation value).
        observable: Observable to compute the expectation value of. If
            ``None``, the ``executor`` must return an expectation value.
            Otherwise, the ``QuantumResult`` returned by ``executor`` is used
            to compute the expectation of the observable.
        factory: ``Factory`` object that determines the zero-noise
            extrapolation method.
        scale_noise: The function for scaling the noise of a quantum circuit.
            A list of built-in functions can be found in ``mitiq.zne.scaling``.
        num_to_average: Number of times expectation values are computed by
            the executor after each call to ``scale_noise``, then averaged.

    Returns:
        The expectation value estimated with ZNE.
    """
    if not factory:
        factory = RichardsonFactory(scale_factors=[1.0, 2.0, 3.0])

    if not isinstance(factory, Factory):
        raise TypeError(
            f"Argument `factory` must be of type mitiq.factories.Factory "
            f"but type(factory) is {type(factory)}.")

    if not callable(scale_noise):
        raise TypeError("Argument `scale_noise` must be callable.")

    if num_to_average < 1:
        raise ValueError("Argument `num_to_average` must be a positive int.")

    return factory.run(circuit, executor, observable, scale_noise,
                       int(num_to_average)).reduce()
예제 #7
0
def execute_with_zne(
    circuit: QPROGRAM,
    executor: Union[Executor, Callable[[QPROGRAM], QuantumResult]],
    observable: Optional[Observable] = None,
    *,
    factory: Optional[Factory] = None,
    scale_noise: Callable[[QPROGRAM, float], QPROGRAM] = fold_gates_at_random,
    num_to_average: int = 1,
) -> float:
    """Returns the zero-noise extrapolated expectation value that is computed
    by running the quantum program `qp` with the executor function.

    Args:
        circuit: Quantum program to execute with error mitigation.
        executor: A ``mitiq.Executor`` or a function which inputs a (list
            of) quantum circuits and outputs a (list of)
            ``mitiq.QuantumResult`` s.
        observable: Observable to compute the expectation value of. If None,
            the `executor` must return an expectation value. Otherwise,
            the `QuantumResult` returned by `executor` is used to compute the
            expectation of the observable.
        factory: Factory object that determines the zero-noise extrapolation
            method.
        scale_noise: Function for scaling the noise of a quantum circuit.
        num_to_average: Number of times expectation values are computed by
            the executor after each call to scale_noise, then averaged.
    """
    if not factory:
        factory = RichardsonFactory(scale_factors=[1.0, 2.0, 3.0])

    if not isinstance(factory, Factory):
        raise TypeError(
            f"Argument `factory` must be of type mitiq.factories.Factory "
            f"but type(factory) is {type(factory)}."
        )

    if not callable(scale_noise):
        raise TypeError("Argument `scale_noise` must be callable.")

    if num_to_average < 1:
        raise ValueError("Argument `num_to_average` must be a positive int.")

    return factory.run(
        circuit, executor, observable, scale_noise, int(num_to_average)
    ).reduce()
예제 #8
0
def test_execute_with_zne_with_supported_circuits(circuit_type):
    # Define a circuit equivalent to the identity
    qreg = cirq.LineQubit.range(2)
    cirq_circuit = cirq.Circuit(
        cirq.H.on_each(qreg),
        cirq.CNOT(*qreg),
        cirq.CNOT(*qreg),
        cirq.H.on_each(qreg),
    )
    # Convert to one of the supported program types
    circuit = convert_from_mitiq(cirq_circuit, circuit_type)
    expected = generic_executor(circuit, noise_level=0.0)
    unmitigated = generic_executor(circuit)
    # Use odd scale factors for deterministic results
    fac = RichardsonFactory([1.0, 3.0, 5.0])
    zne_value = execute_with_zne(circuit, generic_executor, factory=fac)
    # Test zero noise limit is better than unmitigated expectation value
    assert abs(unmitigated - expected) > abs(zne_value - expected)
예제 #9
0
def test_mitigate_executor_with_shot_list():
    """Tests the mitigation of an executor using different shots
    for each noise scale factor.
    """
    rand_circ = random_one_qubit_identity_circuit(num_cliffords=TEST_DEPTH)
    qp = measure(rand_circ, qid=0)

    fac = RichardsonFactory(
        [1.0, 2.0, 3.0], shot_list=[10 ** 4, 10 ** 5, 10 ** 6]
    )
    new_executor = mitigate_executor(
        basic_executor, scale_noise=scale_noise, factory=fac
    )
    # bad_result is computed with native noise (scale = 1)
    bad_result = basic_executor(scale_noise(qp, 1))
    good_result = new_executor(qp)
    assert not np.isclose(bad_result, 1.0, atol=1.0e-1)
    assert np.isclose(good_result, 1.0, atol=1.0e-1)
    assert fac._instack[0] == {"scale_factor": 1.0, "shots": 10 ** 4}
    assert fac._instack[1] == {"scale_factor": 2.0, "shots": 10 ** 5}
    assert fac._instack[2] == {"scale_factor": 3.0, "shots": 10 ** 6}
    fold_global,
)
from mitiq.benchmarks.utils import noisy_simulation
from mitiq.zne import mitigate_executor

SCALE_FUNCTIONS = [
    fold_gates_at_random,
    fold_gates_from_left,
    fold_gates_from_right,
    fold_global,
]

FACTORIES = [
    AdaExpFactory(steps=3, scale_factor=1.5, asymptote=0.25),
    ExpFactory([1.0, 1.4, 2.1], asymptote=0.25),
    RichardsonFactory([1.0, 1.4, 2.1]),
    LinearFactory([1.0, 1.6]),
    PolyFactory([1.0, 1.4, 2.1], order=2),
]


def test_rb_circuits():
    depths = range(2, 10, 2)

    # test single qubit RB
    for trials in [2, 3]:
        circuits = rb_circuits(n_qubits=1, num_cliffords=depths, trials=trials)
        for qc in circuits:
            # we check the ground state population to ignore any global phase
            wvf = qc.final_wavefunction()
            zero_prob = abs(wvf[0]**2)