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)