Hi!
I have a question regarding the two circuit-cutting postprocessing functions qcut_processing_fn_sample
and qcut_processing_fn_mc
:
Is qcut_processing_fn_mc
with a postprocessing function fn
the same as running qcut_processing_fn_sample
and running np.mean([fn(s) for s in samples])
on the resulting samples?
In particular, in the following example, they seem to be the same (or at least similar), but are they by definition?
import pennylane as qml
from pennylane import numpy as np
from functools import partial
dev = qml.device("default.qubit", wires=2, shots=10000)
def fn(x):
if x[0] == 0:
return 1
if x[0] == 1:
return -1
@partial(qml.cut_circuit_mc, classical_processing_fn=fn)
@qml.qnode(dev)
def circuit(x):
qml.RX(0.89, wires=0)
qml.RY(0.5, wires=1)
qml.RX(1.3, wires=2)
qml.CNOT(wires=[0, 1])
qml.WireCut(wires=1)
qml.CNOT(wires=[1, 2])
qml.RX(x, wires=0)
qml.RY(0.7, wires=1)
qml.RX(2.3, wires=2)
return qml.sample(wires=[0, 1, 2])
@partial(qml.cut_circuit_mc)
@qml.qnode(dev)
def circuit2(x):
qml.RX(0.89, wires=0)
qml.RY(0.5, wires=1)
qml.RX(1.3, wires=2)
qml.CNOT(wires=[0, 1])
qml.WireCut(wires=1)
qml.CNOT(wires=[1, 2])
qml.RX(x, wires=0)
qml.RY(0.7, wires=1)
qml.RX(2.3, wires=2)
return qml.sample(wires=[0, 1, 2])
x = 2.90
res1 = circuit(x)
samples = circuit2(x)
res2 = np.mean([fn(s) for s in samples])
print(abs(res1-res2))
If they are the same per definition, what is the advantage of qcut_processing_fn_mc
compared to qcut_processing_fn_sample
?
Thank you!
Nate