qml.transforms.sign_expand¶

sign_expand
(tape, circuit=False, J=10, delta=0.0, controls=('Hadamard', 'Target'))[source]¶ Splits a tape measuring a (fastforwardable) 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 (QuantumTape) – the tape 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 sgndecomposition
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
 Returns a tuple containing a list of quantum tapes
to be evaluated, and a function to be applied to these tape executions to compute the expectation value.
 Return type
tuple[list[QuantumTape], function]
Example
Given a Hamiltonian,
H = qml.PauliZ(0) + 0.5 * qml.PauliZ(2) + qml.PauliZ(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.PauliX(wires=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.PauliX(wires=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 postprocessing 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.batch_execute(tapes) >>> fn(res) 0.4999999999999999
To evaluate the circuit approximation of the decomposition one can construct the sgndecomposition 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.batch_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.PauliX(wires=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.batch_execute(tapes) >>> fn(res) 10.108949481425782