Jump to content

Bernstein–Vazirani algorithm

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Vtomole (talk | contribs) at 02:27, 1 July 2019 (Create Bernstein-Vazirani Wikipedia page). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

The Bernstein-Vazirani algorithm is a quantum algorithm invented by Ethan Bernstein and Umesh Vazirani in 1992[1] . It's a restricted version of the Deutsch–Jozsa algorithm where instead of distinguishing between two different classes of functions, it tries to learn a string encoded in a function.[2] The Bernstein-Vazirani algorithm was designed to prove an oracle separation between complexity classes BQP and BPP.[1]

Problem statement

Given an oracle that implements some function , It's promised that the function is a dot product between and a secret string modulo 2. , find .

Algorithm

Classically, the most efficient method to find the secret string is by evaluating the function on each input of Hamming weight 1. [3]

In contrast to the classical solution which needs at least queries of the function to find , only one query is needed quantumly. The quantum algorithm is as follows: [3]

Apply a Hadamard transform to the qubit state to get

.

Applying the oracle to the state that was generated by the previous Hadamard transform turns the state into

.

Another Hadamard transform is applied to each qubit which makes it so that for qubits where , its state is converted from to and for qubits where , its state is converted from to .

To obtain , a measurement on the Standard basis () is performed on the qubits.

Implementation

An implementation of the Bernstein-Vazirani algorithm in Cirq.[4]

"""Demonstrates the Bernstein-Vazirani algorithm.

The (non-recursive) Bernstein-Vazirani algorithm takes a black-box oracle
implementing a function f(a) = a·factors + bias (mod 2), where 'bias' is 0 or 1,
'a' and 'factors' are vectors with all elements equal to 0 or 1, and the
algorithm solves for 'factors' in a single query to the oracle.

=== REFERENCE ===

Bernstein, Ethan, and Umesh Vazirani. "Quantum complexity theory."
SIAM Journal on Computing 26.5 (1997): 1411-1473.

=== EXAMPLE OUTPUT ===

Secret function:
f(a) = a·<0, 1, 1, 1, 0, 0, 1, 0> + 1 (mod 2)
Circuit:
(0, 0): ───────H───────────────────────H───M───

(1, 0): ───────H───────@───────────────H───M───
                       │                   │
(2, 0): ───────H───────┼───@───────────H───M───
                       │   │               │
(3, 0): ───────H───────┼───┼───@───────H───M───
                       │   │   │           │
(4, 0): ───────H───────┼───┼───┼───────H───M───
                       │   │   │           │
(5, 0): ───────H───────┼───┼───┼───────H───M───
                       │   │   │           │
(6, 0): ───────H───────┼───┼───┼───@───H───M───
                       │   │   │   │       │
(7, 0): ───────H───────┼───┼───┼───┼───H───M───
                       │   │   │   │
(8, 0): ───X───H───X───X───X───X───X───────────
Sampled results:
Counter({'01110010': 3})
Most common matches secret factors:
True
"""

import random

import cirq


def main(qubit_count = 8):
    circuit_sample_count = 3

    # Choose qubits to use.
    input_qubits = [cirq.GridQubit(i, 0) for i in range(qubit_count)]
    output_qubit = cirq.GridQubit(qubit_count, 0)

    # Pick coefficients for the oracle and create a circuit to query it.
    secret_bias_bit = random.randint(0, 1)
    secret_factor_bits = [random.randint(0, 1) for _ in range(qubit_count)]
    oracle = make_oracle(input_qubits,
                         output_qubit,
                         secret_factor_bits,
                         secret_bias_bit)
    print('Secret function:\nf(a) = a·<{}> + {} (mod 2)'.format(
        ', '.join(str(e) for e in secret_factor_bits),
        secret_bias_bit))

    # Embed the oracle into a special quantum circuit querying it exactly once.
    circuit = make_bernstein_vazirani_circuit(
        input_qubits, output_qubit, oracle)
    print('Circuit:')
    print(circuit)

    # Sample from the circuit a couple times.
    simulator = cirq.Simulator()
    result = simulator.run(circuit, repetitions=circuit_sample_count)
    frequencies = result.histogram(key='result', fold_func=bitstring)
    print('Sampled results:\n{}'.format(frequencies))

    # Check if we actually found the secret value.
    most_common_bitstring = frequencies.most_common(1)[0][0]
    print('Most common matches secret factors:\n{}'.format(
        most_common_bitstring == bitstring(secret_factor_bits)))


def make_oracle(input_qubits,
                output_qubit,
                secret_factor_bits,
                secret_bias_bit):
    """Gates implementing the function f(a) = a·factors + bias (mod 2)."""

    if secret_bias_bit:
        yield cirq.X(output_qubit)

    for qubit, bit in zip(input_qubits, secret_factor_bits):
        if bit:
            yield cirq.CNOT(qubit, output_qubit)


def make_bernstein_vazirani_circuit(input_qubits, output_qubit, oracle):
    """Solves for factors in f(a) = a·factors + bias (mod 2) with one query."""

    c = cirq.Circuit()

    # Initialize qubits.
    c.append([
        cirq.X(output_qubit),
        cirq.H(output_qubit),
        cirq.H.on_each(*input_qubits),
    ])

    # Query oracle.
    c.append(oracle)

    # Measure in X basis.
    c.append([
        cirq.H.on_each(*input_qubits),
        cirq.measure(*input_qubits, key='result')
    ])

    return c


def bitstring(bits):
    return ''.join(str(int(b)) for b in bits)


if __name__ == '__main__':
    main()


References

  1. ^ a b Ethan Bernstein and Umesh Vazirani (1997). "Quantum Complexity Theory". SIAM Journal on Computing. 26 (5): 1411–1473. doi:10.1137/S0097539796300921.
  2. ^ Dieter van Melkebeek (September 2010). "Lecture 4: Elementary Quantum Algorithms" (PDF). Retrieved 2019-06-30.
  3. ^ a b Scott Aaronson (November 2018). "Lecture 18, Tues March 28: Bernstein-Vazirani, Simon" (PDF). Retrieved 2019-06-30.
  4. ^ The Cirq Developers. "Implementation of the Bernstein-Vazirani algorithm". Retrieved 2019-06-30.