/* qec.c: Quantum Error Correction Copyright 2003 Bjoern Butscher, Hendrik Weimer This file is part of libquantum libquantum is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. libquantum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with libquantum; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "qureg.h" #include "gates.h" #include "config.h" #include "decoherence.h" #include "measure.h" /* Type of the QEC. Currently implemented versions are: 0: no QEC (default) 1: Steane's 3-bit code */ int type = 0; /* How many qubits are protected */ int width = 0; /* Change the status of the QEC. */ void quantum_qec_set_status(int stype, int swidth) { type = stype; width = swidth; } /* Get the current QEC status */ void quantum_qec_get_status(int *ptype, int *pwidth) { if(ptype) *ptype = type; if(pwidth) *pwidth = width; } /* Encode a quantum register. All qubits up to SWIDTH are protected, the rest is expanded with a repition code. */ void quantum_qec_encode(int type, int width, quantum_reg *reg) { int i; float lambda; lambda = quantum_get_decoherence(); quantum_set_decoherence(0); for(i=0;iwidth;i++) { if(i==reg->width-1) quantum_set_decoherence(lambda); if(iwidth+i, reg); quantum_hadamard(2*reg->width+i, reg); quantum_cnot(reg->width+i, i, reg); quantum_cnot(2*reg->width+i, i, reg); } else { quantum_cnot(i, reg->width+i, reg); quantum_cnot(i, 2*reg->width+i, reg); } } quantum_qec_set_status(1, reg->width); reg->width *= 3; } /* Decode a quantum register and perform Quantum Error Correction on it */ void quantum_qec_decode(int type, int width, quantum_reg *reg) { int i, a, b; int swidth; float lambda; lambda = quantum_get_decoherence(); quantum_set_decoherence(0); swidth=reg->width/3; quantum_qec_set_status(0, 0); for(i=reg->width/3-1;i>=0;i--) { if(i==0) quantum_set_decoherence(lambda); if(i 0) counter += inc; else if(inc < 0) counter = 0; if(frequency > 0) freq = frequency; if(counter >= freq) { counter = 0; quantum_qec_decode(type, width, reg); quantum_qec_encode(type, width, reg); } return counter; } /* Fault-tolerant version of the NOT gate */ void quantum_sigma_x_ft(int target, quantum_reg *reg) { int tmp; float lambda; tmp = type; type = 0; lambda = quantum_get_decoherence(); quantum_set_decoherence(0); /* These operations can be performed simultaneously */ quantum_sigma_x(target, reg); quantum_sigma_x(target+width, reg); quantum_set_decoherence(lambda); quantum_sigma_x(target+2*width, reg); quantum_qec_counter(1, 0, reg); type = tmp; } /* Fault-tolerant version of the Controlled NOT gate */ void quantum_cnot_ft(int control, int target, quantum_reg *reg) { int tmp; float lambda; tmp = type; type = 0; /* These operations can be performed simultaneously */ lambda = quantum_get_decoherence(); quantum_set_decoherence(0); quantum_cnot(control, target, reg); quantum_cnot(control+width, target+width, reg); quantum_set_decoherence(lambda); quantum_cnot(control+2*width, target+2*width, reg); quantum_qec_counter(1, 0, reg); type = tmp; } /* Fault-tolerant version of the Toffoli gate */ void quantum_toffoli_ft(int control1, int control2, int target, quantum_reg *reg) { int i; int c1, c2; MAX_UNSIGNED mask; mask = ((MAX_UNSIGNED) 1 << target) + ((MAX_UNSIGNED) 1 << (target+width)) + ((MAX_UNSIGNED) 1 << (target+2*width)); for(i=0;isize;i++) { c1 = 0; c2 = 0; if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control1)) c1 = 1; if(reg->node[i].state & ((MAX_UNSIGNED) 1 << (control1+width))) { c1 ^= 1; } if(reg->node[i].state & ((MAX_UNSIGNED) 1 << (control1+2*width))) { c1 ^= 1; } if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control2)) c2 = 1; if(reg->node[i].state & ((MAX_UNSIGNED) 1 << (control2+width))) { c2 ^= 1; } if(reg->node[i].state & ((MAX_UNSIGNED) 1 << (control2+2*width))) { c2 ^= 1; } if(c1 == 1 && c2 == 1) reg->node[i].state = reg->node[i].state ^ mask; } quantum_decohere(reg); quantum_qec_counter(1, 0, reg); }