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)