Commit 8fd767d1 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Work on Steane code impl for standard lib



Not yet tested.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent c79de6e9
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#include <functional>
#include "bit_flip_code.hpp"
#include "five_qubit_code.hpp"
#include "seven_qubit_steane_code.hpp"

// Encode a physical qubit into a logical qubit using given scratch qubits.
// Inputs:
@@ -26,7 +27,7 @@ using QecCode = std::tuple<stabilizerGroups, encodeFn, recoverFn>;
// Code name:
// - "bit-flip"
// - "five-qubit"
// - "seven-qubit"
// - "steane" (7 qubits)
// - "surface-code",
// etc.
QecCode getQecCode(const std::string &in_codeName) {
@@ -52,6 +53,18 @@ QecCode getQecCode(const std::string &in_codeName) {
        });
    return std::make_tuple(five_qubit_code_stabilizers(), encoder, recover);
  }
  if (in_codeName == "steane") {
    encodeFn encoder(
        [](qreg q, int dataQubitIdx, std::vector<int> scratchQubitIdx) {
          seven_qubit_code_encoder(q, dataQubitIdx, scratchQubitIdx);
        });
    recoverFn recover(
        [](qreg q, std::vector<int> logicalReg, std::vector<int> syndromes) {
          seven_qubit_code_recover(q, logicalReg, syndromes);
        });
    return std::make_tuple(seven_qubit_code_stabilizers(), encoder, recover);
  }
  
  throw std::runtime_error("Error: '" + in_codeName +
                           "' is not a valid QEC code.");
}
 No newline at end of file
+46 −0
Original line number Diff line number Diff line
#pragma once

// Distance-3 Steane quantum error correction code with 7 qubits
std::vector<std::vector<qcor::PauliOperator>> seven_qubit_code_stabilizers() {
  static const std::vector<std::vector<qcor::PauliOperator>> STABILIZERS{
      // Steane code has two groups of syndromes to detect X and Z errors.
      // X syndromes
      {qcor::X(0), qcor::X(2), qcor::X(4), qcor::X(6)},
      {qcor::X(1), qcor::X(2), qcor::X(5), qcor::X(6)},
      {qcor::X(3), qcor::X(4), qcor::X(5), qcor::X(6)},
      // Z syndromes
      {qcor::Z(0), qcor::Z(2), qcor::Z(4), qcor::Z(6)},
      {qcor::Z(1), qcor::Z(2), qcor::Z(5), qcor::Z(6)},
      {qcor::Z(3), qcor::Z(4), qcor::Z(5), qcor::Z(6)}};
  return STABILIZERS;
}

__qpu__ void seven_qubit_code_encoder(qreg q, int dataQubitIdx,
                                      std::vector<int> scratchQubitIdx) {
  H(q[scratchQubitIdx[0]]);
  H(q[scratchQubitIdx[2]]);
  H(q[scratchQubitIdx[5]]);
  CX(q[dataQubitIdx], q[scratchQubitIdx[4]]);
  CX(q[scratchQubitIdx[5]], q[scratchQubitIdx[1]]);
  CX(q[scratchQubitIdx[5]], q[scratchQubitIdx[3]]);
  CX(q[scratchQubitIdx[1]], q[dataQubitIdx]);
  CX(q[scratchQubitIdx[2]], q[scratchQubitIdx[4]]);
  CX(q[scratchQubitIdx[0]], q[scratchQubitIdx[4]]);
  CX(q[scratchQubitIdx[4]], q[scratchQubitIdx[5]]);
  CX(q[scratchQubitIdx[2]], q[scratchQubitIdx[3]]);
  CX(q[scratchQubitIdx[0]], q[scratchQubitIdx[1]]);
}

__qpu__ void seven_qubit_code_recover(qreg q, std::vector<int> logicalReg,
                                      std::vector<int> syndromes) {
  auto xSyndromes = {syndromes[0], syndromes[1], syndromes[2]};
  auto zSyndromes = {syndromes[3], syndromes[4], syndromes[5]};
  auto xSyndromeIdx = syndrome_array_to_int(xSyndromes);
  auto zSyndromeIdx = syndrome_array_to_int(zSyndromes);
  if (xSyndromeIdx > 0) {
    Z(q[xSyndromeIdx - 1]);
  }
  if (zSyndromeIdx > 0) {
    X(q[zSyndromeIdx - 1]);
  }
}