Hi,
while working on a project, I realized it would be nice if there was a small library of basic arithmetic functions. Specifically, since continuous functions can be approximated by a power series, the following minimal toolkit would allow users to implement whatever they want:
With these one could calculate e.g.
exp(x) = 1 + x + 1/2! x^2 + 1/3! x^3
Cheers,
Riccardo
Thanks @rdisipio!
This is great feedback and I agree that it would be something very nice to add.
Iβm not sure how soon weβd be able to get to looking at such a feature, but in the meantime we actively welcome contributions!
Cheers,
Tom
And as always, pull requests are very welcome.
Chase
Yeah, Iβll see what I can do but no committments. Since weβre here, I actually started looking at the QFT. I couldnβt find an implementation anywhere in the code base. Is called something else? Also, when I print out the circtuit, I get this:
1: βββββββββββββββββββββββββββCββββββββββββββββββCβββββββββββββββββββββββββββββββββββHββββββββββββββββββββββ°Rot(1.57, 0, 0)βββββββββββββ€ β¨Zβ©
2: ββββββCββββββββββββββββHββββββββββββββββββββββ°Rot(1.57, 0, 0)βββββββββββββββββββββββββ°Rot(0.785, 0, 0)βββββββββββββββββββββββββββββββ€ β¨Zβ©
3: ββHβββ°Rot(1.57, 0, 0)ββββββ°Rot(0.785, 0, 0)βββββββββββββββββββββ°Rot(0.393, 0, 0)ββββββββββββββββββββββββββββββββββββββββββββββ°SWAPβββ€ β¨Zβ©
The second H gate is supposed to be applied after the sequence of controlled rotations. Is there any βbarrierβ command in PennyLane? Or is it just an issue with the printing routine?
FYI, one can get some inspiration from this library based on Qiskit: https://github.com/hkhetawat/QArithmetic
Cheers,
Riccardo
1 Like
Thanks @rdisipio!
The QFT is available in the development branch of PennyLane. To access this, you can install using these instructions.
1 Like
Hello again,
To get my feet wet, I tried to implement the Draper Adder but Iβm quite confused. The algorithm is implemented in a number of languages but this is probably the easiest to read: https://github.com/hkhetawat/QArithmetic/blob/master/QArithmetic.py
I see that QFT in PennyLane derives from Operation
base class, but for now I wanted to keep things easy, so I implemented it as a simple sequence of gates.
#!/usr/bin/env python
import numpy as np
import pennylane as qml
def add(wires_a, wires_b):
assert len(wires_b) > len(wires_a)
n = len(wires_a)
# encode number a into the phase basis
qml.QFT(wires=wires_b)
for i in range(n, 0, -1):
# loop over control qubits (a)
for j in range(i, 0, -1):
if n - 1 >= j - 1:
phi = 2 * np.pi / np.power(2, i-j+1)
qml.ControlledPhaseShift(phi, wires=[wires_a[j-1], wires_b[i-1]])
# go back to computational basis
qml.QFT(wires=wires_b).inv()
def test_add(bs):
print(bs)
qml.BasisState(bs, wires=wires)
add(wires_a, wires_b)
return [qml.expval(qml.PauliZ(i)) for i in wires_b]
n_qubits_per_number = 3
wires_a = [f'a{i}' for i in range(n_qubits_per_number)]
wires_b = [f'b{i}' for i in range(n_qubits_per_number+1)]
wires = wires_a + wires_b
dev = qml.device('default.qubit', wires=wires, shots=1000, analytic=False)
circ = qml.QNode(test_add, dev)
pad = [0]
a = [0, 1, 0]
b = pad + [0, 0, 1]
bs = a + b
z = circ(bs)
print(circ.draw())
print(z)
I donβt know if the output is correct. I get z = [ 0.678 1. -1. -1. ]
which may be a base-2 encoding of 3 (itβs either 1100 or 0011 depending on how you interpret the pauli-z states). If I print out the circuit after execution, I see this:
a0: βββ|0β©ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββControlledPhaseShift(0.785)βββControlledPhaseShift(1.57)βββControlledPhaseShift(3.14)βββββββββββ€
a1: βββ|1β©ββββββββββββββββββββββββββββββββββββββControlledPhaseShift(1.57)βββControlledPhaseShift(3.14)βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
a2: βββ|0β©βββββββββControlledPhaseShift(3.14)βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
b0: βββ|0β©βββQFTβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ°ControlledPhaseShift(3.14)βββQFTβ»ΒΉβββ€ β¨Zβ©
b1: βββ|0β©βββQFTβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ°ControlledPhaseShift(3.14)βββββββββββββββββββββββββββββββββ°ControlledPhaseShift(1.57)ββββββββββββββββββββββββββββββββQFTβ»ΒΉβββ€ β¨Zβ©
b2: βββ|0β©βββQFTβββ°ControlledPhaseShift(3.14)βββ°ControlledPhaseShift(1.57)ββββββββββββββββββββββββββββββββ°ControlledPhaseShift(0.785)βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββQFTβ»ΒΉβββ€ β¨Zβ©
b3: βββ°|1β©βββ°QFTββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ°QFTβ»ΒΉβββ€ β¨Zβ©
I donβt think the gates are executed in the same order they are defined in the nested loops, e.g. controlled gates acting on b3
should be executed before moving to b2
. What am I doing wrong?
Thanks,
Riccardo
Hi @rdisipio,
This looks really cool! Thanks for checking it out.
I need a bit more time to get familiar with the circuit, but from an initial look at the printed-out circuit, it seems weird that no phase shift gates are being applied to b3
. Has your code taken into account that the b
register has n + 1
qubits? Maybe you just need to add-in that offset.
I will have a closer look though, this looks really cool! In the long run, it might be nice to add this as a PennyLane template.
Thanks!