XACC
states.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_STATES_H_
33 #define CLASSES_STATES_H_
34 
35 namespace qpp {
40 class States final : public internal::Singleton<const States> // const Singleton
41 {
42  friend class internal::Singleton<const States>;
43 
44  public:
45  // Pauli eigen-states
46  ket x0{ket::Zero(2)};
47  ket x1{ket::Zero(2)};
48  ket y0{ket::Zero(2)};
49  ket y1{ket::Zero(2)};
50  ket z0{ket::Zero(2)};
51  ket z1{ket::Zero(2)};
52 
53  // projectors onto Pauli eigen-states
54  cmat px0{cmat::Zero(2, 2)};
56  cmat px1{cmat::Zero(2, 2)};
58  cmat py0{cmat::Zero(2, 2)};
60  cmat py1{cmat::Zero(2, 2)};
62  cmat pz0{cmat::Zero(2, 2)};
64  cmat pz1{cmat::Zero(2, 2)};
66 
67  // Bell states
68  ket b00{ket::Zero(4)};
70  ket b01{ket::Zero(4)};
72  ket b10{ket::Zero(4)};
74  ket b11{ket::Zero(4)};
76 
77  // projectors onto Bell states
78  cmat pb00{cmat::Zero(4, 4)};
79  cmat pb01{cmat::Zero(4, 4)};
80  cmat pb10{cmat::Zero(4, 4)};
81  cmat pb11{cmat::Zero(4, 4)};
82 
83  // W and GHZ states
84  ket GHZ{ket::Zero(8)};
85  ket W{ket::Zero(8)};
86 
87  // projectors onto GHZ and W
88  cmat pGHZ{cmat::Zero(8, 8)};
89  cmat pW{cmat::Zero(8, 8)};
90 
98  ket mes(idx d = 2) const {
99  // EXCEPTION CHECKS
100 
101  // check valid dims
102  if (d == 0)
103  throw exception::DimsInvalid("qpp::States::mes()");
104  // END EXCEPTION CHECKS
105 
106  ket psi = mket({0, 0}, {d, d});
107  for (idx i = 1; i < d; ++i) {
108  psi += mket({i, i}, {d, d});
109  }
110 
111  return psi / std::sqrt(d);
112  }
113 
121  ket zero(idx n, idx d = 2) const {
122  // EXCEPTION CHECKS
123 
124  // check out of range
125  if (n == 0)
126  throw exception::OutOfRange("qpp::States::zero()");
127  // check valid dims
128  if (d == 0)
129  throw exception::DimsInvalid("qpp::States::zero()");
130  // END EXCEPTION CHECKS
131 
132  idx D = static_cast<idx>(std::llround(std::pow(d, n)));
133  ket result = ket::Zero(D);
134  result(0) = 1;
135 
136  return result;
137  }
138 
146  ket one(idx n, idx d = 2) const {
147  // EXCEPTION CHECKS
148 
149  // check out of range
150  if (n == 0)
151  throw exception::OutOfRange("qpp::States::one()");
152  // check valid dims
153  if (d == 0)
154  throw exception::DimsInvalid("qpp::States::one()");
155  // END EXCEPTION CHECKS
156 
157  ket result = ket::Zero(static_cast<ket::Index>(std::pow(d, n)));
158  result(multiidx2n(std::vector<idx>(n, 1), std::vector<idx>(n, d))) = 1;
159 
160  return result;
161  }
162 
171  ket jn(idx j, idx n, idx d = 2) const {
172  // EXCEPTION CHECKS
173 
174  // check out of range
175  if (n == 0)
176  throw exception::OutOfRange("qpp::States::jn()");
177  // check valid subsystem
178  if (j >= d)
179  throw exception::SubsysMismatchDims("qpp::States::jn()");
180 
181  // check valid dims
182  if (d == 0)
183  throw exception::DimsInvalid("qpp::States::jn()");
184  // END EXCEPTION CHECKS
185 
186  ket result = ket::Zero(static_cast<ket::Index>(std::pow(d, n)));
187  result(multiidx2n(std::vector<idx>(n, j), std::vector<idx>(n, d))) = 1;
188 
189  return result;
190  }
191 
198  ket plus(idx n) const {
199  // EXCEPTION CHECKS
200 
201  // check out of range
202  if (n == 0)
203  throw exception::OutOfRange("qpp::States::plus()");
204  // END EXCEPTION CHECKS
205 
206  idx D = static_cast<idx>(std::llround(std::pow(2, n)));
207  ket result = ket::Ones(D);
208 
209  return result / std::sqrt(D);
210  }
211 
218  ket minus(idx n) const {
219  // EXCEPTION CHECKS
220 
221  // check out of range
222  if (n == 0)
223  throw exception::OutOfRange("qpp::States::minus()");
224  // END EXCEPTION CHECKS
225 
226  return kronpow(x1, n);
227  }
228 
229  private:
233  States() {
234  // initialize
235  x0 << 1 / std::sqrt(2.), 1 / std::sqrt(2.);
236  x1 << 1 / std::sqrt(2.), -1 / std::sqrt(2.);
237  y0 << 1 / std::sqrt(2.), 1_i / std::sqrt(2.);
238  y1 << 1 / std::sqrt(2.), -1_i / std::sqrt(2.);
239  z0 << 1, 0;
240  z1 << 0, 1;
241  px0 = x0 * x0.adjoint();
242  px1 = x1 * x1.adjoint();
243  py0 = y0 * y0.adjoint();
244  py1 = y1 * y1.adjoint();
245  pz0 = z0 * z0.adjoint();
246  pz1 = z1 * z1.adjoint();
247 
248  // Bell states, as described in Nielsen and Chuang
249  // |ij> -> |b_{ij}> by the CNOT*(H x Id) circuit
250 
251  b00 << 1 / std::sqrt(2.), 0, 0, 1 / std::sqrt(2.);
252  // (|00> + |11>) / sqrt(2)
253  b01 << 0, 1 / std::sqrt(2.), 1 / std::sqrt(2.), 0;
254  // (|01> + |10>) / sqrt(2)
255  b10 << 1 / std::sqrt(2.), 0, 0, -1 / std::sqrt(2.);
256  // (|00> - |11>) / sqrt(2)
257  b11 << 0, 1 / std::sqrt(2.), -1 / std::sqrt(2.), 0;
258  // (|01> - |10>) / sqrt(2)
259 
260  pb00 = b00 * b00.adjoint();
261  pb01 = b01 * b01.adjoint();
262  pb10 = b10 * b10.adjoint();
263  pb11 = b11 * b11.adjoint();
264 
265  GHZ << 1, 0, 0, 0, 0, 0, 0, 1;
266  GHZ = GHZ / std::sqrt(2.);
267  W << 0, 1, 1, 0, 1, 0, 0, 0;
268  W = W / std::sqrt(3.);
269 
270  pGHZ = GHZ * GHZ.adjoint();
271  pW = W * W.adjoint();
272  }
273 
277  ~States() = default;
278 }; /* class States */
279 
280 } /* namespace qpp */
281 
282 #endif /* CLASSES_STATES_H_ */
Quantum++ main namespace.
Definition: circuits.h:35