use super::ErrorCorrection;
use crate::error::{Result, SimulatorError};
use quantrs2_circuit::builder::Circuit;
use quantrs2_core::qubit::QubitId;
#[derive(Debug, Clone, Copy)]
pub struct BitFlipCode;
impl ErrorCorrection for BitFlipCode {
fn physical_qubits(&self) -> usize {
3
}
fn logical_qubits(&self) -> usize {
1
}
fn distance(&self) -> usize {
3
}
fn encode_circuit(
&self,
logical_qubits: &[QubitId],
ancilla_qubits: &[QubitId],
) -> Result<Circuit<16>> {
let mut circuit = Circuit::<16>::new();
if logical_qubits.is_empty() {
return Err(SimulatorError::InvalidInput(
"BitFlipCode requires at least 1 logical qubit".to_string(),
));
}
if ancilla_qubits.len() < 2 {
return Err(SimulatorError::InvalidInput(
"BitFlipCode requires at least 2 ancilla qubits".to_string(),
));
}
let q0 = logical_qubits[0];
let q1 = ancilla_qubits[0];
let q2 = ancilla_qubits[1];
circuit.cnot(q0, q1).expect(
"Failed to apply CNOT from logical qubit to first ancilla in BitFlipCode encoding",
);
circuit.cnot(q0, q2).expect(
"Failed to apply CNOT from logical qubit to second ancilla in BitFlipCode encoding",
);
Ok(circuit)
}
fn decode_circuit(
&self,
encoded_qubits: &[QubitId],
syndrome_qubits: &[QubitId],
) -> Result<Circuit<16>> {
let mut circuit = Circuit::<16>::new();
if encoded_qubits.len() < 3 {
return Err(SimulatorError::InvalidInput(
"BitFlipCode requires at least 3 encoded qubits".to_string(),
));
}
if syndrome_qubits.len() < 2 {
return Err(SimulatorError::InvalidInput(
"BitFlipCode requires at least 2 syndrome qubits".to_string(),
));
}
let q0 = encoded_qubits[0];
let q1 = encoded_qubits[1];
let q2 = encoded_qubits[2];
let s0 = syndrome_qubits[0];
let s1 = syndrome_qubits[1];
circuit
.cnot(q0, s0)
.expect("Failed to apply CNOT from q0 to s0 in BitFlipCode syndrome extraction");
circuit
.cnot(q1, s0)
.expect("Failed to apply CNOT from q1 to s0 in BitFlipCode syndrome extraction");
circuit
.cnot(q1, s1)
.expect("Failed to apply CNOT from q1 to s1 in BitFlipCode syndrome extraction");
circuit
.cnot(q2, s1)
.expect("Failed to apply CNOT from q2 to s1 in BitFlipCode syndrome extraction");
circuit
.x(s1)
.expect("Failed to apply X to s1 before syndrome 01 correction in BitFlipCode");
circuit
.cx(s0, q0)
.expect("Failed to apply controlled-X for syndrome 01 correction in BitFlipCode");
circuit
.x(s1)
.expect("Failed to apply X to s1 after syndrome 01 correction in BitFlipCode");
circuit
.x(s0)
.expect("Failed to apply X to s0 before syndrome 10 correction in BitFlipCode");
circuit
.cx(s1, q1)
.expect("Failed to apply controlled-X for syndrome 10 correction in BitFlipCode");
circuit
.x(s0)
.expect("Failed to apply X to s0 after syndrome 10 correction in BitFlipCode");
circuit
.cx(s0, q2)
.expect("Failed to apply first controlled-X for syndrome 11 correction in BitFlipCode");
circuit.cx(s1, q2).expect(
"Failed to apply second controlled-X for syndrome 11 correction in BitFlipCode",
);
Ok(circuit)
}
}
#[derive(Debug, Clone, Copy)]
pub struct PhaseFlipCode;
impl ErrorCorrection for PhaseFlipCode {
fn physical_qubits(&self) -> usize {
3
}
fn logical_qubits(&self) -> usize {
1
}
fn distance(&self) -> usize {
3
}
fn encode_circuit(
&self,
logical_qubits: &[QubitId],
ancilla_qubits: &[QubitId],
) -> Result<Circuit<16>> {
let mut circuit = Circuit::<16>::new();
if logical_qubits.is_empty() {
return Err(SimulatorError::InvalidInput(
"PhaseFlipCode requires at least 1 logical qubit".to_string(),
));
}
if ancilla_qubits.len() < 2 {
return Err(SimulatorError::InvalidInput(
"PhaseFlipCode requires at least 2 ancilla qubits".to_string(),
));
}
let q0 = logical_qubits[0];
let q1 = ancilla_qubits[0];
let q2 = ancilla_qubits[1];
circuit
.h(q0)
.expect("Failed to apply first Hadamard to q0 in PhaseFlipCode encoding");
circuit
.h(q1)
.expect("Failed to apply first Hadamard to q1 in PhaseFlipCode encoding");
circuit
.h(q2)
.expect("Failed to apply first Hadamard to q2 in PhaseFlipCode encoding");
circuit
.cnot(q0, q1)
.expect("Failed to apply CNOT from q0 to q1 in PhaseFlipCode encoding");
circuit
.cnot(q0, q2)
.expect("Failed to apply CNOT from q0 to q2 in PhaseFlipCode encoding");
circuit
.h(q0)
.expect("Failed to apply second Hadamard to q0 in PhaseFlipCode encoding");
circuit
.h(q1)
.expect("Failed to apply second Hadamard to q1 in PhaseFlipCode encoding");
circuit
.h(q2)
.expect("Failed to apply second Hadamard to q2 in PhaseFlipCode encoding");
Ok(circuit)
}
fn decode_circuit(
&self,
encoded_qubits: &[QubitId],
syndrome_qubits: &[QubitId],
) -> Result<Circuit<16>> {
let mut circuit = Circuit::<16>::new();
if encoded_qubits.len() < 3 {
return Err(SimulatorError::InvalidInput(
"PhaseFlipCode requires at least 3 encoded qubits".to_string(),
));
}
if syndrome_qubits.len() < 2 {
return Err(SimulatorError::InvalidInput(
"PhaseFlipCode requires at least 2 syndrome qubits".to_string(),
));
}
let q0 = encoded_qubits[0];
let q1 = encoded_qubits[1];
let q2 = encoded_qubits[2];
let s0 = syndrome_qubits[0];
let s1 = syndrome_qubits[1];
circuit
.h(q0)
.expect("Failed to apply first Hadamard to q0 in PhaseFlipCode decoding");
circuit
.h(q1)
.expect("Failed to apply first Hadamard to q1 in PhaseFlipCode decoding");
circuit
.h(q2)
.expect("Failed to apply first Hadamard to q2 in PhaseFlipCode decoding");
circuit
.cnot(q0, s0)
.expect("Failed to apply CNOT from q0 to s0 in PhaseFlipCode syndrome extraction");
circuit
.cnot(q1, s0)
.expect("Failed to apply CNOT from q1 to s0 in PhaseFlipCode syndrome extraction");
circuit
.cnot(q1, s1)
.expect("Failed to apply CNOT from q1 to s1 in PhaseFlipCode syndrome extraction");
circuit
.cnot(q2, s1)
.expect("Failed to apply CNOT from q2 to s1 in PhaseFlipCode syndrome extraction");
circuit
.x(s1)
.expect("Failed to apply X to s1 before syndrome 01 correction in PhaseFlipCode");
circuit
.cx(s0, q0)
.expect("Failed to apply controlled-X for syndrome 01 correction in PhaseFlipCode");
circuit
.x(s1)
.expect("Failed to apply X to s1 after syndrome 01 correction in PhaseFlipCode");
circuit
.x(s0)
.expect("Failed to apply X to s0 before syndrome 10 correction in PhaseFlipCode");
circuit
.cx(s1, q1)
.expect("Failed to apply controlled-X for syndrome 10 correction in PhaseFlipCode");
circuit
.x(s0)
.expect("Failed to apply X to s0 after syndrome 10 correction in PhaseFlipCode");
circuit.cx(s0, q2).expect(
"Failed to apply first controlled-X for syndrome 11 correction in PhaseFlipCode",
);
circuit.cx(s1, q2).expect(
"Failed to apply second controlled-X for syndrome 11 correction in PhaseFlipCode",
);
circuit
.h(q0)
.expect("Failed to apply second Hadamard to q0 in PhaseFlipCode decoding");
circuit
.h(q1)
.expect("Failed to apply second Hadamard to q1 in PhaseFlipCode decoding");
circuit
.h(q2)
.expect("Failed to apply second Hadamard to q2 in PhaseFlipCode decoding");
Ok(circuit)
}
}
#[derive(Debug, Clone, Copy)]
pub struct ShorCode;
impl ErrorCorrection for ShorCode {
fn physical_qubits(&self) -> usize {
9
}
fn logical_qubits(&self) -> usize {
1
}
fn distance(&self) -> usize {
3
}
fn encode_circuit(
&self,
logical_qubits: &[QubitId],
ancilla_qubits: &[QubitId],
) -> Result<Circuit<16>> {
let mut circuit = Circuit::<16>::new();
if logical_qubits.is_empty() {
return Err(SimulatorError::InvalidInput(
"ShorCode requires at least 1 logical qubit".to_string(),
));
}
if ancilla_qubits.len() < 8 {
return Err(SimulatorError::InvalidInput(
"ShorCode requires at least 8 ancilla qubits".to_string(),
));
}
let q = logical_qubits[0]; let a = &ancilla_qubits[0..8];
circuit
.h(q)
.expect("Failed to apply Hadamard to logical qubit in ShorCode encoding");
circuit
.cnot(q, a[0])
.expect("Failed to apply CNOT to create Block 1 in ShorCode encoding"); circuit
.cnot(q, a[3])
.expect("Failed to apply CNOT to create Block 2 in ShorCode encoding");
circuit
.cnot(q, a[1])
.expect("Failed to apply first CNOT for Block 1 bit-flip encoding in ShorCode");
circuit
.cnot(q, a[2])
.expect("Failed to apply second CNOT for Block 1 bit-flip encoding in ShorCode");
circuit
.cnot(a[3], a[4])
.expect("Failed to apply first CNOT for Block 2 bit-flip encoding in ShorCode");
circuit
.cnot(a[3], a[5])
.expect("Failed to apply second CNOT for Block 2 bit-flip encoding in ShorCode");
circuit
.cnot(q, a[6])
.expect("Failed to apply CNOT to create Block 3 in ShorCode encoding");
circuit
.cnot(a[6], a[7])
.expect("Failed to apply CNOT for Block 3 bit-flip encoding in ShorCode");
Ok(circuit)
}
fn decode_circuit(
&self,
encoded_qubits: &[QubitId],
syndrome_qubits: &[QubitId],
) -> Result<Circuit<16>> {
let mut circuit = Circuit::<16>::new();
if encoded_qubits.len() < 9 {
return Err(SimulatorError::InvalidInput(
"ShorCode requires at least 9 encoded qubits".to_string(),
));
}
if syndrome_qubits.len() < 8 {
return Err(SimulatorError::InvalidInput(
"ShorCode requires at least 8 syndrome qubits".to_string(),
));
}
let data = encoded_qubits;
let synd = syndrome_qubits;
circuit.cnot(data[0], synd[0]).expect(
"Failed to apply CNOT from data[0] to synd[0] in ShorCode Group 1 syndrome detection",
);
circuit.cnot(data[1], synd[0]).expect(
"Failed to apply CNOT from data[1] to synd[0] in ShorCode Group 1 syndrome detection",
);
circuit.cnot(data[1], synd[1]).expect(
"Failed to apply CNOT from data[1] to synd[1] in ShorCode Group 1 syndrome detection",
);
circuit.cnot(data[2], synd[1]).expect(
"Failed to apply CNOT from data[2] to synd[1] in ShorCode Group 1 syndrome detection",
);
circuit.cnot(data[3], synd[2]).expect(
"Failed to apply CNOT from data[3] to synd[2] in ShorCode Group 2 syndrome detection",
);
circuit.cnot(data[4], synd[2]).expect(
"Failed to apply CNOT from data[4] to synd[2] in ShorCode Group 2 syndrome detection",
);
circuit.cnot(data[4], synd[3]).expect(
"Failed to apply CNOT from data[4] to synd[3] in ShorCode Group 2 syndrome detection",
);
circuit.cnot(data[5], synd[3]).expect(
"Failed to apply CNOT from data[5] to synd[3] in ShorCode Group 2 syndrome detection",
);
circuit.cnot(data[6], synd[4]).expect(
"Failed to apply CNOT from data[6] to synd[4] in ShorCode Group 3 syndrome detection",
);
circuit.cnot(data[7], synd[4]).expect(
"Failed to apply CNOT from data[7] to synd[4] in ShorCode Group 3 syndrome detection",
);
circuit.cnot(data[7], synd[5]).expect(
"Failed to apply CNOT from data[7] to synd[5] in ShorCode Group 3 syndrome detection",
);
circuit.cnot(data[8], synd[5]).expect(
"Failed to apply CNOT from data[8] to synd[5] in ShorCode Group 3 syndrome detection",
);
circuit.x(synd[1]).expect(
"Failed to apply X to synd[1] before Group 1 syndrome 01 correction in ShorCode",
);
circuit
.cx(synd[0], data[0])
.expect("Failed to apply controlled-X for Group 1 syndrome 01 correction in ShorCode");
circuit.x(synd[1]).expect(
"Failed to apply X to synd[1] after Group 1 syndrome 01 correction in ShorCode",
);
circuit.x(synd[0]).expect(
"Failed to apply X to synd[0] before Group 1 syndrome 10 correction in ShorCode",
);
circuit
.cx(synd[1], data[1])
.expect("Failed to apply controlled-X for Group 1 syndrome 10 correction in ShorCode");
circuit.x(synd[0]).expect(
"Failed to apply X to synd[0] after Group 1 syndrome 10 correction in ShorCode",
);
circuit.cx(synd[0], data[2]).expect(
"Failed to apply first controlled-X for Group 1 syndrome 11 correction in ShorCode",
);
circuit.cx(synd[1], data[2]).expect(
"Failed to apply second controlled-X for Group 1 syndrome 11 correction in ShorCode",
);
circuit.x(synd[3]).expect(
"Failed to apply X to synd[3] before Group 2 syndrome 01 correction in ShorCode",
);
circuit
.cx(synd[2], data[3])
.expect("Failed to apply controlled-X for Group 2 syndrome 01 correction in ShorCode");
circuit.x(synd[3]).expect(
"Failed to apply X to synd[3] after Group 2 syndrome 01 correction in ShorCode",
);
circuit.x(synd[2]).expect(
"Failed to apply X to synd[2] before Group 2 syndrome 10 correction in ShorCode",
);
circuit
.cx(synd[3], data[4])
.expect("Failed to apply controlled-X for Group 2 syndrome 10 correction in ShorCode");
circuit.x(synd[2]).expect(
"Failed to apply X to synd[2] after Group 2 syndrome 10 correction in ShorCode",
);
circuit.cx(synd[2], data[5]).expect(
"Failed to apply first controlled-X for Group 2 syndrome 11 correction in ShorCode",
);
circuit.cx(synd[3], data[5]).expect(
"Failed to apply second controlled-X for Group 2 syndrome 11 correction in ShorCode",
);
circuit.x(synd[5]).expect(
"Failed to apply X to synd[5] before Group 3 syndrome 01 correction in ShorCode",
);
circuit
.cx(synd[4], data[6])
.expect("Failed to apply controlled-X for Group 3 syndrome 01 correction in ShorCode");
circuit.x(synd[5]).expect(
"Failed to apply X to synd[5] after Group 3 syndrome 01 correction in ShorCode",
);
circuit.x(synd[4]).expect(
"Failed to apply X to synd[4] before Group 3 syndrome 10 correction in ShorCode",
);
circuit
.cx(synd[5], data[7])
.expect("Failed to apply controlled-X for Group 3 syndrome 10 correction in ShorCode");
circuit.x(synd[4]).expect(
"Failed to apply X to synd[4] after Group 3 syndrome 10 correction in ShorCode",
);
circuit.cx(synd[4], data[8]).expect(
"Failed to apply first controlled-X for Group 3 syndrome 11 correction in ShorCode",
);
circuit.cx(synd[5], data[8]).expect(
"Failed to apply second controlled-X for Group 3 syndrome 11 correction in ShorCode",
);
for &q in &[data[0], data[3], data[6]] {
circuit
.h(q)
.expect("Failed to apply Hadamard for phase error detection in ShorCode");
}
circuit.cnot(data[0], synd[6]).expect(
"Failed to apply CNOT from data[0] to synd[6] in ShorCode phase error detection",
);
circuit.cnot(data[3], synd[6]).expect(
"Failed to apply CNOT from data[3] to synd[6] in ShorCode phase error detection",
);
circuit.cnot(data[3], synd[7]).expect(
"Failed to apply CNOT from data[3] to synd[7] in ShorCode phase error detection",
);
circuit.cnot(data[6], synd[7]).expect(
"Failed to apply CNOT from data[6] to synd[7] in ShorCode phase error detection",
);
circuit
.x(synd[7])
.expect("Failed to apply X to synd[7] before phase syndrome 01 correction in ShorCode");
for &q in &[data[0], data[1], data[2]] {
circuit.cz(synd[6], q).expect(
"Failed to apply controlled-Z for Group 1 phase syndrome 01 correction in ShorCode",
);
}
circuit
.x(synd[7])
.expect("Failed to apply X to synd[7] after phase syndrome 01 correction in ShorCode");
circuit
.x(synd[6])
.expect("Failed to apply X to synd[6] before phase syndrome 10 correction in ShorCode");
for &q in &[data[3], data[4], data[5]] {
circuit.cz(synd[7], q).expect(
"Failed to apply controlled-Z for Group 2 phase syndrome 10 correction in ShorCode",
);
}
circuit
.x(synd[6])
.expect("Failed to apply X to synd[6] after phase syndrome 10 correction in ShorCode");
for &q in &[data[6], data[7], data[8]] {
circuit
.cz(synd[6], q)
.expect("Failed to apply first controlled-Z for Group 3 phase syndrome 11 correction in ShorCode");
circuit
.cz(synd[7], q)
.expect("Failed to apply second controlled-Z for Group 3 phase syndrome 11 correction in ShorCode");
}
for &q in &[data[0], data[3], data[6]] {
circuit.h(q).expect(
"Failed to apply Hadamard to transform back from phase error basis in ShorCode",
);
}
Ok(circuit)
}
}
#[derive(Debug, Clone, Copy)]
pub struct FiveQubitCode;
impl ErrorCorrection for FiveQubitCode {
fn physical_qubits(&self) -> usize {
5
}
fn logical_qubits(&self) -> usize {
1
}
fn distance(&self) -> usize {
3
}
fn encode_circuit(
&self,
logical_qubits: &[QubitId],
ancilla_qubits: &[QubitId],
) -> Result<Circuit<16>> {
let mut circuit = Circuit::<16>::new();
if logical_qubits.is_empty() {
return Err(SimulatorError::InvalidInput(
"FiveQubitCode requires at least 1 logical qubit".to_string(),
));
}
if ancilla_qubits.len() < 4 {
return Err(SimulatorError::InvalidInput(
"FiveQubitCode requires at least 4 ancilla qubits".to_string(),
));
}
let q0 = logical_qubits[0];
let ancs = ancilla_qubits;
circuit
.h(ancs[0])
.expect("Failed to apply Hadamard to ancs[0] in FiveQubitCode encoding initialization");
circuit
.h(ancs[1])
.expect("Failed to apply Hadamard to ancs[1] in FiveQubitCode encoding initialization");
circuit
.h(ancs[2])
.expect("Failed to apply Hadamard to ancs[2] in FiveQubitCode encoding initialization");
circuit
.h(ancs[3])
.expect("Failed to apply Hadamard to ancs[3] in FiveQubitCode encoding initialization");
circuit
.cnot(q0, ancs[0])
.expect("Failed to apply CNOT from q0 to ancs[0] in FiveQubitCode encoding");
circuit
.cnot(q0, ancs[1])
.expect("Failed to apply CNOT from q0 to ancs[1] in FiveQubitCode encoding");
circuit
.cnot(q0, ancs[2])
.expect("Failed to apply CNOT from q0 to ancs[2] in FiveQubitCode encoding");
circuit
.cnot(q0, ancs[3])
.expect("Failed to apply CNOT from q0 to ancs[3] in FiveQubitCode encoding");
circuit
.h(q0)
.expect("Failed to apply Hadamard to q0 for X stabilizer in FiveQubitCode encoding");
circuit.h(ancs[1]).expect(
"Failed to apply Hadamard to ancs[1] for X stabilizer in FiveQubitCode encoding",
);
circuit.h(ancs[3]).expect(
"Failed to apply Hadamard to ancs[3] for X stabilizer in FiveQubitCode encoding",
);
circuit
.cnot(q0, ancs[0])
.expect("Failed to apply CNOT for X stabilizer step 1 in FiveQubitCode encoding");
circuit
.cnot(ancs[1], ancs[0])
.expect("Failed to apply CNOT for X stabilizer step 2 in FiveQubitCode encoding");
circuit
.cnot(ancs[0], ancs[2])
.expect("Failed to apply CNOT for X stabilizer step 3 in FiveQubitCode encoding");
circuit
.cnot(ancs[2], ancs[3])
.expect("Failed to apply CNOT for X stabilizer step 4 in FiveQubitCode encoding");
circuit.cz(q0, ancs[1]).expect(
"Failed to apply controlled-Z for Z stabilizer step 1 in FiveQubitCode encoding",
);
circuit.cz(ancs[0], ancs[2]).expect(
"Failed to apply controlled-Z for Z stabilizer step 2 in FiveQubitCode encoding",
);
circuit.cz(ancs[1], ancs[3]).expect(
"Failed to apply controlled-Z for Z stabilizer step 3 in FiveQubitCode encoding",
);
circuit
.h(ancs[0])
.expect("Failed to apply final Hadamard to ancs[0] in FiveQubitCode encoding");
circuit
.h(ancs[2])
.expect("Failed to apply final Hadamard to ancs[2] in FiveQubitCode encoding");
Ok(circuit)
}
fn decode_circuit(
&self,
encoded_qubits: &[QubitId],
syndrome_qubits: &[QubitId],
) -> Result<Circuit<16>> {
let mut circuit = Circuit::<16>::new();
if encoded_qubits.len() < 5 {
return Err(SimulatorError::InvalidInput(
"FiveQubitCode requires at least 5 encoded qubits".to_string(),
));
}
if syndrome_qubits.len() < 4 {
return Err(SimulatorError::InvalidInput(
"FiveQubitCode requires at least 4 syndrome qubits".to_string(),
));
}
let data = encoded_qubits;
let synd = syndrome_qubits;
circuit
.h(synd[0])
.expect("Failed to apply Hadamard to synd[0] before Generator 1 in FiveQubitCode syndrome extraction");
circuit
.cnot(synd[0], data[0])
.expect("Failed to apply CNOT for Generator 1 XZZXI at position 0 in FiveQubitCode");
circuit.cz(synd[0], data[1]).expect(
"Failed to apply controlled-Z for Generator 1 XZZXI at position 1 in FiveQubitCode",
);
circuit.cz(synd[0], data[2]).expect(
"Failed to apply controlled-Z for Generator 1 XZZXI at position 2 in FiveQubitCode",
);
circuit
.cnot(synd[0], data[3])
.expect("Failed to apply CNOT for Generator 1 XZZXI at position 3 in FiveQubitCode");
circuit
.h(synd[0])
.expect("Failed to apply Hadamard to synd[0] after Generator 1 in FiveQubitCode syndrome extraction");
circuit
.h(synd[1])
.expect("Failed to apply Hadamard to synd[1] before Generator 2 in FiveQubitCode syndrome extraction");
circuit
.cnot(synd[1], data[1])
.expect("Failed to apply CNOT for Generator 2 IXZZX at position 1 in FiveQubitCode");
circuit.cz(synd[1], data[2]).expect(
"Failed to apply controlled-Z for Generator 2 IXZZX at position 2 in FiveQubitCode",
);
circuit.cz(synd[1], data[3]).expect(
"Failed to apply controlled-Z for Generator 2 IXZZX at position 3 in FiveQubitCode",
);
circuit
.cnot(synd[1], data[4])
.expect("Failed to apply CNOT for Generator 2 IXZZX at position 4 in FiveQubitCode");
circuit
.h(synd[1])
.expect("Failed to apply Hadamard to synd[1] after Generator 2 in FiveQubitCode syndrome extraction");
circuit
.h(synd[2])
.expect("Failed to apply Hadamard to synd[2] before Generator 3 in FiveQubitCode syndrome extraction");
circuit
.cnot(synd[2], data[0])
.expect("Failed to apply CNOT for Generator 3 XIXZZ at position 0 in FiveQubitCode");
circuit
.cnot(synd[2], data[2])
.expect("Failed to apply CNOT for Generator 3 XIXZZ at position 2 in FiveQubitCode");
circuit.cz(synd[2], data[3]).expect(
"Failed to apply controlled-Z for Generator 3 XIXZZ at position 3 in FiveQubitCode",
);
circuit.cz(synd[2], data[4]).expect(
"Failed to apply controlled-Z for Generator 3 XIXZZ at position 4 in FiveQubitCode",
);
circuit
.h(synd[2])
.expect("Failed to apply Hadamard to synd[2] after Generator 3 in FiveQubitCode syndrome extraction");
circuit
.h(synd[3])
.expect("Failed to apply Hadamard to synd[3] before Generator 4 in FiveQubitCode syndrome extraction");
circuit.cz(synd[3], data[0]).expect(
"Failed to apply controlled-Z for Generator 4 ZXIXZ at position 0 in FiveQubitCode",
);
circuit
.cnot(synd[3], data[1])
.expect("Failed to apply CNOT for Generator 4 ZXIXZ at position 1 in FiveQubitCode");
circuit
.cnot(synd[3], data[3])
.expect("Failed to apply CNOT for Generator 4 ZXIXZ at position 3 in FiveQubitCode");
circuit.cz(synd[3], data[4]).expect(
"Failed to apply controlled-Z for Generator 4 ZXIXZ at position 4 in FiveQubitCode",
);
circuit
.h(synd[3])
.expect("Failed to apply Hadamard to synd[3] after Generator 4 in FiveQubitCode syndrome extraction");
let syndrome_0001 = [false, false, false, true];
self.add_conditional_correction(&mut circuit, synd, syndrome_0001, data[0], 'X')?;
let syndrome_0010 = [false, false, true, false];
self.add_conditional_correction(&mut circuit, synd, syndrome_0010, data[1], 'X')?;
let syndrome_0100 = [false, true, false, false];
self.add_conditional_correction(&mut circuit, synd, syndrome_0100, data[2], 'X')?;
let syndrome_1000 = [true, false, false, false];
self.add_conditional_correction(&mut circuit, synd, syndrome_1000, data[3], 'X')?;
let syndrome_0011 = [false, false, true, true];
self.add_conditional_correction(&mut circuit, synd, syndrome_0011, data[0], 'Z')?;
let syndrome_0101 = [false, true, false, true];
self.add_conditional_correction(&mut circuit, synd, syndrome_0101, data[1], 'Z')?;
let syndrome_1001 = [true, false, false, true];
self.add_conditional_correction(&mut circuit, synd, syndrome_1001, data[2], 'Z')?;
let syndrome_1100 = [true, true, false, false];
self.add_conditional_correction(&mut circuit, synd, syndrome_1100, data[3], 'Z')?;
let syndrome_0111 = [false, true, true, true];
self.add_conditional_correction(&mut circuit, synd, syndrome_0111, data[0], 'Y')?;
let syndrome_1011 = [true, false, true, true];
self.add_conditional_correction(&mut circuit, synd, syndrome_1011, data[1], 'Y')?;
let syndrome_1101 = [true, true, false, true];
self.add_conditional_correction(&mut circuit, synd, syndrome_1101, data[2], 'Y')?;
let syndrome_1110 = [true, true, true, false];
self.add_conditional_correction(&mut circuit, synd, syndrome_1110, data[3], 'Y')?;
Ok(circuit)
}
}
impl FiveQubitCode {
fn add_conditional_correction(
&self,
circuit: &mut Circuit<16>,
syndrome_qubits: &[QubitId],
syndrome: [bool; 4],
target: QubitId,
error_type: char,
) -> Result<()> {
for (i, &should_be_one) in syndrome.iter().enumerate() {
if !should_be_one {
circuit
.x(syndrome_qubits[i])
.expect("Failed to apply X gate to negate syndrome bit in FiveQubitCode conditional correction");
}
}
for i in 1..syndrome_qubits.len() {
circuit
.cx(syndrome_qubits[i], syndrome_qubits[0])
.expect("Failed to apply controlled-X to combine syndrome bits in FiveQubitCode conditional correction");
}
match error_type {
'X' => {
circuit.cx(syndrome_qubits[0], target).expect(
"Failed to apply controlled-X correction for bit flip in FiveQubitCode",
);
}
'Z' => {
circuit.cz(syndrome_qubits[0], target).expect(
"Failed to apply controlled-Z correction for phase flip in FiveQubitCode",
);
}
'Y' => {
circuit
.cz(syndrome_qubits[0], target)
.expect("Failed to apply controlled-Z for Y correction in FiveQubitCode");
circuit
.cx(syndrome_qubits[0], target)
.expect("Failed to apply controlled-X for Y correction in FiveQubitCode");
}
_ => {
return Err(SimulatorError::UnsupportedOperation(format!(
"Unsupported error type: {error_type}"
)))
}
}
for i in 1..syndrome_qubits.len() {
circuit
.cx(syndrome_qubits[i], syndrome_qubits[0])
.expect("Failed to apply controlled-X to undo syndrome bit combination in FiveQubitCode conditional correction");
}
for (i, &should_be_one) in syndrome.iter().enumerate() {
if !should_be_one {
circuit
.x(syndrome_qubits[i])
.expect("Failed to apply X gate to reset syndrome bit in FiveQubitCode conditional correction");
}
}
Ok(())
}
}