Skip to main content

A Python library implementing error mitigation on pyquil programs.

Project description

Error Mitigation Implemented on Rigetti Forest™

The unwanted interaction of the quantum computer with the outside world introduces noise into the computations which makes fault tolerant Quantum Computation outof reach of current technologies. In this regard, to make use of NISQ devices one can consider techniques which alleviate the impacts of errors without additional resource requirements. One of such mitigation techniques (for short depth circuits) is the so called ”Extrapolation to the zero noise limit” or as we will refer to it Error Mitigation (EM) which has been successfully implemented recently. It is assumed that the action of the noise is weak and it can be described by some small parameter. The expectation value of any observable depends on this parameter and can be expanded as series in it and the 0th order term will correspond to noise-free value. It’s suggested to gain the expectation values at different noise parameters and then apply Richardson’s deferred approach to the limit to obtain an approximation to noise-free value.

This package provides easy to use interface for applying error correcting code with EM technique to any PyQuil program.

EM in this package is implemented as described here.

Installation

EMPyQuil can be installed using pip, or directly from source.

To instead install EMPyQuil as a PyPI package, do the following:

pip install em_pyquil

If you would prefer to install EMPyQuil directly from source, do the following:

pip install git+https://github.com/gate42qc/em-pyquil

Usage

This package provides two functions: apply_em and apply_noise which can be used with PyQuil QuantumComputer objects. These functions will override run methods of passed QuantumComputer objects making them return error mitigated results.

So if you have some piece of code and want to run the error mitigated version of it you only need to call apply_em on QuantumComputer object you will use for running your program.

from pyquil.api import get_qc
from pyquil.quil import Program
from pyquil.gates import X
from em_pyquil import apply_em, apply_noise

noisy_qc = apply_noise(get_qc("3q-qvm"))
em_qc = apply_em(get_qc("3q-qvm"))

p = Program(X(0))

em_res = em_qc.run_and_measure(p, 1000)  # results obtained running the program with noise and filtered with EM technique

noisy_res = noisy_qc.run_and_measure(p, 1000)  # results obtained running the program with just noise model without filtering

Examples

There are more examples in the examples directory.

Running your programs with EM technique applied

In our EM implementation we run the program multiple times with noise models with different values of the noise parameter (in current implementation noise parameter is the gate time). Then we will collect result bitstrings, get mean results for each qubit over trials, then using Richardson’s method we extrapolate results. The extrapolated results are rounded to 0 or 1 and returned.

So after the following line:

em_qc = apply_em(get_qc("3q-qvm"))

the em_qc will work exactly like QuantumComputer instance would work except that it will run programs multiple times and will return extrapolated results. This allows you to run you existing programs with EM without changing much of our existing code.

:note Do not call apply_noise or noisy_qc on the same QuantumComputer object.

You can customise noise parameters used in EM by giving the base parameter and list of coefficients:

# programs will run with gate times: 1*60e-9, 1.5*60e-9 and 2*60e-9
em_qc = apply_em(get_qc("3q-qvm"), base_gate_time=60e-9, noise_param_coefficients=[1, 1.5, 2])

Comparing noisy and noise + EM results

There is another function: apply_noise in this package you could use to obtain QuantumComputer instance that uses similar noise model to apply_em so that you can compare results:

import numpy as np
import matplotlib.pyplot as plt
import random

from pyquil.api import get_qc
from pyquil.quil import Program
from pyquil.gates import RX, RZ, CZ

from em_pyquil import apply_em, apply_noise


def get_dagger_of_native_gate(gate):
    if gate.name == "RZ":
        return RZ(-gate.params[0], gate.qubits[0])
    if gate.name == "RX":
        return RX(-gate.params[0], gate.qubits[0])
    if gate.name == "CZ":
        return CZ(*gate.qubits)

    raise ValueError("Unsupported gate: " + str(gate))


def get_random_circuit(qubits, length, two_qubit_gate_portion=0.3):
    p = Program()

    for i in range(int(length / 2)):
        if (len(qubits) > 1) and (random.random() < two_qubit_gate_portion):
            random_gate = CZ(*(random.sample(qubits, 2)))
        else:
            theta = 2 * np.pi * random.random()
            qubit = random.choice(qubits)
            random_gate = random.choice([
                RZ(theta, qubit),
                RX(np.pi / 2, qubit),
                RX(- np.pi / 2, qubit)
            ])

        p.inst(random_gate)

    for gate in reversed(Program(p.out()).instructions):
        p.inst(get_dagger_of_native_gate(gate))

    return Program('PRAGMA PRESERVE_BLOCK') + p + Program('PRAGMA END_PRESERVE_BLOCK')


def run_with_qc(qc, lengths):
    data = []

    for i in lengths:
        fidelities = []
        for j in range(20):
            p = get_random_circuit(qc.qubits(), i)
            res = qc.run_and_measure(p, 10000)
            fidelity = 1 - np.mean(res[0] * res[1])
            fidelities.append(fidelity)
        mean_fidelity = np.mean(np.array(fidelities))
        data.append(mean_fidelity)

    return data


noisy_qc = apply_noise(get_qc("3q-qvm"))
em_qc = apply_em(get_qc("3q-qvm"))

lengths = np.arange(2, 100, 5)

em_data = run_with_qc(em_qc, lengths)
noisy_data = run_with_qc(noisy_qc, lengths)

plt.xlabel('Circuit depth')
plt.ylabel('Fidelity')
plt.plot(lengths, noisy_data, 'o-', label="Only Noise")
plt.plot(lengths, em_data, 'o-', label="Noise + EM")
plt.legend()
plt.show()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

em-pyquil-1.0.2.tar.gz (5.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

em_pyquil-1.0.2-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file em-pyquil-1.0.2.tar.gz.

File metadata

  • Download URL: em-pyquil-1.0.2.tar.gz
  • Upload date:
  • Size: 5.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.4.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.3

File hashes

Hashes for em-pyquil-1.0.2.tar.gz
Algorithm Hash digest
SHA256 6b488c91adeb59967a872d2e473200ca85b9b09f7112ae1451374d58f63dd933
MD5 b1a695f0249146d7ae25e4fb1a0d63e5
BLAKE2b-256 0b24820bad2ebd6f3ed3eb3836ba352595e117b32fc76cc613c203f7555e8a3e

See more details on using hashes here.

File details

Details for the file em_pyquil-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: em_pyquil-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.4.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.3

File hashes

Hashes for em_pyquil-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 fbd43c7f0021795edfe49f64af986a6672ccb8d468a0a7a3e4e32a5d7de9651f
MD5 177bd8938e618eabd4c0f8b3fece0aa3
BLAKE2b-256 f3b3af41968e768ae63736ce88010c760db023697c1cbcc2ee48ea0f99214ef9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page