Adaptive QPE

Download this notebook - adaptive-qpe.ipynb

Implementation of the adaptive random walk phase estimation algorithm from https://arxiv.org/abs/2208.04526.

The example Hamiltonian and numbers are taken from https://arxiv.org/abs/2206.12950.

import math
from guppylang import guppy
from guppylang.std.angles import angle
from guppylang.std.builtins import comptime, result
from guppylang.std.quantum import discard, measure, qubit, h, rz, x, crz
@guppy
def oracle(ctrl: qubit, q: qubit, t: float) -> None:
    """Applies a controlled e^-iπHt/2 gate for the example Hamiltonian H = 0.5 * Z."""
    crz(ctrl, q, angle(0.5 * t))


@guppy
def eigenstate() -> qubit:
    """Prepares eigenstate of the example Hamiltonian H = 0.5 * Z."""
    q = qubit()
    x(q)
    return q
sqrt_e = math.sqrt(math.e)
sqrt_e_div = math.sqrt((math.e - 1) / math.e)


@guppy
def main() -> None:
    # Pick initial estimate of phase mean and stdv
    # and prepare eigenstate
    mu, sigma = comptime(sqrt_e_div), 1 / comptime(sqrt_e)
    tgt = eigenstate()
    for _ in range(24):
        t = 1 / sigma

        aux = qubit()
        h(aux)
        rz(aux, angle((sigma - mu) * t))
        oracle(aux, tgt, t)
        h(aux)

        if measure(aux):
            mu += sigma / comptime(sqrt_e)
        else:
            mu -= sigma / comptime(sqrt_e)
        sigma *= comptime(sqrt_e_div)

    discard(tgt)
    result("eigenvalue", 2 * mu)
emulator = main.emulator(n_qubits=2).with_seed(2)
emulator.run()
EmulatorResult(results=[QsysShot(entries=[('eigenvalue', 2.3679925580437398)])])
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

# run more shots
shots = emulator.with_shots(500).run()
fig, ax = plt.subplots(1, 1)
ax.hist([shot.as_dict()["eigenvalue"] for shot in shots], bins=100)
ax.xaxis.set_major_locator(ticker.MultipleLocator(0.5))
plt.show()
../../_images/4924b0d83252af9374ce822ff10adb7447153776777e257564e0630573d41151.png