Bernstein-Vazirani
Cirq implementation of Bernstein-Vazirani
Last updated
Cirq implementation of Bernstein-Vazirani
Last updated
#@title Bernstein-Vazirani Algorithm Simulator
## Imports
import numpy as np
import cirq
import random
class BV(object):
def __init__(self, bitstring_length=8, repetitions=10):
self.repetitions = repetitions
self.num_qubits = bitstring_length + 1
# Choose qubits to use.
self.input_qubits = [cirq.GridQubit(i, 0) for i in range(self.num_qubits)]
self.output_qubit = cirq.GridQubit(self.num_qubits, 0)
def make_oracle(self, input_qubits, output_qubit,
secret_bitstring=None, secret_bias_bit=None):
"""Gates implementing the function f(a) = a·string + bias (mod 2)."""
if secret_bias_bit:
yield cirq.X(self.output_qubit)
for qubit, bit in zip(self.input_qubits, secret_bitstring):
if bit:
yield cirq.CNOT(qubit, self.output_qubit)
def make_bernstein_vazirani_circuit(self, 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 run_bernstein_vazirani_simulation(self, secret_bitstring=None,
secret_bias_bit=None):
# Embed the oracle into a special quantum circuit querying it exactly once.
if not secret_bias_bit:
secret_bias_bit = random.randint(0, 1)
if not secret_bitstring:
secret_bitstring = [random.randint(0, 1)
for _ in range(self.num_qubits)]
oracle = self.make_oracle(self.input_qubits, self.output_qubit,
secret_bitstring, secret_bias_bit)
circuit = self.make_bernstein_vazirani_circuit(self.input_qubits,
self.output_qubit, oracle)
print('######### Printing Circuit ##########')
print(circuit)
# Sample from the circuit a couple times.
simulator = cirq.Simulator()
result = simulator.run(circuit, repetitions=self.repetitions)
frequencies = result.histogram(key='result', fold_func=bitstring)
print('######### Printing Results ##########')
print(f"Targeted secret string: {''.join(map(str, secret_bitstring))}",
"||", "% of measurements")
for k, v in frequencies.items():
print(f"Measured secret string: {k}", "||", v*100/self.repetitions)
def bitstring(bits):
return ''.join(str(int(b)) for b in bits)
dsim = BV(bitstring_length=5)
dsim.run_bernstein_vazirani_simulation()