ECF 1.5
Quantum.h
1/*
2Quantum.h
3Written by Walter O. Krawec
4
5Copyright (c) 2016 Walter O. Krawec
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
9The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12*/
13
14#ifndef QUANTUM_H_
15#define QUANTUM_H_
16
17#include <vector>
18#include <list>
19
20#include "Algebra.h"
21
22namespace quantum
23{
24 // if empty, assume computational
25 // otherwise B[i][j] is pr. amp of |j> for |i> where |j> is orth. and |i> is from applyOp (not nec. orth.)
26 // that is, |i> is an "e" state and |i> = (B[i][0], B[i][1], ...)
27 struct Basis
28 {
29 std::vector < std::vector < Complex > > B;
30 void orthoganalize();
31
32 Complex innerProduct(std::vector<Complex>& a, std::vector<Complex>& b)
33 {
34 Complex sum = 0 + 0*I;
35
36 for(unsigned int i=0; i<a.size(); ++i)
37 {
38 Complex c = b[i], d;
39 c = creal(b[i]) - cimag(b[i])*I;
40 d = a[i] * c;
41
42 sum = sum + d;
43 }
44 return sum;
45 }
46
47 double norm(std::vector <Complex>& a)
48 {
49 double sum = 0;
50 Complex b,c;
51 for(unsigned int i=0; i<a.size(); ++i)
52 {
53 c = a[i];
54 c = creal(a[i]) - cimag(a[i])*I;
55 b = a[i] * c;
56 sum = sum + creal(b);
57 }
58 return sqrt(sum);
59 }
60 };
61
62 struct KetBra
63 {
64 KetBra() {p = 0;};
65 KetBra(int n)
66 {
67 ket.resize(n);
68 bra.resize(n);
69 for(int i=0; i<n; ++i)
70 {
71 ket[i] = 0;
72 bra[i] = 0;
73 }
74 p = 0;
75 };
76
77 void project() // takes |ket> and creates |ket><bra| (ignores "p")
78 {
79 bra = ket;
80 return;
81 for(unsigned int i=0; i<ket.size(); ++i)
82 bra[i] = ket[i];
83 }
84
85 void print(std::ostream& f)
86 {
87 f << "(" << creal(p) << "+" << cimag(p) << "i)|";
88 for(unsigned int i=0; i<ket.size(); ++i)
89 f << ket[i] << ",";
90 f << "><";
91 for(unsigned int i=0; i<bra.size(); ++i)
92 f << bra[i] << ",";
93 f << "|";
94 }
95
96 Complex trace(std::vector <Basis>& basis);
97 Complex trace();
98
99 std::vector <int> ket, bra;
100 Complex p;
101 };
102
104 {
105 public:
106 // startSpace and endSpace index which spaces the operator should act on;
107 // output is assumed startSpace, startSpace+1, ..., endSpace (one extra space used).
108 void applyOp(int space); // assume endSpace = space+1
109 void applyOp(int startSpace, int endSpace);
110
111 void applyOp(int space1, int space2, Basis& op);
112 void applyOp(int space1, int space2, int space3, Basis& op);
113
114 void applyOp(int space, algebra::mat& U);
115 void applyOp(algebra::mat& U, int transitSpace);
116 // applies "U" to space "space" if the state of "condSpace" is "cond" (i.e., applies a controlled "U")
117 void applyConditionalOp(int condSpace, int cond, int space, algebra::mat& U);
118
119 void swap(int space1, int space2);
120 void measureAndSave(int measureSpace, int saveSpace);
121 void measure(int measureSpace);
122
123 double SafeLog(double x)
124 {
125 if(x < 0.0000001)
126 return 0;
127 return log(x) / log(2.0);
128 }
129 double ShannonEntropy(); // computes entropy of diagonal elements
130 double entropy(); // computes von Neumann entropy
131
132 double calculatePr(int measureSpace, int state);
133 double calculatePr(int space1, int state1, int space2, int state2);
134 double calculatePr(const std::vector <int>& spaceList, const std::vector <int>& stateList);
135
136 // takes p and creates p1*p|0> + p2*p|1> (where |0>,|1> are in "space"); assumes "space" is |0>
137 void splitAndSave(double p1, double p2, int space);
138
139 void computeDensityMat(algebra::mat& output);
140 void computeDensityMat(std::vector <Basis>& basis, algebra::mat& output);
142
143 void trace(int space, DensityList& output);
144 void trace(int space);
145 double trace();
146 void project(int space, int state, DensityList& output);
147 void project(int space, int state);
148 void CNOT(int controlSpace, int targetSpace);
149 void NOT(int space);
150
151 void applyHadamard(int space);
152 void applyRotation(int space, double rotation);
153 void applySU2(int space, double p, double theta, double psi);
154
155
156 // Added Mar. 19 for new project
157 void applyHadamard(int target, int control);
158 void applyNOT(int target, int control);
159 void applyPiOver8(int target, int control);
160 void applySU2(int target, int control, double p, double theta, double psi);
161
162 // the following sets targetSpace = targetVal (for all elements in vector) if condSpace = condVal (for each ket and bra separately - measure afterwards)
163 // be careful when using the procedure...
164 void conditionalSet(std::vector <int>& targetSpace, std::vector <int>& targetVal, std::vector <int>& condSpace, std::vector <int>& condVal);
165
166 void print(std::ostream& f)
167 {
168 std::list <KetBra>::iterator Iter;
169 bool first = true;
170 for(Iter = density.begin(); Iter != density.end(); ++Iter)
171 {
172 if(creal(Iter->p) == 0 && cimag(Iter->p) == 0) continue;
173 if(!first)
174 f << " + ";
175 first = false;
176 Iter->print(f);
177 }
178
179 std::cout << "\n\n";
180 }
181 //private:
182 std::vector <int> dimension;
183 std::list <KetBra> density;
184 };
185}
186
187#endif
void computeDensityMatFast(algebra::mat &output)
Definition: Quantum.cpp:1062