-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbernstein_vazirani.rs
61 lines (49 loc) · 1.54 KB
/
bernstein_vazirani.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use peroxide::fuga::*;
use qip::prelude::*;
use quantum_algorithm::apply_if;
use seq_macro::seq;
use std::result::Result;
const N: usize = 20usize;
macro_rules! bernstein_vazirani {
($l:ident) => {{
let a = $l.qubit();
let a = $l.x(a);
let a = $l.h(a);
seq!(Q in 0..20usize {
let q~Q = $l.qubit();
let q~Q = $l.h(q~Q);
});
let b = Uniform(1i32, 2i32.pow(N as u32)-1).sample(1)[0] as usize;
let b_str = format!("{:0width$b}", b, width = N);
let b_chars = b_str.chars().collect::<Vec<char>>();
// Oracle
let q = {
seq!(Q in 0..20 {
#[allow(unused_variables)]
let (q~Q, a) = apply_if!(b_chars[Q] == '1', $l.cnot(q~Q, a)?, (q~Q, a));
});
let mut q = vec![];
seq!(Q in 0..20usize {
q.push(q~Q);
});
$l.merge_registers(q).unwrap()
};
let q = $l.h(q);
(q, b_str)
}};
}
fn main() -> Result<(), CircuitError> {
let mut l = LocalBuilder::<f64>::default();
let (q, b_str) = bernstein_vazirani!(l);
let (_, handle) = l.measure(q);
let (_, measured) = l.calculate_state();
let (result, p) = measured.get_measurement(handle);
// Reversing result (little-endian)
let result = format!("{:0width$b}", result, width = N)
.chars()
.rev()
.collect::<String>();
println!("Measured: {} with probability {:.4}", result, p,);
println!("Expected: {}", b_str);
Ok(())
}