Testing utilities which perform linear algebra routines upon reference qvector and qmatrix. These are slow, serial, un-optimised, defensively- designed routines.
More...
|
| int | getBitAt (qindex num, int ind) |
| |
| vector< int > | getBits (qindex num, int numBits) |
| |
| qindex | getBitsAt (qindex num, vector< int > inds) |
| |
| qmatrix | getConjugate (qmatrix) |
| |
| qmatrix | getConjugateTranspose (qmatrix) |
| |
| qmatrix | getControlledMatrix (qmatrix matrix, int numCtrls) |
| |
| qvector | getDiscreteFourierTransform (qvector in, bool inverse) |
| |
| qvector | getDiscreteFourierTransform (qvector in, vector< int > targs, bool inverse) |
| |
| qmatrix | getExponentialOfDiagonalMatrix (qmatrix) |
| |
| qmatrix | getExponentialOfNormalisedPauliVector (qreal arg, qreal x, qreal y, qreal z) |
| |
| qmatrix | getExponentialOfPauliMatrix (qcomp arg, qmatrix pauli) |
| |
| qcomp | getInnerProduct (qvector bra, qvector ket) |
| |
| qmatrix | getKroneckerProduct (qmatrix, int count) |
| |
| qmatrix | getKroneckerProduct (qmatrix, qmatrix) |
| |
| qmatrix | getKroneckerProduct (vector< qmatrix >) |
| |
| int | getLog2 (qindex) |
| |
| qmatrix | getMixture (vector< qmatrix > densmatrs, vector< qreal > probs) |
| |
| qmatrix | getMixture (vector< qvector > statevecs, vector< qreal > probs) |
| |
| qvector | getNormalised (qvector) |
| |
| qindex | getNumPermutations (int n, int k) |
| |
| qmatrix | getOrthonormalisedRows (qmatrix) |
| |
| qmatrix | getOuterProduct (qvector ket, qvector bra) |
| |
| qmatrix | getPartialTrace (qmatrix matrix, vector< int > targets) |
| |
| qindex | getPow2 (int) |
| |
| qmatrix | getPowerOfDiagonalMatrix (qmatrix diag, qcomp power) |
| |
| qmatrix | getProjector (int outcome) |
| |
| qmatrix | getProjector (vector< int > targets, vector< int > outcomes, int numQubits) |
| |
| qcomp | getSum (qvector) |
| |
| qreal | getSum (vector< qreal > vec) |
| |
| qmatrix | getSuperOperator (vector< qmatrix >) |
| |
| qcomp | getTrace (qmatrix) |
| |
| qmatrix | getTranspose (qmatrix) |
| |
| bool | isApproxCPTP (vector< qmatrix >) |
| |
| bool | isApproxUnitary (qmatrix) |
| |
| bool | isDiagonal (qmatrix) |
| |
| qvector | operator* (const qmatrix &, const qvector &) |
| |
| qindex | setBitAt (qindex num, int ind, int bit) |
| |
| qindex | setBitsAt (qindex num, vector< int > inds, qindex bits) |
| |
Testing utilities which perform linear algebra routines upon reference qvector and qmatrix. These are slow, serial, un-optimised, defensively- designed routines.
◆ getBitAt()
| int getBitAt |
( |
qindex | num, |
|
|
int | ind ) |
Definition at line 48 of file linalg.cpp.
48 {
49 DEMAND( num >= 0 );
50
51 return (num >> ind) & 1;
52}
◆ getBits()
| vector< int > getBits |
( |
qindex | num, |
|
|
int | numBits ) |
Definition at line 55 of file linalg.cpp.
55 {
56 DEMAND( numBits > 0 );
57
58
59 vector<int> out(numBits);
60
61 for (int i=0; i<numBits; i++)
62 out[i] = getBitAt(num, i);
63
64 return out;
65}
◆ getBitsAt()
| qindex getBitsAt |
( |
qindex | num, |
|
|
vector< int > | inds ) |
Definition at line 68 of file linalg.cpp.
68 {
69 DEMAND( num >= 0 );
70
71 qindex out = 0;
72
73 for (size_t i=0; i<inds.size(); i++)
74 out |= getBitAt(num, inds[i]) << i;
75
76 return out;
77}
◆ getConjugate()
| qmatrix getConjugate |
( |
qmatrix | m | ) |
|
Definition at line 283 of file linalg.cpp.
283 {
284
285 for (auto& row : m)
286 for (auto& elem : row)
287 elem = std::conj(elem);
288
289 return m;
290}
◆ getConjugateTranspose()
| qmatrix getConjugateTranspose |
( |
qmatrix | m | ) |
|
Definition at line 293 of file linalg.cpp.
293 {
294 DEMAND( m.size() > 0 );
295
296
297
298
299
300
301 qmatrix out(m[0].size(), qvector(m.size()));
302
303 for (size_t r=0; r<out.size(); r++)
304 for (size_t c=0; c<out[0].size(); c++)
305 out[r][c] = std::conj(m[c][r]);
306
307 return out;
308}
◆ getControlledMatrix()
| qmatrix getControlledMatrix |
( |
qmatrix | matrix, |
|
|
int | numCtrls ) |
Definition at line 453 of file linalg.cpp.
453 {
454
455 size_t dim = getPow2(numCtrls) * matrix.size();
456 size_t off = dim - matrix.size();
457
460
461 return out;
462}
qmatrix getIdentityMatrix(size_t dim)
void setSubMatrix(qmatrix &dest, qmatrix sub, size_t r, size_t c)
◆ getDiscreteFourierTransform() [1/2]
| qvector getDiscreteFourierTransform |
( |
qvector | in, |
|
|
bool | inverse ) |
Definition at line 162 of file linalg.cpp.
162 {
163 DEMAND( in.size() > 0 );
164
165 size_t dim = in.size();
166 qvector out = getZeroVector(dim);
167
168
169 qreal pi = 3.14159265358979323846;
170 qreal a = 1 / std::sqrt(dim);
171 qreal b = (inverse ? -1 : 1) * 2 * pi / dim;
172
173 for (size_t x=0; x<dim; x++)
174 for (size_t y=0; y<dim; y++)
175 out[x] += a * std::exp(b * x * y * 1_i) * in[y];
176
177 return out;
178}
◆ getDiscreteFourierTransform() [2/2]
| qvector getDiscreteFourierTransform |
( |
qvector | in, |
|
|
vector< int > | targs, |
|
|
bool | inverse ) |
Definition at line 181 of file linalg.cpp.
181 {
182 DEMAND( in.size() > 0 );
183
184 size_t dim = in.size();
185 qvector out = getZeroVector(dim);
186
187 qindex len = getPow2(targs.size());
188 qreal pi = 3.14159265358979323846;
189 qreal a = 1 / std::sqrt(len);
190 qreal b = (inverse ? -1 : 1) * 2 * pi / len;
191
192 for (size_t i=0; i<dim; i++) {
193 size_t x = getBitsAt(i, targs);
194 for (size_t y=0; y<len; y++) {
195 qindex j = setBitsAt(i, targs, y);
196 out[j] += a * std::exp(b * x * y * 1_i) * in[i];
197 }
198 }
199
200 return out;
201}
◆ getExponentialOfDiagonalMatrix()
| qmatrix getExponentialOfDiagonalMatrix |
( |
qmatrix | m | ) |
|
Definition at line 338 of file linalg.cpp.
338 {
339 DEMAND( isDiagonal(m) );
340
342
343 for (size_t i=0; i<m.size(); i++)
344 out[i][i] = std::exp(m[i][i]);
345
346 return out;
347}
qmatrix getZeroMatrix(size_t dim)
◆ getExponentialOfNormalisedPauliVector()
| qmatrix getExponentialOfNormalisedPauliVector |
( |
qreal | arg, |
|
|
qreal | x, |
|
|
qreal | y, |
|
|
qreal | z ) |
Definition at line 359 of file linalg.cpp.
359 {
360
361
362 qreal n = std::sqrt(x*x + y*y + z*z);
363 x /= n;
364 y /= n;
365 z /= n;
366
368 qmatrix out = std::cos(arg/2)*id - 1_i*std::sin(arg/2)*(
369 x * getPauliMatrix(1) +
370 y * getPauliMatrix(2) +
371 z * getPauliMatrix(3));
372
373 return out;
374}
◆ getExponentialOfPauliMatrix()
| qmatrix getExponentialOfPauliMatrix |
( |
qcomp | arg, |
|
|
qmatrix | pauli ) |
Definition at line 350 of file linalg.cpp.
350 {
351
352
354 qmatrix out = std::cos(arg/2)*id - 1_i*std::sin(arg/2)*m;
355 return out;
356}
◆ getInnerProduct()
| qcomp getInnerProduct |
( |
qvector | bra, |
|
|
qvector | ket ) |
Definition at line 210 of file linalg.cpp.
210 {
211 DEMAND( bra.size() == ket.size() );
212
213 qcomp out = 0;
214
215 for (size_t i=0; i<bra.size(); i++)
216 out += std::conj(bra[i]) * ket[i];
217
218 return out;
219}
◆ getKroneckerProduct() [1/3]
| qmatrix getKroneckerProduct |
( |
qmatrix | m, |
|
|
int | count ) |
Definition at line 561 of file linalg.cpp.
561 {
562 DEMAND( count >= 1 );
563
565
566 for (int n=0; n<count; n++)
568
569 return out;
570}
qmatrix getKroneckerProduct(qmatrix a, qmatrix b)
◆ getKroneckerProduct() [2/3]
| qmatrix getKroneckerProduct |
( |
qmatrix | a, |
|
|
qmatrix | b ) |
Definition at line 525 of file linalg.cpp.
525 {
526
527
528
529
530
531
532 size_t aRows = a.size();
533 size_t bRows = b.size();
534 size_t aCols = a[0].size();
535 size_t bCols = b[0].size();
536
537 qmatrix out(aRows * bRows, qvector(aCols * bCols));
538
539 for (size_t r=0; r<bRows; r++)
540 for (size_t c=0; c<bCols; c++)
541 for (size_t i=0; i<aRows; i++)
542 for (size_t j=0; j<aCols; j++)
543 out[r+bRows*i][c+bCols*j] = a[i][j] * b[r][c];
544
545 return out;
546}
◆ getKroneckerProduct() [3/3]
| qmatrix getKroneckerProduct |
( |
vector< qmatrix > | matrices | ) |
|
Definition at line 549 of file linalg.cpp.
549 {
550
552
553
554 for (auto& m : matrices)
556
557 return out;
558}
◆ getLog2()
Definition at line 29 of file linalg.cpp.
29 {
30 DEMAND( a >= 0 );
31 DEMAND( (a & (a - 1)) == 0 );
32
33 int n = 0;
34 while (a >>= 1)
35 n++;
36
37 return n;
38}
◆ getMixture() [1/2]
| qmatrix getMixture |
( |
vector< qmatrix > | densmatrs, |
|
|
vector< qreal > | probs ) |
Definition at line 465 of file linalg.cpp.
465 {
466 DEMAND( densmatrs.size() > 0 );
467
469 for (size_t i=0; i<densmatrs.size(); i++)
470 out += probs[i] * densmatrs[i];
471
472 return out;
473}
◆ getMixture() [2/2]
| qmatrix getMixture |
( |
vector< qvector > | statevecs, |
|
|
vector< qreal > | probs ) |
Definition at line 476 of file linalg.cpp.
476 {
477
478 vector<qmatrix> densmatrs(statevecs.size());
479 for (size_t i=0; i<statevecs.size(); i++)
480 densmatrs[i] = getOuterProduct(statevecs[i], statevecs[i]);
481
482 return getMixture(densmatrs, probs);
483}
◆ getNormalised()
| qvector getNormalised |
( |
qvector | vec | ) |
|
Definition at line 145 of file linalg.cpp.
145 {
146
147
148 vector<qreal> probs(vec.size());
149 for (size_t i=0; i<vec.size(); i++)
150 probs[i] = std::norm(vec[i]);
151
152
153 qreal norm = getSum(probs);
154 qreal fac = 1 / std::sqrt(norm);
155 for (auto& x : vec)
156 x *= fac;
157
158 return vec;
159}
◆ getNumPermutations()
| qindex getNumPermutations |
( |
int | n, |
|
|
int | k ) |
Definition at line 97 of file linalg.cpp.
97 {
98 DEMAND( n >= k );
99
100 constexpr auto max = std::numeric_limits<qindex>::max();
101
102
103 qindex p = 1;
104 for (int t=n-k+1; t<=n; t++)
105 p *= (p < max / t)? t : 0;
106
107 return p;
108}
◆ getOrthonormalisedRows()
| qmatrix getOrthonormalisedRows |
( |
qmatrix | matr | ) |
|
Definition at line 377 of file linalg.cpp.
377 {
378
379
380 for (size_t i=0; i<matr.size(); i++) {
381 qvector row = matr[i];
382
383
384 for (int k=i-1; k>=0; k--) {
385
386
387 qcomp prod = getInnerProduct(matr[k], row);
388
389
390 matr[i] -= prod * matr[k];
391 }
392
393
394 matr[i] = getNormalised(matr[i]);
395 }
396
397
398 return matr;
399}
◆ getOuterProduct()
| qmatrix getOuterProduct |
( |
qvector | ket, |
|
|
qvector | bra ) |
Definition at line 222 of file linalg.cpp.
222 {
223 DEMAND( bra.size() == ket.size() );
224
226
227 for (size_t i=0; i<ket.size(); i++)
228 for (size_t j=0; j<ket.size(); j++)
229 out[i][j] = ket[i] * std::conj(bra[j]);
230
231 return out;
232}
◆ getPartialTrace()
| qmatrix getPartialTrace |
( |
qmatrix | matrix, |
|
|
vector< int > | targets ) |
Definition at line 424 of file linalg.cpp.
424 {
425 DEMAND( in.size() > getPow2(targets.size()) );
426
427 auto numTargs = targets.size();
428 auto numQubits = getLog2(in.size());
429 auto numTargVals = getPow2(numTargs);
430
432
433 for (qindex v=0; v<numTargVals; v++) {
434
435
437 for (size_t t=0; t<numTargs; t++) {
438 int bit = getBitAt(v, t);
439 matrices[targets[t]] = {
440 {bit? 0.:1.},
441 {bit? 1.:0.}};
442 }
443
446 out += bra * in * ket;
447 }
448
449 return out;
450}
qmatrix getConjugateTranspose(qmatrix m)
◆ getPow2()
Definition at line 41 of file linalg.cpp.
41 {
42 DEMAND( a >= 0 );
43
44 return ((qindex) 1) << a;
45}
◆ getPowerOfDiagonalMatrix()
| qmatrix getPowerOfDiagonalMatrix |
( |
qmatrix | diag, |
|
|
qcomp | power ) |
Definition at line 311 of file linalg.cpp.
311 {
312 DEMAND( isDiagonal(m) );
313
315
316
317
318
319
320
321
322 for (size_t i=0; i<m.size(); i++) {
323 bool mIsRe = std::imag(m[i][i]) == 0;
324 bool mIsNeg = std::real(m[i][i]) < 0;
325 bool pIsRe = std::imag(p) == 0;
326 bool pIsInt = std::trunc(std::real(p)) == std::real(p);
327
328
329 out[i][i] = (mIsRe && mIsNeg && pIsRe && pIsInt)?
330 qcomp(std::pow(std::real(m[i][i]), std::real(p)),0):
331 std::pow(m[i][i], p);
332 }
333
334 return out;
335}
◆ getProjector() [1/2]
| qmatrix getProjector |
( |
int | outcome | ) |
|
Definition at line 402 of file linalg.cpp.
402 {
403 DEMAND( outcome == 0 || outcome == 1 );
404
406 out[outcome][outcome] = 1.;
407 return out;
408}
◆ getProjector() [2/2]
| qmatrix getProjector |
( |
vector< int > | targets, |
|
|
vector< int > | outcomes, |
|
|
int | numQubits ) |
Definition at line 411 of file linalg.cpp.
411 {
412 DEMAND( targets.size() == outcomes.size() );
413 DEMAND( numQubits > *std::max_element(targets.begin(), targets.end()) );
414
415
417 for (size_t i=0; i<targets.size(); i++)
418 matrices[targets[i]] = getProjector(outcomes[i]);
419
421}
◆ getSum() [1/2]
| qcomp getSum |
( |
qvector | vec | ) |
|
Definition at line 117 of file linalg.cpp.
117 {
118
119 qcomp sum = qcomp(0,0);
120 qcomp y, t, c=sum;
121
122
123 for (auto& x : vec) {
124 y = x - c;
125 t = sum + y;
126 c = ( t - sum ) - y;
127 sum = t;
128 }
129
130 return sum;
131}
◆ getSum() [2/2]
| qreal getSum |
( |
vector< qreal > | vec | ) |
|
Definition at line 134 of file linalg.cpp.
134 {
135
136
137 qvector in = getZeroVector(vec.size());
138 for (size_t i=0; i<in.size(); i++)
139 in[i] = qcomp(vec[i],0);
140
141 return std::real(getSum(in));
142}
◆ getSuperOperator()
| qmatrix getSuperOperator |
( |
vector< qmatrix > | matrices | ) |
|
Definition at line 486 of file linalg.cpp.
486 {
487 DEMAND( matrices.size() > 0 );
488
489 size_t dim = matrices[0].size();
490
491
493 for (auto& matr : matrices)
495
496 return out;
497}
◆ getTrace()
| qcomp getTrace |
( |
qmatrix | m | ) |
|
Definition at line 261 of file linalg.cpp.
261 {
262
263 qcomp out = 0;
264 for (size_t r=0; r<m.size(); r++)
265 out += m[r][r];
266
267 return out;
268}
◆ getTranspose()
| qmatrix getTranspose |
( |
qmatrix | m | ) |
|
Definition at line 271 of file linalg.cpp.
271 {
272
274
275 for (size_t r=0; r<m.size(); r++)
276 for (size_t c=0; c<m.size(); c++)
277 out[r][c] = m[c][r];
278
279 return out;
280}
◆ isApproxCPTP()
| bool isApproxCPTP |
( |
vector< qmatrix > | matrices | ) |
|
Definition at line 579 of file linalg.cpp.
579 {
580 DEMAND( matrices.size() >= 1 );
581
582 size_t dim = matrices[0].size();
585
586 for (auto& m : matrices)
588
589 return doMatricesAgree(sum, id);
590}
◆ isApproxUnitary()
| bool isApproxUnitary |
( |
qmatrix | m | ) |
|
Definition at line 252 of file linalg.cpp.
252 {
253
254
257 return doMatricesAgree(md, id);
258}
◆ isDiagonal()
| bool isDiagonal |
( |
qmatrix | m | ) |
|
Definition at line 241 of file linalg.cpp.
241 {
242
243 for (size_t r=0; r<m.size(); r++)
244 for (size_t c=0; c<m.size(); c++)
245 if (r!=c && m[r][c] != 0_i)
246 return false;
247
248 return true;
249}
◆ operator*()
| qvector operator* |
( |
const qmatrix & | m, |
|
|
const qvector & | v ) |
Definition at line 506 of file linalg.cpp.
506 {
507 DEMAND( m.size() == v.size() );
508
509 qvector out = getZeroVector(v.size());
510
511 for (size_t r=0; r<v.size(); r++)
512 for (size_t c=0; c<v.size(); c++)
513 out[r] += m[r][c] * v[c];
514
515 return out;
516}
◆ setBitAt()
| qindex setBitAt |
( |
qindex | num, |
|
|
int | ind, |
|
|
int | bit ) |
Definition at line 80 of file linalg.cpp.
80 {
81 DEMAND( num >= 0 );
82
83 qindex one = 1;
84 return (num & ~(one << ind)) | (bit << ind);
85}
◆ setBitsAt()
| qindex setBitsAt |
( |
qindex | num, |
|
|
vector< int > | inds, |
|
|
qindex | bits ) |
Definition at line 88 of file linalg.cpp.
88 {
89
90 for (size_t i=0; i<inds.size(); i++)
91 num = setBitAt(num, inds[i], getBitAt(bits, i));
92
93 return num;
94}