Qwerty Examples #
Below is a sampling of quantum algorithms implemented in Qwerty. For each algorithm, the left code block is the algorithm itself, and the right is Python code that invokes the algorithm on an example input.
The Qwerty QCE ‘25 paper describes many of these examples in more detail.
Deutsch’s Algorithm #
Algorithm (
deutsch.py
):from qwerty import *
def deutsch(oracle):
@qpu
def kernel():
return 'p' | oracle.sign | pm.measure
return kernel()
Driver (
deutsch_driver.py
):from qwerty import *
from deutsch import deutsch
@classical
def balanced(x: bit) -> bit:
return ~x
@classical
def constant(x: bit) -> bit:
return bit[1](0b1)
print('If f(x) = ~x:')
print('f(0) xor f(1) =', deutsch(balanced))
print('If f(x) = 1:')
print('f(0) xor f(1) =', deutsch(constant))
Bernstein–Vazirani #
Algorithm (
bv.py
):from qwerty import *
def bv(secret_str):
@classical[[N]]
def oracle(x: bit[N]) -> bit:
return (secret_str & x).xor_reduce()
@qpu[[N]]
def kernel():
return ('p'**N | oracle.sign
| pm**N >> std**N
| measure**N)
return kernel()
Driver (
bv_driver.py
):from qwerty import *
from bv import bv
secret_str = bit[4](0b1101)
print(bv(secret_str))
Superdense Coding #
Algorithm (
superdense.py
):from qwerty import *
def superdense_coding(payload: bit[2]):
bit0, bit1 = payload
@qpu
def kernel():
alice, bob = '00' + '11'
sent_to_bob = (
alice | ({'0'>>'1', '1'>>'0'}
if bit0 else id)
| ('1' >> -'1'
if bit1 else id))
return (sent_to_bob * bob
| {'00' + '11', '00' + -'11',
'10' + '01', '01' + -'10'}
.measure)
recovered_payload = kernel()
return recovered_payload
Driver (
superdense_driver.py
):from qwerty import *
from superdense import superdense_coding
for i in range(1 << 2):
payload = bit[2](i)
print('{} -> {}'.format(
payload, superdense_coding(payload)))
Quantum Teleportation #
Algorithm (
teleport.py
):from qwerty import *
@qpu
def teleport(payload: qubit) -> qubit:
alice, bob = '00' + '11'
bit_flip, sign_flip = (
alice * payload | (flip if '_1' else id)
| (std * pm).measure)
teleported_payload = (
bob | (flip if bit_flip else id)
| ('1' >> -'1'
if sign_flip else id))
return teleported_payload
Driver (
teleport_driver.py
):from qwerty import *
from teleport import teleport
@qpu
def teleport_1():
alice = '1'
bob = teleport(alice)
return std.measure(bob)
histogram(teleport_1(shots=1024))
@qpu
def teleport_j():
alice = 'j'
bob = teleport(alice)
return ij.measure(bob)
histogram(teleport_j(shots=1024))
Grover’s Algorithm #
Algorithm (
grover.py
):from qwerty import *
def grover(oracle, num_iter):
@qpu[[N]]
def grover_iter(q):
return (q | oracle.sign
| 'p'**N >> -'p'**N)
@qpu[[N]]
def kernel():
return ('p'**N | (grover_iter
for i in range(num_iter))
| measure**N)
return kernel()
Driver (
grover_driver.py
):from qwerty import *
from grover import grover
@classical
def oracle(x: bit[4]) -> bit:
return x[0] & ~x[1] & x[2] & ~x[3]
print(grover(oracle, num_iter=3))
Period Finding #
Algorithm (
period.py
):import math
from fractions import Fraction
from qwerty import *
def period_finding(f):
@qpu[[N]]
def kernel():
return ('p'**N * '0'**N
| f.xor
| id**N * discard**N
| fourier[N].measure)
def shift_binary_point(bits):
return Fraction(int(bits),
2**len(bits))
frac1 = shift_binary_point(kernel())
frac2 = shift_binary_point(kernel())
return math.lcm(frac1.denominator,
frac2.denominator)
Driver (
period_driver.py
):from qwerty import *
from period import period_finding
@classical
def mod4(x: bit[3]) -> bit[3]:
return x % 4
period = period_finding(mod4)
if period == 4:
print('Success!')
else:
print('Period finding failed')
Quantum Phase Estimation #
Algorithm (
qpe.py
):from fractions import Fraction
from qwerty import *
def qpe(prec, get_init_state, op):
@qpu[[M]]
def kernel():
return ('p'**prec * get_init_state()
| (op[[prec-1-j]]
in '?'**j * '1' * '?'**(prec-1-j)
* '_'**M
for j in range(prec))
| fourier[prec].measure
* discard**M)
bits = kernel()
return Fraction(int(bits),
2**len(bits))
Driver (
qpe_driver.py
):from qwerty import *
from qpe import qpe
angle_deg = 225.0
precision = 3
@qpu
def init1():
return '1'
@qpu[[J]]
@reversible
def tilt_op(q):
return q | '1' >> '1'@(angle_deg*2**J)
print('Expected:', angle_deg)
angle_got = 360*qpe(precision, init1,
tilt_op)
print('Actual:', float(angle_got))
Shor’s Algorithm #
Algorithm (
shor.py
):import math
from qwerty import *
from qpe import qpe
def order_finding(err_tol, x, modN):
m = math.ceil(math.log2(modN))
prec = 2*m + 1 + math.ceil(
math.log2(2+1/(2*err_tol)))
@qpu
def one():
return '0'**(m-1) * '1'
@classical[[J]]
@reversible
def mult(y: bit[m]) -> bit[m]:
return x**2**J * y % modN
op = mult.inplace
frac1 = qpe(prec, one, op)
frac2 = qpe(prec, one, op)
def get_denom(frac):
cf = cfrac(frac)
for conv in reversed(cf.convergents()):
if conv.denominator < modN:
return conv.denominator
return math.lcm(get_denom(frac1),
get_denom(frac2))
Driver (
shor_driver.py
):import math
import random
from shor import order_finding
def shor(epsilon, num):
if num % 2 == 0:
return 2
x = random.randint(2, num-1)
if (y := math.gcd(x, num)) > 1:
print('Got lucky! Skipping order subroutine')
return y
r = order_finding(epsilon, x, num)
if r % 2 == 0 and pow(x, r//2, num) != -1:
if (gcd := math.gcd(x**(r//2)-1, num)) > 1 \
and gcd != num:
return gcd
if (gcd := math.gcd(x**(r//2)+1, num)) > 1 \
and gcd != num:
return gcd
raise Exception("Shor's failed")
print(shor(0.2, 15))