qml.ftqc.diagonalize_mcms

diagonalize_mcms(tape)[source]

Diagonalize any mid-circuit measurements in a parameterized basis into the computational basis.

Parameters

tape (QNode or QuantumScript or Callable) – The quantum circuit to modify the mid-circuit measurements of.

Returns

The transformed circuit as described in qml.transform.

Return type

qnode (QNode) or tuple[List[QuantumScript], function]

Examples:

This transform allows us to transform mid-circuit measurements into the measurement basis by adding the relevant diagonalizing gates to the tape just before the measurement is performed.

from pennylane.ftqc import diagonalize_mcms, ParametricMidMeasureMP

dev = qml.device("default.qubit", shots=1000)

@diagonalize_mcms
@qml.qnode(dev, mcm_method="one-shot")
def circuit(x):
    qml.RX(x, wires=0)
    m = measure_y(0)
    qml.cond(m, qml.X)(1)
    return qml.expval(qml.Z(1))

Applying the transform inserts the relevant gates before the measurement to allow measurements to be in the Z basis, so the original circuit

>>> print(qml.draw(circuit, level=0)(np.pi/4))
0: ──RX(0.79)──┤↗ʸ├────┤
1: ─────────────║────X─┤  <Z>
                ╚════╝

becomes

>>> print(qml.draw(circuit)(np.pi/4))
0: ──RX(0.79)──S†──H──┤↗├────┤
1: ────────────────────║───X─┤  <Z>
                       ╚═══╝

The transform can also handle diagonalization of conditional measurements created by qml.ftqc.cond_measure. This is done by replacing the measurements for the true and false condition with conditional diagonalizing gates, and a single measurement in the computational basis:

from pennylane.ftqc import cond_measure, diagonalize_mcms, measure_x

dev = qml.device("default.qubit")

@diagonalize_mcms
@qml.qnode(dev)
def circuit(x):
    qml.RY(x[0], wires=0)
    qml.RX(x[1], wires=1)
    m = qml.measure(0)
    m2 = cond_measure(m, measure_x, measure_y)(1)
    qml.cond(m2, qml.X)(1)
    return qml.expval(qml.Z(1))

The cond_measure function adds a conditional X-basis measurement and a conditional Y basis measurement to the circuit, with opposite conditions. When the transform is applied, the diagonalizing gates of the measurements are conditional. The two conditional measurements then become equivalent measurements in the computational basis with opposite conditions, and can be simplified to a single, unconditional measurement in the computational basis.

This circuit thus diagonalizes to:

>>> print(qml.draw(circuit)([np.pi, np.pi/4]))
0: ──RY(3.14)──┤↗├───────────────────┤
1: ──RX(0.79)───║───H──S†──H──┤↗├──X─┤  <Z>
                ╚═══╩══╩═══╝   ║   ║
                               ╚═══╝

where the initial Hadamard gate on wire 1 has the same condition as the original X-basis measurement, and the adjoint S gate and second Hadamard share a condition with the Y-basis measurement.