The Quantum Exact Simulation Toolkit v4.0.0
Loading...
Searching...
No Matches
qmatrix.cpp
1/** @file
2 * Testing utilities which define 'qmatrix', used
3 * to perform reference complex matrix algebra, and
4 * as a reference proxy to a quantum density matrix.
5 *
6 * @author Tyson Jones
7 */
8
9#include "qmatrix.hpp"
10#include "qvector.hpp"
11#include "macros.hpp"
12
13
14/*
15 * MATRIX CREATION
16 */
17
18qmatrix getZeroMatrix(size_t dim) {
19 DEMAND( dim >= 1 );
20
21 return qmatrix(dim, qvector(dim, 0));
22}
23
24qmatrix getConstantMatrix(size_t dim, qcomp elem) {
25 DEMAND( dim >= 1 );
26
27 return qmatrix(dim, qvector(dim, elem));
28}
29
30qmatrix getIdentityMatrix(size_t dim) {
31 DEMAND( dim >= 1 );
32
33 qmatrix out = getZeroMatrix(dim);
34
35 for (size_t i=0; i<dim; i++)
36 out[i][i] = 1;
37
38 return out;
39}
40
41qmatrix getDiagonalMatrix(qvector v) {
42 DEMAND( v.size() >= 1 );
43
44 qmatrix out = getZeroMatrix(v.size());
45
46 for (size_t i=0; i<v.size(); i++)
47 out[i][i] = v[i];
48
49 return out;
50}
51
52qmatrix getPauliMatrix(int id) {
53 DEMAND( id >= 0 );
54 DEMAND( id <= 3 );
55
56 if (id == 0)
57 return {{1 ,0}, {0, 1}};
58
59 if (id == 1)
60 return {{0, 1}, {1, 0}};
61
62 if (id == 2)
63 return {{0, -1_i}, {1_i, 0}};
64
65 if (id == 3)
66 return {{1, 0}, {0, -1}};
67
68 // unreachable
69 return {{-1}};
70}
71
72
73/*
74 * SCALAR MULTIPLICATION
75 */
76
77qmatrix operator * (const qcomp& a, const qmatrix& m) {
78 qmatrix out = m;
79
80 for (auto& row : out)
81 for (auto& elem : row)
82 elem *= a;
83
84 return out;
85}
86
87qmatrix operator * (const qmatrix& m, const qcomp& a) {
88 return a * m;
89}
90
91qmatrix operator *= (qmatrix& m, const qcomp& a) {
92 m = a * m;
93 return m;
94}
95
96qmatrix operator * (const qreal& a, const qmatrix& m) {
97 return qcomp(a,0) * m;
98}
99
100qmatrix operator * (const qmatrix& m, const qreal& a) {
101 return a * m;
102}
103
104qmatrix operator *= (qmatrix& m, const qreal& a) {
105 m = a * m;
106 return m;
107}
108
109
110/*
111 * SCALAR DIVISION
112 */
113
114qmatrix operator / (const qmatrix& m, const qcomp& a) {
115 DEMAND( std::abs(a) != 0 );
116
117 return (1/a) * m;
118}
119
120qmatrix operator /= (qmatrix& m, const qcomp& a) {
121 m = m / a;
122 return m;
123}
124
125qmatrix operator / (const qmatrix& m, const qreal& a) {
126 return m / qcomp(a,0);
127}
128
129qmatrix operator /= (qmatrix& m, const qreal& a) {
130 m = m / a;
131 return m;
132}
133
134
135/*
136 * MATRIX ADDITION
137 */
138
139qmatrix operator + (const qmatrix& m1, const qmatrix& m2) {
140 DEMAND( m1.size() == m2.size() );
141
142 qmatrix out = m1;
143
144 for (size_t r=0; r<m1.size(); r++)
145 for (size_t c=0; c<m1.size(); c++)
146 out[r][c] += m2[r][c];
147
148 return out;
149}
150
151qmatrix operator += (qmatrix& m1, const qmatrix& m2) {
152 m1 = m1 + m2;
153 return m1;
154}
155
156
157/*
158 * MATRIX SUBTRACTION
159 */
160
161qmatrix operator - (const qmatrix& m1, const qmatrix& m2) {
162 return m1 + (-1 * m2);
163}
164
165qmatrix operator -= (qmatrix& m1, const qmatrix& m2) {
166 m1 = m1 - m2;
167 return m1;
168}
169
170
171/*
172 * MATRIX MULTIPLICATION
173 */
174
175qmatrix operator * (const qmatrix& m1, const qmatrix& m2) {
176 DEMAND( m1.size() > 0 );
177 DEMAND( m2.size() > 0 );
178 DEMAND( m1[0].size() == m2.size() );
179
180 // unlike most functions which assume qmatrix is square,
181 // we cheekily permit m1 and m2 to be non-square (and
182 // ergo differing), necessary to calculate partial traces
183 qmatrix out = qmatrix(m1.size(), qvector(m2[0].size(),0));
184
185 for (size_t r=0; r<out.size(); r++)
186 for (size_t c=0; c<out[0].size(); c++)
187 for (size_t k=0; k<m2.size(); k++)
188 out[r][c] += m1[r][k] * m2[k][c];
189
190 return out;
191}
192
193qmatrix operator *= (qmatrix& m1, const qmatrix& m2) {
194 m1 = m1 * m2;
195 return m1;
196}
197
198
199/*
200 * SETTERS
201 */
202
203void setSubMatrix(qmatrix &dest, qmatrix sub, size_t r, size_t c) {
204 DEMAND( sub.size() > 0 );
205 DEMAND( sub .size() + r <= dest.size() );
206 DEMAND( sub[0].size() + c <= dest.size() );
207
208 // this function cheekily supports when 'sub' is non-square,
209 // which is inconsistent with the preconditions of most of
210 // the qmatrix functions, but is needed by setDensityQuregAmps()
211
212 for (size_t i=0; i<sub.size(); i++)
213 for (size_t j=0; j<sub[i].size(); j++)
214 dest[r+i][c+j] = sub[i][j];
215}
216
217void setSubMatrix(qmatrix &dest, qvector sub, size_t flatInd) {
218 DEMAND( sub.size() + flatInd <= dest.size()*dest.size() );
219
220 for (size_t i=0; i<sub.size(); i++) {
221 size_t r = (i + flatInd) / dest.size(); // floors
222 size_t c = (i + flatInd) % dest.size();
223 dest[r][c] = sub[i];
224 }
225}
226
227void setToDebugState(qmatrix &m) {
228 DEMAND( !m.empty() );
229
230 size_t i = 0;
231
232 // iterate column-wise
233 for (size_t c=0; c<m.size(); c++) {
234 for (size_t r=0; r<m.size(); r++) {
235 m[r][c] = qcomp(2*i/10., (2*i+1)/10.);
236 i++;
237 }
238 }
239}
240
241
242/*
243 * GETTERS
244 */
245
246qvector getDiagonals(qmatrix m) {
247 DEMAND( m.size() > 1 );
248
249 qvector out = getZeroVector(m.size());
250
251 for (size_t i=0; i<out.size(); i++)
252 out[i] = m[i][i];
253
254 return out;
255}
qmatrix getIdentityMatrix(size_t dim)
Definition qmatrix.cpp:30
void setSubMatrix(qmatrix &dest, qmatrix sub, size_t r, size_t c)
Definition qmatrix.cpp:203
qmatrix getZeroMatrix(size_t dim)
Definition qmatrix.cpp:18