1use super::ErrorCorrection;
7use crate::error::{Result, SimulatorError};
8use quantrs2_circuit::builder::Circuit;
9use quantrs2_core::qubit::QubitId;
10
11#[derive(Debug, Clone, Copy)]
16pub struct BitFlipCode;
17
18impl ErrorCorrection for BitFlipCode {
19 fn physical_qubits(&self) -> usize {
20 3
21 }
22
23 fn logical_qubits(&self) -> usize {
24 1
25 }
26
27 fn distance(&self) -> usize {
28 3
29 }
30
31 fn encode_circuit(
32 &self,
33 logical_qubits: &[QubitId],
34 ancilla_qubits: &[QubitId],
35 ) -> Result<Circuit<16>> {
36 let mut circuit = Circuit::<16>::new();
38
39 if logical_qubits.len() < 1 {
41 return Err(SimulatorError::InvalidInput(
42 "BitFlipCode requires at least 1 logical qubit".to_string(),
43 ));
44 }
45 if ancilla_qubits.len() < 2 {
46 return Err(SimulatorError::InvalidInput(
47 "BitFlipCode requires at least 2 ancilla qubits".to_string(),
48 ));
49 }
50
51 let q0 = logical_qubits[0];
53 let q1 = ancilla_qubits[0];
54 let q2 = ancilla_qubits[1];
55
56 circuit.cnot(q0, q1).unwrap();
59 circuit.cnot(q0, q2).unwrap();
60
61 Ok(circuit)
62 }
63
64 fn decode_circuit(
65 &self,
66 encoded_qubits: &[QubitId],
67 syndrome_qubits: &[QubitId],
68 ) -> Result<Circuit<16>> {
69 let mut circuit = Circuit::<16>::new();
70
71 if encoded_qubits.len() < 3 {
73 return Err(SimulatorError::InvalidInput(
74 "BitFlipCode requires at least 3 encoded qubits".to_string(),
75 ));
76 }
77 if syndrome_qubits.len() < 2 {
78 return Err(SimulatorError::InvalidInput(
79 "BitFlipCode requires at least 2 syndrome qubits".to_string(),
80 ));
81 }
82
83 let q0 = encoded_qubits[0];
85 let q1 = encoded_qubits[1];
86 let q2 = encoded_qubits[2];
87 let s0 = syndrome_qubits[0];
88 let s1 = syndrome_qubits[1];
89
90 circuit.cnot(q0, s0).unwrap();
92 circuit.cnot(q1, s0).unwrap();
93 circuit.cnot(q1, s1).unwrap();
94 circuit.cnot(q2, s1).unwrap();
95
96 circuit.x(s1).unwrap();
99 circuit.cx(s0, q0).unwrap();
100 circuit.x(s1).unwrap();
101
102 circuit.x(s0).unwrap();
104 circuit.cx(s1, q1).unwrap();
105 circuit.x(s0).unwrap();
106
107 circuit.cx(s0, q2).unwrap();
109 circuit.cx(s1, q2).unwrap();
110
111 Ok(circuit)
112 }
113}
114
115#[derive(Debug, Clone, Copy)]
120pub struct PhaseFlipCode;
121
122impl ErrorCorrection for PhaseFlipCode {
123 fn physical_qubits(&self) -> usize {
124 3
125 }
126
127 fn logical_qubits(&self) -> usize {
128 1
129 }
130
131 fn distance(&self) -> usize {
132 3
133 }
134
135 fn encode_circuit(
136 &self,
137 logical_qubits: &[QubitId],
138 ancilla_qubits: &[QubitId],
139 ) -> Result<Circuit<16>> {
140 let mut circuit = Circuit::<16>::new();
142
143 if logical_qubits.len() < 1 {
145 return Err(SimulatorError::InvalidInput(
146 "PhaseFlipCode requires at least 1 logical qubit".to_string(),
147 ));
148 }
149 if ancilla_qubits.len() < 2 {
150 return Err(SimulatorError::InvalidInput(
151 "PhaseFlipCode requires at least 2 ancilla qubits".to_string(),
152 ));
153 }
154
155 let q0 = logical_qubits[0];
157 let q1 = ancilla_qubits[0];
158 let q2 = ancilla_qubits[1];
159
160 circuit.h(q0).unwrap();
162 circuit.h(q1).unwrap();
163 circuit.h(q2).unwrap();
164
165 circuit.cnot(q0, q1).unwrap();
167 circuit.cnot(q0, q2).unwrap();
168
169 circuit.h(q0).unwrap();
171 circuit.h(q1).unwrap();
172 circuit.h(q2).unwrap();
173
174 Ok(circuit)
175 }
176
177 fn decode_circuit(
178 &self,
179 encoded_qubits: &[QubitId],
180 syndrome_qubits: &[QubitId],
181 ) -> Result<Circuit<16>> {
182 let mut circuit = Circuit::<16>::new();
183
184 if encoded_qubits.len() < 3 {
186 return Err(SimulatorError::InvalidInput(
187 "PhaseFlipCode requires at least 3 encoded qubits".to_string(),
188 ));
189 }
190 if syndrome_qubits.len() < 2 {
191 return Err(SimulatorError::InvalidInput(
192 "PhaseFlipCode requires at least 2 syndrome qubits".to_string(),
193 ));
194 }
195
196 let q0 = encoded_qubits[0];
198 let q1 = encoded_qubits[1];
199 let q2 = encoded_qubits[2];
200 let s0 = syndrome_qubits[0];
201 let s1 = syndrome_qubits[1];
202
203 circuit.h(q0).unwrap();
205 circuit.h(q1).unwrap();
206 circuit.h(q2).unwrap();
207
208 circuit.cnot(q0, s0).unwrap();
210 circuit.cnot(q1, s0).unwrap();
211 circuit.cnot(q1, s1).unwrap();
212 circuit.cnot(q2, s1).unwrap();
213
214 circuit.x(s1).unwrap();
217 circuit.cx(s0, q0).unwrap();
218 circuit.x(s1).unwrap();
219
220 circuit.x(s0).unwrap();
222 circuit.cx(s1, q1).unwrap();
223 circuit.x(s0).unwrap();
224
225 circuit.cx(s0, q2).unwrap();
227 circuit.cx(s1, q2).unwrap();
228
229 circuit.h(q0).unwrap();
231 circuit.h(q1).unwrap();
232 circuit.h(q2).unwrap();
233
234 Ok(circuit)
235 }
236}
237
238#[derive(Debug, Clone, Copy)]
244pub struct ShorCode;
245
246impl ErrorCorrection for ShorCode {
247 fn physical_qubits(&self) -> usize {
248 9
249 }
250
251 fn logical_qubits(&self) -> usize {
252 1
253 }
254
255 fn distance(&self) -> usize {
256 3
257 }
258
259 fn encode_circuit(
260 &self,
261 logical_qubits: &[QubitId],
262 ancilla_qubits: &[QubitId],
263 ) -> Result<Circuit<16>> {
264 let mut circuit = Circuit::<16>::new();
265
266 if logical_qubits.len() < 1 {
268 return Err(SimulatorError::InvalidInput(
269 "ShorCode requires at least 1 logical qubit".to_string(),
270 ));
271 }
272 if ancilla_qubits.len() < 8 {
273 return Err(SimulatorError::InvalidInput(
274 "ShorCode requires at least 8 ancilla qubits".to_string(),
275 ));
276 }
277
278 let q = logical_qubits[0]; let a = &ancilla_qubits[0..8]; circuit.h(q).unwrap();
285
286 circuit.cnot(q, a[0]).unwrap(); circuit.cnot(q, a[3]).unwrap(); circuit.cnot(q, a[1]).unwrap();
295 circuit.cnot(q, a[2]).unwrap();
296
297 circuit.cnot(a[3], a[4]).unwrap();
299 circuit.cnot(a[3], a[5]).unwrap();
300
301 circuit.cnot(q, a[6]).unwrap();
304 circuit.cnot(a[6], a[7]).unwrap();
305
306 Ok(circuit)
315 }
316
317 fn decode_circuit(
318 &self,
319 encoded_qubits: &[QubitId],
320 syndrome_qubits: &[QubitId],
321 ) -> Result<Circuit<16>> {
322 let mut circuit = Circuit::<16>::new();
323
324 if encoded_qubits.len() < 9 {
326 return Err(SimulatorError::InvalidInput(
327 "ShorCode requires at least 9 encoded qubits".to_string(),
328 ));
329 }
330 if syndrome_qubits.len() < 8 {
331 return Err(SimulatorError::InvalidInput(
332 "ShorCode requires at least 8 syndrome qubits".to_string(),
333 ));
334 }
335
336 let data = encoded_qubits;
338 let synd = syndrome_qubits;
339
340 circuit.cnot(data[0], synd[0]).unwrap();
344 circuit.cnot(data[1], synd[0]).unwrap();
345 circuit.cnot(data[1], synd[1]).unwrap();
346 circuit.cnot(data[2], synd[1]).unwrap();
347
348 circuit.cnot(data[3], synd[2]).unwrap();
350 circuit.cnot(data[4], synd[2]).unwrap();
351 circuit.cnot(data[4], synd[3]).unwrap();
352 circuit.cnot(data[5], synd[3]).unwrap();
353
354 circuit.cnot(data[6], synd[4]).unwrap();
356 circuit.cnot(data[7], synd[4]).unwrap();
357 circuit.cnot(data[7], synd[5]).unwrap();
358 circuit.cnot(data[8], synd[5]).unwrap();
359
360 circuit.x(synd[1]).unwrap();
365 circuit.cx(synd[0], data[0]).unwrap();
366 circuit.x(synd[1]).unwrap();
367
368 circuit.x(synd[0]).unwrap();
370 circuit.cx(synd[1], data[1]).unwrap();
371 circuit.x(synd[0]).unwrap();
372
373 circuit.cx(synd[0], data[2]).unwrap();
375 circuit.cx(synd[1], data[2]).unwrap();
376
377 circuit.x(synd[3]).unwrap();
380 circuit.cx(synd[2], data[3]).unwrap();
381 circuit.x(synd[3]).unwrap();
382
383 circuit.x(synd[2]).unwrap();
385 circuit.cx(synd[3], data[4]).unwrap();
386 circuit.x(synd[2]).unwrap();
387
388 circuit.cx(synd[2], data[5]).unwrap();
390 circuit.cx(synd[3], data[5]).unwrap();
391
392 circuit.x(synd[5]).unwrap();
395 circuit.cx(synd[4], data[6]).unwrap();
396 circuit.x(synd[5]).unwrap();
397
398 circuit.x(synd[4]).unwrap();
400 circuit.cx(synd[5], data[7]).unwrap();
401 circuit.x(synd[4]).unwrap();
402
403 circuit.cx(synd[4], data[8]).unwrap();
405 circuit.cx(synd[5], data[8]).unwrap();
406
407 for &q in &[data[0], data[3], data[6]] {
411 circuit.h(q).unwrap();
412 }
413
414 circuit.cnot(data[0], synd[6]).unwrap();
416 circuit.cnot(data[3], synd[6]).unwrap();
417 circuit.cnot(data[3], synd[7]).unwrap();
418 circuit.cnot(data[6], synd[7]).unwrap();
419
420 circuit.x(synd[7]).unwrap();
424 for &q in &[data[0], data[1], data[2]] {
425 circuit.cz(synd[6], q).unwrap();
426 }
427 circuit.x(synd[7]).unwrap();
428
429 circuit.x(synd[6]).unwrap();
431 for &q in &[data[3], data[4], data[5]] {
432 circuit.cz(synd[7], q).unwrap();
433 }
434 circuit.x(synd[6]).unwrap();
435
436 for &q in &[data[6], data[7], data[8]] {
438 circuit.cz(synd[6], q).unwrap();
439 circuit.cz(synd[7], q).unwrap();
440 }
441
442 for &q in &[data[0], data[3], data[6]] {
444 circuit.h(q).unwrap();
445 }
446
447 Ok(circuit)
448 }
449}
450
451#[derive(Debug, Clone, Copy)]
456pub struct FiveQubitCode;
457
458impl ErrorCorrection for FiveQubitCode {
459 fn physical_qubits(&self) -> usize {
460 5
461 }
462
463 fn logical_qubits(&self) -> usize {
464 1
465 }
466
467 fn distance(&self) -> usize {
468 3
469 }
470
471 fn encode_circuit(
472 &self,
473 logical_qubits: &[QubitId],
474 ancilla_qubits: &[QubitId],
475 ) -> Result<Circuit<16>> {
476 let mut circuit = Circuit::<16>::new();
477
478 if logical_qubits.len() < 1 {
480 return Err(SimulatorError::InvalidInput(
481 "FiveQubitCode requires at least 1 logical qubit".to_string(),
482 ));
483 }
484 if ancilla_qubits.len() < 4 {
485 return Err(SimulatorError::InvalidInput(
486 "FiveQubitCode requires at least 4 ancilla qubits".to_string(),
487 ));
488 }
489
490 let q0 = logical_qubits[0];
492 let ancs = ancilla_qubits;
493
494 circuit.h(ancs[0]).unwrap();
501 circuit.h(ancs[1]).unwrap();
502 circuit.h(ancs[2]).unwrap();
503 circuit.h(ancs[3]).unwrap();
504
505 circuit.cnot(q0, ancs[0]).unwrap();
508 circuit.cnot(q0, ancs[1]).unwrap();
509 circuit.cnot(q0, ancs[2]).unwrap();
510 circuit.cnot(q0, ancs[3]).unwrap();
511
512 circuit.h(q0).unwrap();
517 circuit.h(ancs[1]).unwrap();
518 circuit.h(ancs[3]).unwrap();
519
520 circuit.cnot(q0, ancs[0]).unwrap();
521 circuit.cnot(ancs[1], ancs[0]).unwrap();
522 circuit.cnot(ancs[0], ancs[2]).unwrap();
523 circuit.cnot(ancs[2], ancs[3]).unwrap();
524
525 circuit.cz(q0, ancs[1]).unwrap();
527 circuit.cz(ancs[0], ancs[2]).unwrap();
528 circuit.cz(ancs[1], ancs[3]).unwrap();
529
530 circuit.h(ancs[0]).unwrap();
531 circuit.h(ancs[2]).unwrap();
532
533 Ok(circuit)
537 }
538
539 fn decode_circuit(
540 &self,
541 encoded_qubits: &[QubitId],
542 syndrome_qubits: &[QubitId],
543 ) -> Result<Circuit<16>> {
544 let mut circuit = Circuit::<16>::new();
545
546 if encoded_qubits.len() < 5 {
548 return Err(SimulatorError::InvalidInput(
549 "FiveQubitCode requires at least 5 encoded qubits".to_string(),
550 ));
551 }
552 if syndrome_qubits.len() < 4 {
553 return Err(SimulatorError::InvalidInput(
554 "FiveQubitCode requires at least 4 syndrome qubits".to_string(),
555 ));
556 }
557
558 let data = encoded_qubits;
560 let synd = syndrome_qubits;
561
562 circuit.h(synd[0]).unwrap();
567 circuit.cnot(synd[0], data[0]).unwrap();
568 circuit.cz(synd[0], data[1]).unwrap();
569 circuit.cz(synd[0], data[2]).unwrap();
570 circuit.cnot(synd[0], data[3]).unwrap();
571 circuit.h(synd[0]).unwrap();
572
573 circuit.h(synd[1]).unwrap();
575 circuit.cnot(synd[1], data[1]).unwrap();
576 circuit.cz(synd[1], data[2]).unwrap();
577 circuit.cz(synd[1], data[3]).unwrap();
578 circuit.cnot(synd[1], data[4]).unwrap();
579 circuit.h(synd[1]).unwrap();
580
581 circuit.h(synd[2]).unwrap();
583 circuit.cnot(synd[2], data[0]).unwrap();
584 circuit.cnot(synd[2], data[2]).unwrap();
585 circuit.cz(synd[2], data[3]).unwrap();
586 circuit.cz(synd[2], data[4]).unwrap();
587 circuit.h(synd[2]).unwrap();
588
589 circuit.h(synd[3]).unwrap();
591 circuit.cz(synd[3], data[0]).unwrap();
592 circuit.cnot(synd[3], data[1]).unwrap();
593 circuit.cnot(synd[3], data[3]).unwrap();
594 circuit.cz(synd[3], data[4]).unwrap();
595 circuit.h(synd[3]).unwrap();
596
597 let syndrome_0001 = [false, false, false, true];
604 self.add_conditional_correction(&mut circuit, synd, syndrome_0001, data[0], 'X')?;
605
606 let syndrome_0010 = [false, false, true, false];
608 self.add_conditional_correction(&mut circuit, synd, syndrome_0010, data[1], 'X')?;
609
610 let syndrome_0100 = [false, true, false, false];
612 self.add_conditional_correction(&mut circuit, synd, syndrome_0100, data[2], 'X')?;
613
614 let syndrome_1000 = [true, false, false, false];
616 self.add_conditional_correction(&mut circuit, synd, syndrome_1000, data[3], 'X')?;
617
618 let syndrome_0011 = [false, false, true, true];
621 self.add_conditional_correction(&mut circuit, synd, syndrome_0011, data[0], 'Z')?;
622
623 let syndrome_0101 = [false, true, false, true];
625 self.add_conditional_correction(&mut circuit, synd, syndrome_0101, data[1], 'Z')?;
626
627 let syndrome_1001 = [true, false, false, true];
629 self.add_conditional_correction(&mut circuit, synd, syndrome_1001, data[2], 'Z')?;
630
631 let syndrome_1100 = [true, true, false, false];
633 self.add_conditional_correction(&mut circuit, synd, syndrome_1100, data[3], 'Z')?;
634
635 let syndrome_0111 = [false, true, true, true];
638 self.add_conditional_correction(&mut circuit, synd, syndrome_0111, data[0], 'Y')?;
639
640 let syndrome_1011 = [true, false, true, true];
642 self.add_conditional_correction(&mut circuit, synd, syndrome_1011, data[1], 'Y')?;
643
644 let syndrome_1101 = [true, true, false, true];
646 self.add_conditional_correction(&mut circuit, synd, syndrome_1101, data[2], 'Y')?;
647
648 let syndrome_1110 = [true, true, true, false];
650 self.add_conditional_correction(&mut circuit, synd, syndrome_1110, data[3], 'Y')?;
651
652 Ok(circuit)
653 }
654}
655
656impl FiveQubitCode {
657 fn add_conditional_correction(
659 &self,
660 circuit: &mut Circuit<16>,
661 syndrome_qubits: &[QubitId],
662 syndrome: [bool; 4],
663 target: QubitId,
664 error_type: char,
665 ) -> Result<()> {
666 for (i, &should_be_one) in syndrome.iter().enumerate() {
671 if !should_be_one {
672 circuit.x(syndrome_qubits[i]).unwrap();
673 }
674 }
675
676 for i in 1..syndrome_qubits.len() {
684 circuit.cx(syndrome_qubits[i], syndrome_qubits[0]).unwrap();
685 }
686
687 match error_type {
689 'X' => {
690 circuit.cx(syndrome_qubits[0], target).unwrap();
692 }
693 'Z' => {
694 circuit.cz(syndrome_qubits[0], target).unwrap();
696 }
697 'Y' => {
698 circuit.cz(syndrome_qubits[0], target).unwrap();
701 circuit.cx(syndrome_qubits[0], target).unwrap();
702 }
703 _ => {
704 return Err(SimulatorError::UnsupportedOperation(format!(
705 "Unsupported error type: {}",
706 error_type
707 )))
708 }
709 }
710
711 for i in 1..syndrome_qubits.len() {
713 circuit.cx(syndrome_qubits[i], syndrome_qubits[0]).unwrap();
714 }
715
716 for (i, &should_be_one) in syndrome.iter().enumerate() {
718 if !should_be_one {
719 circuit.x(syndrome_qubits[i]).unwrap();
720 }
721 }
722
723 Ok(())
724 }
725}