bernstein-vazirani.rs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //! # Bernstein-Vazirani Algorithm
  2. //!
  3. //! This algorithm finds a hidden integer $a \in \{ 0, 1\}^n$ from
  4. //! an oracle $f_a$ which returns a bit $a \cdot x \equiv \sum_i a_i x_i \mod 2$
  5. //! for an input $x \in \{0,1\}^n$.
  6. //!
  7. //! A classical oracle returns $f_a(x) = a \dot x \mod 2$, while the quantum oracle
  8. //! must be queried with superpositions of input $x$'s.
  9. //!
  10. //! To solve this problem classically, the hidden integer can be found by checking the
  11. //! oracle with the inputs $x = 1,2,/dots,2^i,2^{n-1}$, where each
  12. //! query reveals the $i$th bit of $a$ ($a_i$).
  13. //! This is the optimal classical solution, and is O(n). Using a quantum oracle and the
  14. //! Bernstein-Vazirani algorithm, $a$ can be found with just one query to the oracle.
  15. //!
  16. //! ## The Algorithm
  17. //!
  18. //! 1. Initialize $n$ qubits in the state $\lvert 0, \dots, 0\rangle$.
  19. //! 2. Apply the Hadamard gate $H$ to each qubit.
  20. //! 3. Apply the inner product oracle.
  21. //! 4. Apply the Hadamard gate $H$ to each qubit.
  22. //! 5. Measure the register
  23. //!
  24. //! From this procedure, we find that the registers measured value is equal to that of
  25. //! the original hidden integer.
  26. extern crate qcgpu;
  27. use qcgpu::Simulator;
  28. use qcgpu::gate::h;
  29. fn main() {
  30. let num_qubits = 16; // Number of qubits to use
  31. let a = 101; // Hidden integer, bitstring is 1100101
  32. // You should also make sure that a is representable with $n$ qubits,
  33. // by settings a as $a mod 2^n$.
  34. // Bernstein-Vazirani algorithm
  35. let mut state = Simulator::new_opencl(num_qubits); // New quantum register, using the GPU.
  36. // Apply a hadamard gate to each qubit
  37. state.apply_all(h());
  38. // Apply the inner products oracle
  39. for i in 0..num_qubits {
  40. if a & (1 << i) != 0 {
  41. state.z(i);
  42. }
  43. // Otherwise should apply identity gate, but computationally this doens't change the state.
  44. }
  45. // Apply hadamard gates before measuring
  46. state.apply_all(h());
  47. println!("Measurement Results: {:?}", state.measure_many(1000));
  48. // Measurement Results: {"0000000001100101": 1000}
  49. }