I've been working on implementing Shor's Algorithm in PennyLane, but am struggling to understand how the circuit for 'U' has been constructed according to Qiskit. In the Qiskit textbook, they seek to factor 15, which, for my own sake, is what I decided to do as well (but in PennyLane). I used eight counting qubits, and four for the unitary to act upon. So far, my code looks like this:
n_count = 8
dev = qml.device('default.qubit', wires = n_count + 4, shots = 10)
def c_amod15(a, power):
for iteration in range(power):
if a in [2, 13]:
qml.SWAP(wires = [8, 9])
qml.SWAP(wires = [9, 10])
qml.SWAP(wires = [10, 11])
if a in [7, 8]:
qml.SWAP(wires = [10, 11])
qml.SWAP(wires = [9, 10])
qml.SWAP(wires = [8, 9])
if a == 11:
qml.SWAP(wires = [9, 11])
qml.SWAP(wires = [8, 10])
if a in [7, 11, 13]:
for k in range(8, 12):
qml.PauliX(wires = k)
@qml.qnode(dev)
def circuit():
N = 15
np.random.seed(1)
a = np.random.randint(2, 15)
if math.gcd(a, N) != 1:
raise ValueError("Non-trivial factor.")
for k in range(0, 8):
qml.Hadamard(wires = k)
qml.PauliX(wires = n_count + 3)
for k in range(0, 8):
qml.ctrl(c_amod15, control = k)(a, 2**k)
qml.adjoint(qml.QFT)(wires = [0, 1, 2, 3, 4, 5, 6, 7])
return qml.sample(wires = range(0, 8))
circuit()
print(circuit())
fig, ax = qml.draw_mpl(circuit)()
fig.show()
The 'c_amod15' function was taken directly from Qiskit's hardcoded implementation. Am I applying this in the correct way? My results from this are:
[[1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1]
[0 0 0 0 0 0 0 0]
[1 1 1 1 1 1 1 1]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 1]
[0 0 0 0 0 0 0 1]
[1 1 1 1 1 0 1 1]
[1 1 1 1 1 1 1 1]
[1 1 1 1 1 1 1 1]]
I am still very new to this, and haven't done any of the classical post-processing yet, so any help would be much appreciated.