Source code for qolumbina.programs.comparator.less_than_phase

# This code is developed through cross-language conversion from 
# https://github.com/MgcosA/Code_of_Testing_Oracle_Quantum_Program_Article/blob/master/qolumbina/programs/LessThan.qs
# 
# In detail, the raw program is written in Q#, and we rewrite it in Qiskit.

from qiskit import QuantumCircuit

# ---------- benchmark registration ----------
from ..benchmark_registry import register_benchmark
from pathlib import Path
@register_benchmark(
    Path(__file__).stem,
    family=Path(__file__).resolve().parent.name,
    description="Less-than comparator oracle (phase version)",
    class_name="LessThanPhase",
    source={
        "repo": "https://github.com/MgcosA/Code_of_Testing_Oracle_Quantum_Program_Article/blob/master/",
        "file": "qolumbina/programs/LessThan.qs",
        "language": "Q#",
        "available_doc": True
    },
    testability_refactoring=[
        "Cross-language translation", 
        "Structure reorganization",
        "Input validation"
    ] 
)
def create_less_than_phase(
    input_qubits: int, 
    integer: int,
    name: str | None = None
):
    return LessThanPhase(input_qubits=input_qubits, integer=integer, name=name)


[docs] class LessThanPhase(QuantumCircuit): r""" Less-than comparator oracle (phase version). Acts on :math:`n` qubits and applies a phase flip when :math:`x < m`. """ def __init__(self, input_qubits: int, integer: int, name: str | None = None): r""" Args: input_qubits: The number of input qubits for comparison, i.e., :math:`n`. integer: The integer :math:`k` to compare with, should be in the range of :math:`[0, 2^n)`. name: The name of the circuit. Raises: ValueError: If ``integer`` is negative or not less than :math:`2^n`. """ if integer < 0 or integer >= 2 ** input_qubits: raise ValueError("integer must be in [0, 2**input_qubits)") super().__init__(input_qubits, name=name or "LessThanPhase") self._input_integer = integer self._input_qubits = input_qubits self._build() # ---------- utilities ---------- @staticmethod def _int_as_bool_array(m: int, n: int) -> list[bool]: return [(m >> i) & 1 == 1 for i in range(n)] # ---------- build ---------- def _build(self) -> None: qs = self.qubits n = len(qs) mb = self._int_as_bool_array(self._input_integer, n) # The raw code in the Q# version is only self.x(qs[n - 1]), which could contain a bug. # highest bit if mb[n - 1]: self.x(qs[n - 1]) self.z(qs[n - 1]) self.x(qs[n - 1]) else: self.x(qs[n - 1]) for i in reversed(range(n - 1)): if mb[i]: self.x(qs[i]) # emulate MCZ via H-MCX-H self.h(qs[i]) self.mcx(qs[i + 1 : n], qs[i]) self.h(qs[i]) self.x(qs[i]) else: self.x(qs[i]) for i in range(n): if not mb[i]: self.x(qs[i])