rustiq_core/structures/
graph_state.rs1use super::pauli_like::PauliLike;
3use rand::Rng;
4
5#[derive(Clone, Debug)]
6pub struct GraphState {
7 pub adj: Vec<Vec<bool>>,
8 pub n: usize,
9}
10
11impl GraphState {
12 pub fn new(n: usize) -> Self {
13 Self {
14 adj: vec![vec![false; n]; n],
15 n,
16 }
17 }
18 pub fn random(n: usize) -> Self {
19 let mut rng = rand::thread_rng();
20 let mut gs = Self::new(n);
21 for i in 0..n {
22 for j in i..n {
23 let entry = rng.gen::<bool>();
24 gs.adj[i][j] = entry;
25 gs.adj[j][i] = entry;
26 }
27 }
28 gs
29 }
30 pub fn from_adj(adj: Vec<Vec<bool>>) -> Self {
31 let n = adj.len();
32 for row in adj.iter() {
33 assert_eq!(row.len(), n, "Matrix is not square");
34 }
35 for i in 0..n {
36 for j in 0..n {
37 assert_eq!(adj[i][j], adj[j][i], "Matrix is not symmetric");
38 }
39 }
40 Self { adj, n }
41 }
42 pub fn count_ones(&self) -> usize {
43 self.adj
44 .iter()
45 .map(|row| row.iter().filter(|a| **a).count())
46 .sum::<usize>()
47 }
48}
49impl PauliLike for GraphState {
50 fn h(&mut self, _: usize) {
51 panic!("You are not supposed to apply H to a graph state!");
52 }
53
54 fn s(&mut self, i: usize) {
55 self.adj[i][i] ^= true;
56 }
57
58 fn sd(&mut self, i: usize) {
59 self.adj[i][i] ^= true;
60 }
61
62 fn sqrt_x(&mut self, _: usize) {
63 panic!("You are not supposed to apply SQRT_X to a graph state!");
64 }
65
66 fn sqrt_xd(&mut self, _: usize) {
67 panic!("You are not supposed to apply SQRT_XD to a graph state!");
68 }
69
70 fn cnot(&mut self, i: usize, j: usize) {
71 for k in 0..self.n {
72 self.adj[i][k] ^= self.adj[j][k];
73 }
74 for k in 0..self.n {
75 self.adj[k][i] ^= self.adj[k][j];
76 }
77 }
78
79 fn cz(&mut self, i: usize, j: usize) {
80 self.adj[i][j] ^= true;
81 self.adj[j][i] ^= true;
82 }
83}