Source code for qolumbina.programs.bernstein_vazirani.bv

# This code is refactored by the Jupyter Notebook from
# https://github.com/Qiskit/textbook/blob/main/notebooks/ch-algorithms/bernstein-vazirani.ipynb
#
# The corresponding repository is
# https://github.com/Qiskit/textbook?tab=Apache-2.0-1-ov-file
#
# This program is adapted for use as a benchmark in controlled software testing experiments.
# Modifications made to the original code include (for Apache License 2.0):
# - Refactored to unify the inherent class as QuantumCircuit:
# - Exposed unified program interfaces.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

from qiskit import QuantumCircuit, QuantumRegister 

# ---------- benchmark registration ----------
from ..benchmark_registry import register_benchmark
from pathlib import Path
@register_benchmark(
    Path(__file__).stem,
    family=Path(__file__).resolve().parent.name,
    description="Bernstein-Vazirani algorithm: Find a hidden binary string with a single oracle query.",
    class_name="BernsteinVazirani",
    source={
        "repo": "https://github.com/Qiskit/textbook?tab=Apache-2.0-1-ov-file",
        "file": "notebooks/ch-algorithms/bernstein-vazirani.ipynb",
        "sdk": "Qiskit",
        "available_doc": True
    },
    testability_refactoring=[
        "Structure reorganization"
    ],
)
def create_bv_circuit(
    secret: str, 
    insert_barriers: bool = False, 
    name: str | None = None
):
    return BernsteinVazirani(
        secret=secret, 
        insert_barriers=insert_barriers, 
        name=name
    )


[docs] class BernsteinVazirani(QuantumCircuit): r""" Bernstein-Vazirani algorithm circuit. Acts on :math:`n` input qubits and 1 auxiliary qubit """ def __init__(self, secret: str, insert_barriers: bool = False, name: str | None = None): """ Args: secret: The hidden binary string :math:`s`. insert_barriers: Whether to insert barriers in the circuit. name: Optional name for the circuit. Raises: ValueError: If ``secret`` is empty or contains characters other than ``'0'`` and ``'1'``. """ if not secret or any(c not in "01" for c in secret): raise ValueError("secret must be a non-empty binary string") self._secret = secret self._n = len(secret) self._insert_barriers = insert_barriers # ---------- registers ---------- q_input = QuantumRegister(self._n, "q") q_aux = QuantumRegister(1, "aux") super().__init__(q_input, q_aux, name=name or "BV") self._build() # ---------- build ---------- def _build(self) -> None: n = self._n # put auxiliary in state |-> self.h(n) self.z(n) # Apply Hadamard gates before querying the oracle for i in range(n): self.h(i) # Apply barrier if self._insert_barriers: self.barrier() # Apply the inner-product oracle s = self._secret[::-1] # reverse s to fit qiskit's qubit ordering for q in range(n): if s[q] == '0': self.id(q) else: self.cx(q, n) # Apply barrier if self._insert_barriers: self.barrier() # Apply Hadamard gates after querying the oracle for i in range(n): self.h(i)