qml.qcut.expand_fragment_tapes_mc¶
- expand_fragment_tapes_mc(tapes, communication_graph, shots)[source]¶
Expands fragment tapes into a sequence of random configurations of the contained pairs of
MeasureNode
andPrepareNode
operations.For each pair, a measurement is sampled from the Pauli basis and a state preparation is sampled from the corresponding pair of eigenstates. A settings array is also given which tracks the configuration pairs. Since each of the 4 measurements has 2 possible eigenvectors, all configurations can be uniquely identified by 8 values. The number of rows is determined by the number of cuts and the number of columns is determined by the number of shots.
Note
This function is designed for use as part of the sampling-based circuit cutting workflow. Check out the
cut_circuit_mc()
transform for more details.- Parameters
tapes (Sequence[QuantumTape]) – the fragment tapes containing
MeasureNode
andPrepareNode
operations to be expandedcommunication_graph (nx.MultiDiGraph) – the communication (quotient) graph of the fragmented full graph
shots (int) – number of shots
- Returns
the tapes corresponding to each configuration and the settings that track each configuration pair
- Return type
Tuple[Sequence[QuantumTape], np.ndarray]
Example
Consider the following circuit that contains a sample measurement:
ops = [ qml.Hadamard(wires=0), qml.CNOT(wires=[0, 1]), qml.WireCut(wires=1), qml.CNOT(wires=[1, 2]), ] measurements = [qml.sample(wires=[0, 1, 2])] tape = qml.tape.QuantumTape(ops, measurements)
We can generate the fragment tapes using the following workflow:
>>> g = qml.qcut.tape_to_graph(tape) >>> qml.qcut.replace_wire_cut_nodes(g) >>> subgraphs, communication_graph = qml.qcut.fragment_graph(g) >>> tapes = [qml.qcut.graph_to_tape(sg) for sg in subgraphs]
We can then expand over the measurement and preparation nodes to generate random configurations using:
>>> configs, settings = qml.qcut.expand_fragment_tapes_mc(tapes, communication_graph, 3) >>> print(settings) [[1 6 2]] >>> for i, (c1, c2) in enumerate(zip(configs[0], configs[1])): ... print(f"config {i}:") ... print(c1.draw()) ... print("") ... print(c2.draw()) ... print("") ... config 0: 0: ──H─╭●─┤ Sample[|1⟩⟨1|] 1: ────╰X─┤ Sample[Z] 1: ──I─╭●─┤ Sample[|1⟩⟨1|] 2: ────╰X─┤ Sample[|1⟩⟨1|] config 1: 0: ──H─╭●─┤ Sample[|1⟩⟨1|] 1: ────╰X─┤ Sample[Y] 1: ──H──S─╭●─┤ Sample[|1⟩⟨1|] 2: ───────╰X─┤ Sample[|1⟩⟨1|] config 2: 0: ──H─╭●─┤ Sample[|1⟩⟨1|] 1: ────╰X─┤ Sample[Y] 1: ──X──H──S─╭●─┤ Sample[|1⟩⟨1|] 2: ──────────╰X─┤ Sample[|1⟩⟨1|]