Source code for qolumbina.programs.hamiltonian.adder_hamiltonian_mixture

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

from qiskit import QuantumCircuit, QuantumRegister
from ..quantum_adder import DraperAdder
from . import DiagonalZHamiltonian

# ---------- benchmark registration ----------
from ..benchmark_registry import register_benchmark
from pathlib import Path
@register_benchmark(
    Path(__file__).stem,
    family=Path(__file__).resolve().parent.name,
    description="Adder + Hamiltonian mixture",
    class_name="AdderHamiltonianMixture",
    source={
        "repo": "https://github.com/MgcosA/Code_of_Testing_Oracle_Quantum_Program_Article/blob/master/",
        "file": "qolumbina/programs/MixedProc.qs",
        "sdk": "Q#",
        "available_doc": True
    },
    testability_refactoring=[
        "Cross-language translation", 
        "Structure reorganization",
        "Input validation"  # Ensure $n$ and $t$ are positive
    ] 
)
def create_adder_hamiltonian_mixture(num_qubits, t):
    return AdderHamiltonianMixture(input_qubits=num_qubits, t=t)

[docs] class AdderHamiltonianMixture(QuantumCircuit): r""" Mixture of Draper Adder and Hamiltonian evolution for position operator. """ def __init__(self, input_qubits: int, t: float, name: str | None = None): r""" Args: input_qubits: Number of qubits in each register, i.e., :math:`n` for both addends :math:`\ket{x}_n` and :math:`\ket{y}_n`. t: Evolution time :math:`t` (:math:`t > 0`). name: Optional name for the circuit. Raises: ValueError: If ``t`` is negative. """ if t < 0: raise ValueError("t must be positive") # ---------- registers ---------- qx = QuantumRegister(input_qubits, "x") qy = QuantumRegister(input_qubits, "y") # qy is more significant than qx # little-endian ordering: |y_(n-1) ... y_1 y_0>|x_(n-1) ... x_1 x_0> super().__init__(qx, qy, name=name or "AdderHamiltonianMixture") self._input_qubits = input_qubits self._evolution_time = t self._x_register = qx self._y_register = qy self._build() def _build(self) -> None: n = self._input_qubits t = self._evolution_time # Apply HamiltonianX on |y> register (the first n qubits) # -> HamiltonX(t, qy) hamiltonian_circuit = DiagonalZHamiltonian(input_qubits=n, t=t) self.compose(hamiltonian_circuit, qubits=self._y_register, inplace=True) # Apply QuantumAdder on all 2n qubits, with |y> as the more significant register # -> QAdder(qx, qy) adder_circuit = DraperAdder(input_qubits=n) self.compose(adder_circuit, qubits=[self._x_register[i] for i in range(n)] + [self._y_register[i] for i in range(n)], inplace=True)