XACC
codes.h
Go to the documentation of this file.
1 /*
2  * This file is part of Quantum++.
3  *
4  * MIT License
5  *
6  * Copyright (c) 2013 - 2020 Vlad Gheorghiu.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
32 #ifndef CLASSES_CODES_H_
33 #define CLASSES_CODES_H_
34 
35 namespace qpp {
40 class Codes final : public internal::Singleton<const Codes> // const Singleton
41 {
42  friend class internal::Singleton<const Codes>;
43 
44  public:
49  enum class Type {
50  FIVE_QUBIT,
51  SEVEN_QUBIT_STEANE,
52  NINE_QUBIT_SHOR,
53  };
54 
55  private:
59  Codes() {} // = default; // clang++ spits the error below if defaulted:
60  // error:
61  // default initialization of an object of const type 'const qpp::Codes'
62  // requires a user-provided default constructor
63 
67  ~Codes() = default;
68 
69  public:
78  ket codeword(Type type, idx i) const {
79  ket result;
80  switch (type) {
81  // [[5,1,3]] Five qubit code, as described in Nielsen and Chuang
82  case Type::FIVE_QUBIT:
83  switch (i) {
84  case 0:
85  result =
86  (mket({0, 0, 0, 0, 0}) + mket({1, 0, 0, 1, 0}) +
87  mket({0, 1, 0, 0, 1}) + mket({1, 0, 1, 0, 0}) +
88  mket({0, 1, 0, 1, 0}) - mket({1, 1, 0, 1, 1}) -
89  mket({0, 0, 1, 1, 0}) - mket({1, 1, 0, 0, 0}) -
90  mket({1, 1, 1, 0, 1}) - mket({0, 0, 0, 1, 1}) -
91  mket({1, 1, 1, 1, 0}) - mket({0, 1, 1, 1, 1}) -
92  mket({1, 0, 0, 0, 1}) - mket({0, 1, 1, 0, 0}) -
93  mket({1, 0, 1, 1, 1}) + mket({0, 0, 1, 0, 1})) /
94  4.;
95  break;
96  case 1:
97  result =
98  (mket({1, 1, 1, 1, 1}) + mket({0, 1, 1, 0, 1}) +
99  mket({1, 0, 1, 1, 0}) + mket({0, 1, 0, 1, 1}) +
100  mket({1, 0, 1, 0, 1}) - mket({0, 0, 1, 0, 0}) -
101  mket({1, 1, 0, 0, 1}) - mket({0, 0, 1, 1, 1}) -
102  mket({0, 0, 0, 1, 0}) - mket({1, 1, 1, 0, 0}) -
103  mket({0, 0, 0, 0, 1}) - mket({1, 0, 0, 0, 0}) -
104  mket({0, 1, 1, 1, 0}) - mket({1, 0, 0, 1, 1}) -
105  mket({0, 1, 0, 0, 0}) + mket({1, 1, 0, 1, 0})) /
106  4.;
107  break;
108  default:
109  throw exception::NoCodeword("qpp::Codes::codeword()");
110  }
111  break;
112  // [[7,1,3]] Steane code, as described in Nielsen and Chuang
113  case Type::SEVEN_QUBIT_STEANE:
114  switch (i) {
115  case 0:
116  result = (mket({0, 0, 0, 0, 0, 0, 0}) +
117  mket({1, 0, 1, 0, 1, 0, 1}) +
118  mket({0, 1, 1, 0, 0, 1, 1}) +
119  mket({1, 1, 0, 0, 1, 1, 0}) +
120  mket({0, 0, 0, 1, 1, 1, 1}) +
121  mket({1, 0, 1, 1, 0, 1, 0}) +
122  mket({0, 1, 1, 1, 1, 0, 0}) +
123  mket({1, 1, 0, 1, 0, 0, 1})) /
124  std::sqrt(8.);
125 
126  break;
127  case 1:
128  result = (mket({1, 1, 1, 1, 1, 1, 1}) +
129  mket({0, 1, 0, 1, 0, 1, 0}) +
130  mket({1, 0, 0, 1, 1, 0, 0}) +
131  mket({0, 0, 1, 1, 0, 0, 1}) +
132  mket({1, 1, 1, 0, 0, 0, 0}) +
133  mket({0, 1, 0, 0, 1, 0, 1}) +
134  mket({1, 0, 0, 0, 0, 1, 1}) +
135  mket({0, 0, 1, 0, 1, 1, 0})) /
136  std::sqrt(8.);
137  break;
138  default:
139  throw exception::NoCodeword("qpp::Codes::codeword()");
140  }
141  break;
142  // [[9,1,3]] Shor code
143  case Type::NINE_QUBIT_SHOR:
144  ket shora = mket({0, 0, 0}) + mket({1, 1, 1});
145  ket shorb = mket({0, 0, 0}) - mket({1, 1, 1});
146  switch (i) {
147  case 0:
148  result =
149  kron(shora, kron(shora, shora)) / std::sqrt(8.);
150  break;
151  case 1:
152  result =
153  kron(shorb, kron(shorb, shorb)) / std::sqrt(8.);
154  break;
155  default:
156  throw exception::NoCodeword("qpp::Codes::codeword()");
157  }
158  }
159 
160  return result;
161  }
162 }; /* class Codes */
163 
164 } /* namespace qpp */
165 
166 #endif /* CLASSES_CODES_H_ */
Quantum++ main namespace.
Definition: circuits.h:35