Exemplo n.º 1
0
def test_execute_with_zne_transpiled_qiskit_circuit():
    """Tests ZNE when transpiling to a Qiskit device. Note transpiling can
    introduce idle (unused) qubits to the circuit.
    """
    from qiskit.test.mock import FakeSantiago

    santiago = FakeSantiago()
    backend = qiskit.providers.aer.AerSimulator.from_backend(santiago)

    def execute(circuit: qiskit.QuantumCircuit, shots: int = 8192) -> float:
        job = qiskit.execute(circuit, backend, shots=shots)
        return job.result().get_counts().get("00", 0.0) / shots

    qreg = qiskit.QuantumRegister(2)
    creg = qiskit.ClassicalRegister(2)
    circuit = qiskit.QuantumCircuit(qreg, creg)
    for _ in range(10):
        circuit.x(qreg)

    circuit.measure(qreg, creg)
    circuit = qiskit.transpile(circuit, backend, optimization_level=0)

    true_value = 1.0
    zne_value = execute_with_zne(circuit, execute)

    # Note: Unmitigated value is also (usually) within 10% of the true value.
    # This is more to test usage than effectiveness.
    assert abs(zne_value - true_value) < 0.1
Exemplo n.º 2
0
def test_execute_with_zne():
    """Tests a random identity circuit execution with zero-noise extrapolation.
    """
    rand_circ = random_one_qubit_identity_circuit(num_cliffords=TEST_DEPTH)
    qp = measure(rand_circ, qid=0)
    result = execute_with_zne(qp, basic_executor, scale_noise=scale_noise)
    assert np.isclose(result, 1.0, atol=1.0e-1)
Exemplo n.º 3
0
def track_zne(
    circuit_type: str, nqubits: int, depth: int, observable: Observable,
) -> float:
    """Returns the ZNE error mitigation factor, i.e., the ratio

    (error without ZNE) / (error with ZNE).

    Args:
        circuit_type: Type of benchmark circuit.
        nqubits: Number of qubits in the benchmark circuit.
        depth: Some proxy of depth in the benchmark circuit.
        observable: Observable to compute the expectation value of.
    """
    circuit = get_benchmark_circuit(circuit_type, nqubits, depth)

    true_value = raw.execute(
        circuit, compute_density_matrix_noiseless, observable
    )
    raw_value = raw.execute(
        circuit, mitiq_cirq.compute_density_matrix, observable
    )
    zne_value = zne.execute_with_zne(
        circuit, mitiq_cirq.compute_density_matrix, observable,
    )
    return np.real(abs(true_value - raw_value) / abs(true_value - zne_value))
Exemplo n.º 4
0
def test_execute_with_zne():
    true_zne_value = 1.0

    circuit = measure(
        random_one_qubit_identity_circuit(num_cliffords=TEST_DEPTH), 0)
    base = qiskit_executor(circuit)
    zne_value = zne.execute_with_zne(circuit, qiskit_executor)

    assert abs(true_zne_value - zne_value) < abs(true_zne_value - base)
Exemplo n.º 5
0
def test_execute_with_zne():
    (qp, ) = benchmarks.generate_rb_circuits(
        n_qubits=1,
        num_cliffords=TEST_DEPTH,
        trials=1,
        return_type="pyquil",
    )
    result = zne.execute_with_zne(qp, noiseless_executor)
    assert np.isclose(result, 1.0, atol=1e-5)
Exemplo n.º 6
0
def test_execute_with_zne_no_noise(fold_method, factory, num_to_average):
    """Tests execute_with_zne with noiseless simulation."""
    zne_value = execute_with_zne(
        circ,
        executor,
        num_to_average=num_to_average,
        scale_noise=fold_method,
        factory=factory([1.0, 2.0, 3.0]),
    )
    assert np.isclose(zne_value, 0.0)
Exemplo n.º 7
0
 def qaoa_cost(params: np.ndarray) -> float:
     qaoa_prog = qaoa_ansatz(params)
     if scale_noise is None and factory is None:
         return noisy_backend(qaoa_prog)
     else:
         assert scale_noise is not None
         return execute_with_zne(
             qaoa_prog,
             executor=noisy_backend,
             scale_noise=scale_noise,
             factory=factory,
         )
Exemplo n.º 8
0
def test_qiskit_execute_with_zne():
    true_zne_value = 1.0

    circuit = qiskit_measure(
        *generate_rb_circuits(
            n_qubits=1,
            num_cliffords=TEST_DEPTH,
            trials=1,
            return_type="qiskit",
        ),
        0,
    )
    base = qiskit_executor(circuit)
    zne_value = execute_with_zne(circuit, qiskit_executor)
    assert abs(true_zne_value - zne_value) < abs(true_zne_value - base)
Exemplo n.º 9
0
def test_with_observable_batched_factory(executor):
    observable = Observable(PauliString(spec="Z"))
    circuit = cirq.Circuit(cirq.H.on(cirq.LineQubit(0))) * 20

    noisy_value = observable.expectation(circuit, sample_bitstrings)
    zne_value = execute_with_zne(
        circuit,
        executor=functools.partial(executor, noise_model=cirq.depolarize),
        observable=observable,
        factory=PolyFactory(scale_factors=[1, 3, 5], order=2),
    )
    true_value = observable.expectation(
        circuit, functools.partial(compute_density_matrix, noise_level=(0, )))

    assert abs(zne_value - true_value) <= abs(noisy_value - true_value)
