3
$\begingroup$

Having read the Qiskit demonstration in the Qiskit textbook on how to implement Quantum Phase Estimation, I tried to do so on PennyLane's framework. My code pretty well follows what was done in Qiskit, with a few nuances according to PennyLane, but when I run it over many shots, I get varying answers. For reference, I was implementing the T-Gate (exactly what is done in Qiskit textbook). While my code yields varying possibilities, Qiskit's strictly obtains 001 (which, through post-processing, shows that the applied phase was 1/8). Perhaps there is something wrong with the program I wrote? Is the code supposed to always yield 001?

dev = qml.device('default.qubit', wires = 4, shots=1)

@qml.qnode(dev)

def circuit():

    qml.PauliX(wires = 3)
    
    for qubit in range(3):
        qml.Hadamard(qubit)     
    
    def t_gate(j):
        qml.T(wires = j)
    
    repetitions = 1
    n = len(dev.wires) - 1
    for x in range(n-1, -1, -1):
        for i in range(repetitions):  
            qml.ctrl(t_gate, control = x)(3)
        repetitions *= 2
        
    def ops1(wires = [0, 2]):
        qml.templates.QFT(wires = [0, 2])
    qml.adjoint(ops1)(wires = [0, 2])   

    return qml.sample()

fig, ax = qml.draw_mpl(circuit)()

fig.show()

for i in range(0, 10):

    print(circuit())

Results:

[0 0 1 1]

[0 1 1 1]

[1 1 1 1]

[0 1 1 1]

[1 1 1 1]

[0 0 1 1]

[1 0 1 1]

[0 0 1 1]

[0 0 1 1]

[0 0 1 1]
$\endgroup$
1
  • $\begingroup$ +1 and welcome to our community! Is it possible for your to copy-and-paste that code rather than giving us a screenshot? Having actual text instead of an image, makes the text more searchable and friendly to blind people, people with screen readers, or people with images blocked to speed up loading on their slow mobile phones. $\endgroup$ Jan 3 at 4:25
1
$\begingroup$

Your circuit is very close, with only minor modifications needed to match the result from the Qiskit textbook.

  • The counting registers are the first three wires of the circuit; so we need to apply the inverse QFT to wires 0, 1, and 2.

  • Similarly, we want to measure samples only from wires 0, 1, and 2.

Here is an updated version of your code with these two changes:

import pennylane as qml
import numpy as np

dev = qml.device("default.qubit", wires=4, shots=10)


@qml.qnode(dev)
def circuit():
    qml.PauliX(wires=3)

    for qubit in range(3):
        qml.Hadamard(wires=qubit)

    repetitions = 1

    for x in range(2, -1, -1):
        for i in range(repetitions):
            qml.ControlledPhaseShift(np.pi / 4, wires=[x, 3])

        repetitions *= 2

    qml.adjoint(qml.QFT)(wires=[0, 1, 2])
    return qml.sample(wires=[0, 1, 2])


print(qml.draw(circuit)())
print(circuit())

This gives the results:

 0: ──H────────────────────────────────────────────────────────────────────────────────────────────╭ControlledPhaseShift(0.785)──╭ControlledPhaseShift(0.785)──╭ControlledPhaseShift(0.785)──╭ControlledPhaseShift(0.785)──╭QFT⁻¹──╭┤ Sample[basis]
 1: ──H────────────────────────────────╭ControlledPhaseShift(0.785)──╭ControlledPhaseShift(0.785)──│─────────────────────────────│─────────────────────────────│─────────────────────────────│─────────────────────────────├QFT⁻¹──├┤ Sample[basis]
 2: ──H──╭ControlledPhaseShift(0.785)──│─────────────────────────────│─────────────────────────────│─────────────────────────────│─────────────────────────────│─────────────────────────────│─────────────────────────────╰QFT⁻¹──╰┤ Sample[basis]
 3: ──X──╰ControlledPhaseShift(0.785)──╰ControlledPhaseShift(0.785)──╰ControlledPhaseShift(0.785)──╰ControlledPhaseShift(0.785)──╰ControlledPhaseShift(0.785)──╰ControlledPhaseShift(0.785)──╰ControlledPhaseShift(0.785)───────────┤

[[0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]
 [0 0 1]]

matching the expected result from applying phase estimation.


Note that I also made some other minor modifications:

  • Rather than looping over the QNode executions, if you set shots=N in the device, you will get a somewhat significant speed boost!

  • While qml.ctrl(qml.T, control=x)(wires=x) works, I have slightly modified this to use qml.ControlledPhaseShift, simply because it prints out slightly nicer in the circuit drawer

  • qml.T and qml.QFT are directly callables, so they can be passed directly to qml.ctrl and qml.adjoint, no need to wrap them in functions :)

$\endgroup$
1
  • $\begingroup$ Thank you so much! Your help is much appreciated :) $\endgroup$ Jan 4 at 16:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.