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
62
63
64
65
66
use crate::errors::CircuitError;
use crate::{OpBuilder, Register, UnitaryBuilder};
pub fn work_on<F>(
b: &mut dyn UnitaryBuilder,
r: Register,
indices: &[u64],
f: F,
) -> Result<Register, CircuitError>
where
F: Fn(&mut dyn UnitaryBuilder, Vec<Register>) -> Result<Vec<Register>, CircuitError>,
{
let (selected, remaining) = b.split(r, indices)?;
let qs = b.split_all(selected);
let qs = f(b, qs)?;
if qs.len() != indices.len() {
CircuitError::make_err(format!(
"Output number of qubits from function ({}) did not match number of indices ({}).",
qs.len(),
indices.len()
))
} else {
b.merge_with_indices(remaining, qs, indices)
}
}
pub fn epr_pair(b: &mut OpBuilder, n: u64) -> (Register, Register) {
let m = 2 * n;
let r = b.r(1);
let rs = b.r(m - 1);
let r = b.hadamard(r);
let (r, rs) = b.cnot(r, rs);
let mut all_rs = vec![r];
all_rs.extend(b.split_all(rs));
let back_rs = all_rs.split_off(n as usize);
let ra = b.merge(all_rs).unwrap();
let rb = b.merge(back_rs).unwrap();
(ra, rb)
}
#[cfg(test)]
mod common_circuit_tests {
use super::*;
use crate::run_debug;
#[test]
fn test_work_on() -> Result<(), CircuitError> {
let mut b = OpBuilder::new();
let r = b.register(3)?;
let r_indices = r.indices.clone();
let r = work_on(&mut b, r, &[0], |_b, qs| Ok(qs))?;
run_debug(&r)?;
assert_eq!(r_indices, r.indices);
Ok(())
}
}