tnc/builders/
sycamore_circuit.rs1use std::f64::consts::{FRAC_PI_2, FRAC_PI_6};
4
5use rand::{seq::IndexedRandom, Rng};
6
7use crate::{
8 builders::{
9 circuit_builder::Circuit,
10 connectivity::{sycamore_a, sycamore_b, sycamore_c, sycamore_d},
11 },
12 tensornetwork::tensordata::TensorData,
13};
14
15pub fn sycamore_circuit<R>(qubits: usize, depth: usize, rng: &mut R) -> Circuit
23where
24 R: Rng,
25{
26 assert!(
28 qubits <= 49,
29 "Currently only supports circuits of size equal to the original Sycamore experiment"
30 );
31 let mut rounds = [
32 sycamore_a, sycamore_b, sycamore_c, sycamore_d, sycamore_c, sycamore_d, sycamore_a,
33 sycamore_b,
34 ]
35 .iter()
36 .cycle();
37 let single_qubit_gates = [
38 TensorData::Gate((String::from("sx"), Vec::new(), false)),
39 TensorData::Gate((String::from("sy"), Vec::new(), false)),
40 TensorData::Gate((String::from("sz"), Vec::new(), false)),
41 ];
42 let two_qubit_gate =
43 TensorData::Gate((String::from("fsim"), vec![FRAC_PI_2, FRAC_PI_6], false));
44
45 let mut circuit = Circuit::default();
47 let qreg = circuit.allocate_register(qubits);
48
49 for round in 0..=depth {
51 for i in 0..qubits {
53 let gate = single_qubit_gates.choose(rng).unwrap().clone();
54 circuit.append_gate(gate, &[qreg.qubit(i)]);
55 }
56
57 if round < depth {
59 let layer = rounds.next().unwrap()();
61 for (i, j) in layer {
62 if i > qubits || j > qubits {
63 continue;
64 }
65 let i = i - 1;
66 let j = j - 1;
67 circuit.append_gate(two_qubit_gate.clone(), &[qreg.qubit(i), qreg.qubit(j)]);
68 }
69 }
70 }
71 circuit
72}
73
74#[cfg(test)]
75mod tests {
76 use itertools::Itertools;
77 use rand::{rngs::StdRng, SeedableRng};
78
79 use super::*;
80
81 #[test]
82 fn small_sycamore() {
83 let mut rng = StdRng::seed_from_u64(42);
84 let circuit = sycamore_circuit(3, 3, &mut rng);
85 let (tn, _) = circuit.into_amplitude_network(&"0".repeat(3));
86
87 let rank_counts = tn.tensors().iter().counts_by(|t| t.legs().len());
88 assert_eq!(rank_counts.len(), 3);
89 assert_eq!(rank_counts[&1], 6);
91 assert_eq!(rank_counts[&2], 12);
93 assert_eq!(rank_counts[&4], 1);
95 }
96}