Source code for mqt.bench.benchmarks.ghz_dynamic

# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM
# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH
# All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Licensed under the MIT License

"""Dynamic GHZ benchmark definition."""

from __future__ import annotations

from qiskit.circuit import ClassicalRegister, QuantumCircuit, QuantumRegister
from qiskit.circuit.classical import expr

from ._registry import register_benchmark


[docs] @register_benchmark("ghz_dynamic", description="Dynamic GHZ State") def create_circuit(num_qubits: int) -> QuantumCircuit: """Returns a dynamic quantum circuit implementing the GHZ state. Going from a circuit depth dependent on the number of qubits to a constant depth by using intermediate measurements. A clear example on how to transform the classical GHZ circuit to the dynamic version can be seen in https://arxiv.org/pdf/2308.13065 Fig 5. Arguments: num_qubits: number of qubits of the returned quantum circuit """ q = QuantumRegister(num_qubits, "q") final_measure = ClassicalRegister(num_qubits, "final_measurement") qc = QuantumCircuit(q, final_measure, name="ghz_dynamic") # If num_qubits = 1, then we just apply a Hadamard gate to the qubit if num_qubits == 1: qc.h(0) qc.measure(q, final_measure) return qc mid_measure = ClassicalRegister(num_qubits // 2, "mid_measurement") qc.add_register(mid_measure) # Apply Hadamard gates to all even qubits qc.h(range(0, num_qubits, 2)) # Apply CNOT gates from all even qubits to the previous and next one, if the total number of qubits is even, we ignore the last CNOT for i in range(0, num_qubits, 2): previous_qubit = i - 1 next_qubit = i + 1 if previous_qubit >= 0: qc.cx(i, previous_qubit) if next_qubit < num_qubits - 1: qc.cx(i, next_qubit) # Intermediate measurements on the odd qubits, the if_test statement is there to simulate a reset operation as this is not accepted by some hardware for classical_bit, qubit in zip(mid_measure, range(1, num_qubits, 2), strict=True): qc.measure(qubit, classical_bit) with qc.if_test((classical_bit, 1)): qc.x(qubit) condition = mid_measure[0] # We apply an X gate to all even qubits other than the first one if the XOR of the intermediate measurements of all the previous qubits is 1 for i in range(2, num_qubits, 2): with qc.if_test(expr.equal(condition, True)): qc.x(i) if i // 2 < len(mid_measure): condition = expr.bit_xor(condition, mid_measure[i // 2]) # We apply CNOT gates to the qubits we measured before and reset from the previous qubit for i in range(0, num_qubits - 1, 2): qc.cx(i, i + 1) qc.measure(q, final_measure) return qc