Exemplo n.º 10
0
def test_with_observable_adaptive_factory(executor):
    observable = Observable(PauliString(spec="Z"))
    circuit = cirq.Circuit(cirq.H.on(cirq.LineQubit(0))) * 20

    noisy_value = observable.expectation(circuit, sample_bitstrings)
    zne_value = execute_with_zne(
        circuit,
        executor=functools.partial(executor, noise_model=cirq.amplitude_damp),
        observable=observable,
        factory=AdaExpFactory(steps=4, asymptote=0.5),
    )
    true_value = observable.expectation(
        circuit, functools.partial(compute_density_matrix, noise_level=(0, )))

    assert abs(zne_value - true_value) <= abs(noisy_value - true_value)
Exemplo n.º 11
0
def test_execute_with_zne_bad_arguments():
    """Tests errors are raised when execute_with_zne is called with bad args.
    """
    with pytest.raises(TypeError,
                       match="Argument `executor` must be callable"):
        execute_with_zne(circ, None)

    with pytest.raises(TypeError, match="Argument `factory` must be of type"):
        execute_with_zne(circ, executor, factory=RichardsonFactory)

    with pytest.raises(TypeError, match="Argument `scale_noise` must be"):
        execute_with_zne(circ, executor, scale_noise=None)
Exemplo n.º 12
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)
Exemplo n.º 13
0
def test_with_observable_two_qubits(executor):
    observable = Observable(PauliString(spec="XX", coeff=-1.21),
                            PauliString(spec="ZZ", coeff=0.7))
    circuit = cirq.Circuit(cirq.H.on(cirq.LineQubit(0)),
                           cirq.CNOT.on(*cirq.LineQubit.range(2)))
    circuit += [circuit, cirq.inverse(circuit)] * 20

    noisy_value = observable.expectation(circuit, sample_bitstrings)
    zne_value = execute_with_zne(
        circuit,
        executor=functools.partial(executor, noise_model=cirq.depolarize),
        observable=observable,
        factory=PolyFactory(scale_factors=[1, 3, 5], order=2),
    )
    true_value = observable.expectation(
        circuit, functools.partial(compute_density_matrix, noise_level=(0, )))

    assert abs(zne_value - true_value) <= 3 * abs(noisy_value - true_value)
Exemplo n.º 14
0
def rand_circuit_zne(
    n_qubits: int,
    depth: int,
    trials: int,
    noise: float,
    fac: Optional[Factory] = None,
    scale_noise: Callable[[QPROGRAM, float], QPROGRAM] = fold_gates_at_random,
    op_density: float = 0.99,
    silent: bool = True,
    seed: Optional[int] = None,
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Benchmarks a zero-noise extrapolation method and noise scaling executor
    by running on randomly sampled quantum circuits.

    Args:
        n_qubits: The number of qubits.
        depth: The depth in moments of the random circuits.
        trials: The number of random circuits to average over.
        noise: The noise level of the depolarizing channel for simulation.
        fac: The Factory giving the extrapolation method.
        scale_noise: The method for scaling noise, e.g. fold_gates_at_random
        op_density: The expected proportion of qubits that are acted on in
                    any moment.
        silent: If False will print out statements every tenth trial to
                track progress.
        seed: Optional seed for random number generator.

    Returns:
        The triple (exacts, unmitigateds, mitigateds) where each is a list
        whose values are the expectations of that trial in noiseless, noisy,
        and error-mitigated runs respectively.
    """
    exacts = []
    unmitigateds = []
    mitigateds = []

    qubits = [NamedQubit(str(xx)) for xx in range(n_qubits)]

    if seed:
        rnd_state = np.random.RandomState(seed)
    else:
        rnd_state = None

    for ii in range(trials):
        if not silent and ii % 10 == 0:
            print(ii)

        qc = random_circuit(
            qubits,
            n_moments=depth,
            op_density=op_density,
            random_state=rnd_state,
        )

        wvf = qc.final_state_vector()

        # calculate the exact
        obs = sample_projector(n_qubits, seed=rnd_state)
        exact = np.conj(wvf).T @ obs @ wvf

        # make sure it is real
        exact = np.real_if_close(exact)
        assert np.isreal(exact)

        # create the simulation type
        def obs_sim(circ: Circuit) -> float:
            # we only want the expectation value not the variance
            # this is why we return [0]
            return noisy_simulation(circ, noise, obs)

        # evaluate the noisy answer
        unmitigated = obs_sim(qc)
        # evaluate the ZNE answer
        mitigated = execute_with_zne(qp=qc,
                                     executor=obs_sim,
                                     scale_noise=scale_noise,
                                     factory=fac)
        exacts.append(exact)
        unmitigateds.append(unmitigated)
        mitigateds.append(mitigated)

    return np.asarray(exacts), np.asarray(unmitigateds), np.asarray(mitigateds)
Exemplo n.º 15
0
def test_execute_with_zne():
    qp = random_one_qubit_identity_circuit(num_cliffords=TEST_DEPTH)
    result = execute_with_zne(qp, noiseless_executor)
    assert np.isclose(result, 1.0, atol=1e-5)
Exemplo n.º 16
0
def test_execute_with_zne():
    rand_circ = random_identity_circuit(depth=TEST_DEPTH)
    qp = measure(rand_circ, qid=0)
    result = execute_with_zne(qp, basic_executor, None, scale_noise)
    assert np.isclose(result, 1.0, atol=1.0e-1)