Quantum++  v1.2
A modern C++11 quantum computing library
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 - 2019 Vlad Gheorghiu (vgheorgh@gmail.com)
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(this->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_ */
ket zero(idx n, idx d=2) const
Zero state of n qudits.
Definition: states.h:121
ket minus(idx n) const
Minus state of n qubits.
Definition: states.h:218
ket W
W state.
Definition: states.h:85
cmat pb01
Projector onto the Bell-01 state.
Definition: states.h:79
ket GHZ
GHZ state.
Definition: states.h:84
cmat pb11
Projector onto the Bell-11 state.
Definition: states.h:81
Singleton policy class, used internally to implement the singleton pattern via CRTP (Curiously recurr...
Definition: singleton.h:80
Subsystems mismatch dimensions exception.
Definition: exception.h:365
Eigen::VectorXcd ket
Complex (double precision) dynamic Eigen column vector.
Definition: types.h:54
ket y0
Pauli Sigma-Y 0-eigenstate |y+>
Definition: states.h:48
Quantum++ main namespace.
Definition: circuits.h:35
const Singleton class that implements most commonly used states
Definition: states.h:40
Invalid dimension(s) exception.
Definition: exception.h:269
cmat pb00
Projector onto the Bell-00 state.
Definition: states.h:78
ket z1
Pauli Sigma-Z 1-eigenstate |1>
Definition: states.h:51
ket b01
Bell-01 state, as described in Nielsen and Chuang.
Definition: states.h:70
ket b00
Bell-00 state, as described in Nielsen and Chuang.
Definition: states.h:68
cmat pb10
Projector onto the Bell-10 state.
Definition: states.h:80
cmat pW
Projector onto the W state.
Definition: states.h:89
idx multiidx2n(const std::vector< idx > &midx, const std::vector< idx > &dims)
Multi-index to non-negative integer index.
Definition: functions.h:1424
~States()=default
Default destructor.
cmat py0
Projector onto the Pauli Sigma-Y 0-eigenstate |y+><y+|.
Definition: states.h:58
dyn_mat< typename Derived::Scalar > kronpow(const Eigen::MatrixBase< Derived > &A, idx n)
Kronecker power.
Definition: functions.h:993
cmat px0
Projector onto the Pauli Sigma-X 0-eigenstate |+><+|.
Definition: states.h:54
ket x1
Pauli Sigma-X 1-eigenstate |->
Definition: states.h:47
ket y1
Pauli Sigma-Y 1-eigenstate |y->
Definition: states.h:49
ket z0
Pauli Sigma-Z 0-eigenstate |0>
Definition: states.h:50
ket b11
Bell-11 state, as described in Nielsen and Chuang.
Definition: states.h:74
Argument out of range exception.
Definition: exception.h:515
ket mes(idx d=2) const
Maximally entangled state of 2 qudits.
Definition: states.h:98
ket jn(idx j, idx n, idx d=2) const
state of n qudits
Definition: states.h:171
ket plus(idx n) const
Plus state of n qubits.
Definition: states.h:198
ket one(idx n, idx d=2) const
One state of n qudits.
Definition: states.h:146
cmat pz0
Projector onto the Pauli Sigma-Z 0-eigenstate |0><0|.
Definition: states.h:62
cmat pGHZ
Projector onto the GHZ state.
Definition: states.h:88
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:64
ket mket(const std::vector< idx > &mask, const std::vector< idx > &dims)
Multi-partite qudit ket.
Definition: functions.h:1453
std::size_t idx
Non-negative integer index, make sure you use an unsigned type.
Definition: types.h:39
ket b10
Bell-10 state, as described in Nielsen and Chuang.
Definition: states.h:72
ket x0
Pauli Sigma-X 0-eigenstate |+>
Definition: states.h:46
cmat py1
Projector onto the Pauli Sigma-Y 1-eigenstate |y-><y-|.
Definition: states.h:60
cmat px1
Projector onto the Pauli Sigma-X 1-eigenstate |-><-|.
Definition: states.h:56
cmat pz1
Projector onto the Pauli Sigma-Z 1-eigenstate |1><1|.
Definition: states.h:64
States()
Definition: states.h:233