How to reset a specific qubit to |0> during computation?

Hi!
I’m using qiskit.aer as a backend for machine learning based on tensor network quantum circuits, in the process I want to reuse a specific qubit by resetting it to |0>, is there any function like qiskit.QuantumCircuit .reset() to support this work?
Thanks so much!

Hi @ffff12138, welcome to the forum!

Unfortunately we don’t have the qubit reset functionality in PennyLane yet. We may be implementing it in the future though so stay tuned!

Since the qubit reset is not possible yet, something that you may want to do is add an additional qubit to your circuit and then swap it with the qubit you want to reset. This will have an equivalent functionality.

Please let me know if this helps or if you want me to clarify something here!

Thanks for your reply, the method you mentioned may defeat the original purpose of reuse to reduce the number of qubits, and it has limitations for more qubits that need to be reset to |0>, but it still provides a great idea !

Hi @ffff12138, yes, it’s not the way to go if you want to reduce the number of qubits.

If you are limited in the number of qubits because of the size of your machine you may want to use our circuit cutter. What this does is that it allows you to run programs with more qubits in smaller machines or simulators. The classical processing required increases but it may be just what you need.

Please let me know if this helps or if you need help with using the circuit cutter!

hi! @CatalinaAlbornoz I am facing the same problem, the swap test seems good option, but how can i extract the statevector without considering the swapping ancillas. If I use return qml.state() it returns the system statevector including those swapped.
Thanks for your attention!

Hey @contepablod! You can do a couple of things:

  1. Return qml.state() and then post-process the tensor to effectively ignore the ancilla register (e.g., for a 4+1 qubit state you just want the first 2^4 entries of qml.state() if the 5th qubit is the ancilla register)

  2. Return qml.density_matrix and directly specify which registers you want :slight_smile:. qml.density_matrix — PennyLane 0.30.0 documentation. There are other functionalities in PennyLane that also do partial traces (see qml.qinfo.transforms.reduced_dm: qml.qinfo.transforms.reduced_dm — PennyLane 0.30.0 documentation).

Let me know if that works!

1 Like

Thanks Isaac for qml.density_matrix ! I’ve tried this but it is not retrieving the shape I expect. I will investigate further.

If you’re expecting your circuit to output a 1D vector as opposed to a 2D matrix (what qml.density_matrix will do), then option 1 would be best!

1 Like

Thanks Isaac for the rapid answer. Yeah, my input is a 1024 feature vector map, I expect the same output in the first 10 qubits. The density matrix’s output is (4,4)

Looks like a little post-processing after your circuit runs might be needed then :grin:.

1 Like

Hi again @isaacdevlugt.
This is my circuit to rebuild an image. As I cannot reset qubits I used a SwapTest.

@qml.qnode(dev)
def circuit_test(features):
    #Amplitude Embedding
    qml.AmplitudeEmbedding(
        features=features, wires=range(0, NUM_LAT + NUM_TRASH), normalize=True
    )
    #Unitary Operation (U)
    qml.BasicEntanglerLayers(
        weights=optimal_result, wires=range(0, NUM_LAT + NUM_TRASH), rotation=qml.RY
    )
    # Reset trash space qubits to the |0> state
    for i in range(NUM_LAT, NUM_LAT + NUM_TRASH):
        qml.SWAP(wires=[i, NUM_TRASH + i])
    # Inversed BEL (Udagger)
    qml.CNOT(wires=[NUM_LAT + NUM_TRASH - 1, 0])
    for i in range(NUM_LAT + NUM_TRASH - 1, 0, -1):
        qml.CNOT(wires=[i - 1, i])
    for i in range(0, NUM_LAT + NUM_TRASH):
        qml.RY(-optimal_result[0][i], wires=i)
    return qml.density_matrix(wires=[0, NUM_LAT + NUM_TRASH])

The variable features has shape (1024,) (32x32 image). The weights have been pre-trained, and they are passed. The density matrix yields a shape of (4,4) within the 10 first qubits, but I expect a (1024,) Statevector so I can rebuild the image. Any ideas of how can I proceed?

   return qml.density_matrix(wires=range(0, NUM_LAT + NUM_TRASH))

I changed this and I got a 32,32 matrix so a 1024 flattened vector, but don’t know really if it is the vector i am looking for… Fidelity between input and output is not so high, so maybe i need to improve

Hey @contepablod!

I suggest trying to scale back your tests to make sure this is working properly. Specifically, you can try making a very simple and small circuit where you know analytically what the state should be and compare your circuit’s output to what you have on pen and paper. I’d maybe do that for a couple of different cases.

If those checks pass, then it might be that your algorithm needs some tweaking (e.g., hyperparameters, different loss function, etc.). Let me know if this helps!

1 Like

Hello! I am facing the same problem as in the original question. I want to reset specific qubits to |0> after measuring qml.expval() and subsequently use these qubits again. For example I would like to have a circuit like

dev = qml.device("default.qubit", wires=2)

@qml.qnode(dev)
def circuit(data_sequence):
    results = []
    for inp in data_sequence:
        qml.RY(inp, wires=0)
        qml.CNOT(wires=[0, 1])
        results.append(qml.expval(qml.PauliZ(wires=0)))
        # reset qubit 0 here to |0>
    return results

where in the last line of the for loop qubit 0 is reset to |0>.
I am aware that since release 0.32.0 it is possible to do qml.measure(wires=0, reset=True) which would actually reset the qubit to |0>. However by doing with each reset new qubits are added by pennylane and for a long data_sequence the circuit would become quite huge.

  1. In the Release notes — PennyLane 0.33.0 documentation it says:
    “In this version of PennyLane, executing circuits with qubit reuse will result in the defer_measurements transform being applied. This transform replaces each reused wire with an additional qubit. However, future releases of PennyLane will explore device-level support for qubit reuse without consuming additional qubits.”
    Do you already have a plan when you want to implement reusing qubits without consuming additional qubits?

  2. Do you have other ideas to reset specific qubits without increasing the number of qubits on the circuit?

Hey @tfellner , I’m looking at the circuit example and I’m wondering if parameter broadcasting (also docs here) would make this simpler (and faster) for you? I don’t know if you have a specific reason you’d want to keep this structure, so I’m sorry if I’m off the mark. :sweat_smile:

@Ivana_at_Xanadu thank you for your response!
Unfortunately parameter broadcasting doesn’t solve my problem. I want to built a Quantum Recurrent Neural Network where a sequence of time series data is encoded. Each inp in the for loop represents one datapoint and is encoded on the first qubit. Subsequently an Ansatz is performed with a second quibit representing a “hidden state”. After each time step the qml.expval of the first qubit is measured. Now I want to keep the “hidden state” of the second qubit and encode the data of the next time step onto the first qubit, which is set to |0> before. At the end I want to train the network on all elements in results.

Do you see any way to reset the first qubit to |0>?

Thank you!

Do you already have a plan when you want to implement reusing qubits without consuming additional qubits?

Hi @tfellner! We’re planning over the next few months to add native mid-circuit measurements to default.qubit and lightning.qubit in finite-shot mode. The idea is to save you from having to add an additional qubit with each mid-circuit measurement.

Thank you @Tom_Bromley, this does sound great!
I am looking forward to it!

2 Likes