qml.transforms.sign_expand¶
- sign_expand(tape, circuit=False, J=10, delta=0.0, controls=('Hadamard', 'Target'))[source]¶
Splits a tape measuring a (fast-forwardable) Hamiltonian expectation into mutliple tapes of the Xi or sgn decomposition, and provides a function to recombine the results.
Implementation of ideas from arXiv:2207.09479
For the calculation of variances, one assumes an even distribution of shots among the groups.
- Parameters
tape (QNode or QuantumTape) – the quantum circuit used when calculating the expectation value of the Hamiltonian
circuit (bool) – Toggle the calculation of the analytical Xi decomposition or if True constructs the circuits of the approximate sign decomposition to measure the expectation value
J (int) – The times the time evolution of the hamiltonian is repeated in the quantum signal processing approximation of the sgn-decomposition
delta (float) – The minimal
controls (List[control1, control2]) – The two additional controls to implement the Hadamard test and the quantum signal processing part on, have to be wires on the device
- Returns
The transformed circuit as described in
qml.transform
.- Return type
qnode (pennylane.QNode) or tuple[List[QuantumTape], function]
Example
Given a Hamiltonian,
H = qml.Z(0) + 0.5 * qml.Z(2) + qml.Z(1)
a device with auxiliary qubits,
dev = qml.device("default.qubit", wires=[0,1,2,'Hadamard','Target'])
and a circuit of the form, with the transform as decorator.
@qml.transforms.sign_expand @qml.qnode(dev) def circuit(): qml.Hadamard(wires=0) qml.CNOT(wires=[0, 1]) qml.X(2) return qml.expval(H)
>>> circuit() -0.4999999999999999
You can also work directly on tapes:
operations = [qml.Hadamard(wires=0), qml.CNOT(wires=[0, 1]), qml.X(2)] measurements = [qml.expval(H)] tape = qml.tape.QuantumTape(operations, measurements)
We can use the
sign_expand
transform to generate new tapes and a classical post-processing function for computing the expectation value of the Hamiltonian in these new decompositions>>> tapes, fn = qml.transforms.sign_expand(tape)
We can evaluate these tapes on a device, it needs two additional ancilla gates labeled ‘Hadamard’ and ‘Target’ if one wants to make the circuit approximation of the decomposition:
>>> dev = qml.device("default.qubit", wires=[0,1,2,'Hadamard','Target']) >>> res = dev.execute(tapes) >>> fn(res) -0.4999999999999999
To evaluate the circuit approximation of the decomposition one can construct the sgn-decomposition by changing the kwarg circuit to True:
>>> tapes, fn = qml.transforms.sign_expand(tape, circuit=True, J=20, delta=0) >>> dev = qml.device("default.qubit", wires=[0,1,2,'Hadamard','Target']) >>> dev.execute(tapes) >>> fn(res) -0.24999999999999994
Lastly, as the paper is about minimizing variance, one can also calculate the variance of the estimator by changing the tape:
operations = [qml.Hadamard(wires=0), qml.CNOT(wires=[0, 1]), qml.X(2)] measurements = [qml.var(H)] tape = qml.tape.QuantumTape(operations, measurements)
>>> tapes, fn = qml.transforms.sign_expand(tape, circuit=True, J=20, delta=0) >>> dev = qml.device("default.qubit", wires=[0,1,2,'Hadamard','Target']) >>> res = dev.execute(tapes) >>> fn(res) 10.108949481425782