//! # Bernstein-Vazirani Algorithm //! //! This algorithm finds a hidden integer $a \in \{ 0, 1\}^n$ from //! an oracle $f_a$ which returns a bit $a \cdot x \equiv \sum_i a_i x_i \mod 2$ //! for an input $x \in \{0,1\}^n$. //! //! A classical oracle returns $f_a(x) = a \dot x \mod 2$, while the quantum oracle //! must be queried with superpositions of input $x$'s. //! //! To solve this problem classically, the hidden integer can be found by checking the //! oracle with the inputs $x = 1,2,/dots,2^i,2^{n-1}$, where each //! query reveals the $i$th bit of $a$ ($a_i$). //! This is the optimal classical solution, and is O(n). Using a quantum oracle and the //! Bernstein-Vazirani algorithm, $a$ can be found with just one query to the oracle. //! //! ## The Algorithm //! //! 1. Initialize $n$ qubits in the state $\lvert 0, \dots, 0\rangle$. //! 2. Apply the Hadamard gate $H$ to each qubit. //! 3. Apply the inner product oracle. //! 4. Apply the Hadamard gate $H$ to each qubit. //! 5. Measure the register //! //! From this procedure, we find that the registers measured value is equal to that of //! the original hidden integer. extern crate qcgpu; use qcgpu::Simulator; use qcgpu::gate::h; fn main() { let num_qubits = 16; // Number of qubits to use let a = 101; // Hidden integer, bitstring is 1100101 // You should also make sure that a is representable with $n$ qubits, // by settings a as $a mod 2^n$. // Bernstein-Vazirani algorithm let mut state = Simulator::new_opencl(num_qubits); // New quantum register, using the GPU. // Apply a hadamard gate to each qubit state.apply_all(h()); // Apply the inner products oracle for i in 0..num_qubits { if a & (1 << i) != 0 { state.z(i); } // Otherwise should apply identity gate, but computationally this doens't change the state. } // Apply hadamard gates before measuring state.apply_all(h()); println!("Measurement Results: {:?}", state.measure_many(1000)); // Measurement Results: {"0000000001100101": 1000} }