Skip to main content

willard/
gate.rs

1use crate::Qubit;
2use num::complex::Complex;
3
4pub fn x(qubit: &mut Qubit) {
5    not(qubit);
6}
7
8pub fn y(qubit: &mut Qubit) {
9    let mat = [[Complex::new(0.0, 0.0), Complex::new(0.0, -1.0)],
10	       [Complex::new(0.0, 1.0), Complex::new(0.0, 0.0)]];
11    let mut state: (Complex<f32>, Complex<f32>)= (Complex::new(0.0, 0.0), Complex::new(0.0, 0.0));
12
13    state.0 = mat[0][0] * qubit.state.0 + mat[0][1] * qubit.state.1;
14    state.1 = mat[1][0] * qubit.state.0 + mat[1][1] * qubit.state.1;
15
16    qubit.state = normalize_phase(state);
17}
18
19pub fn z(qubit: &mut Qubit) {
20    phase(qubit, std::f32::consts::PI);
21}
22
23pub fn phase(qubit: &mut Qubit, deg: f32) {
24    let mat = [[Complex::new(1.0, 0.0), Complex::new(0.0, 0.0)],
25	       [Complex::new(0.0, 0.0), Complex::new(deg.cos(), deg.sin())]];
26    let mut state: (Complex<f32>, Complex<f32>)= (Complex::new(0.0, 0.0), Complex::new(0.0, 0.0));
27
28    state.0 = mat[0][0] * qubit.state.0 + mat[0][1] * qubit.state.1;
29    state.1 = mat[1][0] * qubit.state.0 + mat[1][1] * qubit.state.1;
30
31    qubit.state = normalize_phase(state);
32}
33
34pub fn not(qubit: &mut Qubit) {
35    let state = qubit.state;
36    qubit.state = (state.1.re, Complex::new(state.0, -state.1.im));
37}
38
39pub fn h(qubit: &mut Qubit) {
40    let root_two = (2.0 as f32).sqrt();
41    let mat = [[1.0 / root_two, 1.0 / root_two],
42		[1.0 / root_two, -1.0 / root_two]];
43    let mut state: (Complex<f32>, Complex<f32>)= (Complex::new(0.0, 0.0), Complex::new(0.0, 0.0));
44
45    state.0 = mat[0][0] * qubit.state.0 + mat[0][1] * qubit.state.1;
46    state.1 = mat[1][0] * qubit.state.0 + mat[1][1] * qubit.state.1;
47
48    qubit.state = normalize_phase(state);
49}
50
51pub fn sqrt_not(qubit: &mut Qubit) {
52    let mat = [[Complex::new(1.0, 1.0) / 2.0, Complex::new(1.0, -1.0) / 2.0],
53	       [Complex::new(1.0, -1.0) / 2.0, Complex::new(1.0, 1.0) / 2.0]];
54    let mut state: (Complex<f32>, Complex<f32>)= (Complex::new(0.0, 0.0), Complex::new(0.0, 0.0));
55
56    state.0 = mat[0][0] * qubit.state.0 + mat[0][1] * qubit.state.1;
57    state.1 = mat[1][0] * qubit.state.0 + mat[1][1] * qubit.state.1;
58
59    qubit.state = normalize_phase(state);
60}
61
62fn normalize_phase(state: (Complex<f32>, Complex<f32>)) -> (f32, Complex<f32>) {
63    if (state.0 == Complex{re: 0.0, im: 0.0}) {
64	return (0.0, Complex::new(1.0, 0.0));
65    }
66
67    let size = (state.0.conj() * state.0).re.sqrt();
68    let d_phase = (state.0 / size).conj();
69
70    let l = (d_phase * state.0).re;
71    let r = d_phase * state.1;
72    (l, r)
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78    use num::complex::Complex;
79
80    #[test]
81    fn test_x() {
82	let mut qubit = Qubit::default();
83	x(&mut qubit);
84	assert_eq!(qubit.state, (0.0, Complex{re: 1.0, im: 0.0}));
85    }
86
87    #[test]
88    fn test_y() {
89	let mut qubit0 = Qubit::default();
90	y(&mut qubit0);
91	assert_eq!(qubit0.state, (0.0, Complex{re: 1.0, im: 0.0}));
92
93	let mut qubit1 = Qubit::default();
94	x(&mut qubit1);
95	y(&mut qubit1);
96	assert_eq!(qubit1.state, (1.0, Complex{re: 0.0, im: 0.0}));
97    }
98
99    #[test]
100    fn test_z() {
101	let mut qubit0 = Qubit::default();
102	z(&mut qubit0);
103	assert_eq!(qubit0.state, (1.0, Complex{re: 0.0, im: 0.0}));
104
105	let mut qubit1 = Qubit::default();
106	x(&mut qubit1);
107	z(&mut qubit1);
108	assert_eq!(qubit1.state, (0.0, Complex{re: 1.0, im: 0.0}));
109    }
110
111    #[test]
112    fn test_not() {
113	let mut qubit = Qubit::default();
114	not(&mut qubit);
115	assert_eq!(qubit.state, (0.0, Complex{re: 1.0, im: 0.0}));
116    }
117
118    #[test]
119    fn test_h() {
120	// Test on a qubit of state [1.0, 0.0]
121	let mut qubit0 = Qubit::default();
122
123	h(&mut qubit0);
124
125	let root_two = (2.0 as f32).sqrt();
126
127	let got = qubit0.state;
128	let want = (1.0 / root_two, Complex{re: 1.0 / root_two, im: 0.0});
129
130	assert_eq!(got, want);
131
132	// Test on a qubit of state [0.0, 1.0]
133	let mut qubit1 = Qubit::default();
134	not(&mut qubit1);
135
136	h(&mut qubit1);
137
138	let got = qubit1.state;
139	let want = (1.0 / root_two, Complex{re: -1.0 / root_two, im: 0.0});
140
141	assert_eq!(got, want);
142    }
143
144    #[test]
145    fn test_sqrt_not() {
146	let mut qubit = Qubit::default();
147
148	sqrt_not(&mut qubit);
149
150	sqrt_not(&mut qubit);
151	let mut other_qubit = Qubit::default();
152	not(&mut other_qubit);
153
154	let got = qubit.state;
155	let want = other_qubit.state;
156
157	assert_eq!(got, want);
158    }
159
160    #[test]
161    fn test_normalize_phase() {
162	let state = (Complex::new(0.0, -1.0), Complex::new(1.0, 0.0));
163	let got = normalize_phase(state);
164	let want = (1.0, Complex::new(0.0, 1.0));
165	assert_eq!(got, want);
166    }
167}
168