The Quantum Exact Simulation Toolkit v4.1.0
Loading...
Searching...
No Matches
calculations.cpp
1/** @file
2 * Unit tests of the calculations module.
3 *
4 * @author Tyson Jones
5 *
6 * @defgroup unitcalcs Calculations
7 * @ingroup unittests
8 */
9
10#include "quest.h"
11
12#include <catch2/catch_test_macros.hpp>
13#include <catch2/generators/catch_generators_range.hpp>
14#include <catch2/matchers/catch_matchers_string.hpp>
15#include <catch2/matchers/catch_matchers_floating_point.hpp>
16
17#include "tests/utils/qvector.hpp"
18#include "tests/utils/qmatrix.hpp"
19#include "tests/utils/compare.hpp"
20#include "tests/utils/convert.hpp"
21#include "tests/utils/evolve.hpp"
22#include "tests/utils/linalg.hpp"
23#include "tests/utils/lists.hpp"
24#include "tests/utils/macros.hpp"
25#include "tests/utils/random.hpp"
26#include "tests/utils/cache.hpp"
27#include "tests/utils/measure.hpp"
28
29#include <vector>
30#include <algorithm>
31#include <type_traits>
32
33using Catch::Matchers::ContainsSubstring;
34using std::vector;
35
36
37
38/*
39 * UTILITIES
40 */
41
42
43#define TEST_CATEGORY \
44 LABEL_UNIT_TAG "[calculations]"
45
46
47void TEST_ON_CACHED_QUREGS(quregCache cache, auto refState, auto apiFunc, auto refFunc) {
48
49 for (auto& [label, qureg]: cache) {
50
51 DYNAMIC_SECTION( label ) {
52
53 // we initialise to a valid pure or mixed state, rather than the
54 // debug state, since many API functions validate the output domain
55 // which is often invalid for unnormalised states
56 setToRandomState(refState);
57 setQuregToReference(qureg, refState);
58
59 /// @todo
60 /// validate that above is correct, i.e. not the all-zero
61 /// state, which would permit flawed tests to succeed
62
63 // results can be a scalar, a vector, or even a Qureg & qmatrix/qvector
64 auto apiResult = apiFunc(qureg);
65 auto refResult = refFunc(refState);
66 REQUIRE_AGREE( apiResult, refResult );
67
68 // free API result if it is a newly created Qureg
69 if constexpr (std::is_same_v<decltype(apiResult),Qureg>)
70 destroyQureg(apiResult);
71 }
72 }
73}
74
75void TEST_ON_CACHED_STATEVECS_AND_DENSMATRS(auto apiFunc, auto refFunc) {
76 SECTION( LABEL_STATEVEC ) { TEST_ON_CACHED_QUREGS(getCachedStatevecs(), getRefStatevec(), apiFunc, refFunc); }
77 SECTION( LABEL_DENSMATR ) { TEST_ON_CACHED_QUREGS(getCachedDensmatrs(), getRefDensmatr(), apiFunc, refFunc); }
78}
79
80#define TEST_ALL_QUREGS( quregVar, apiExpr, stateVar, refExpr ) \
81 TEST_ON_CACHED_STATEVECS_AND_DENSMATRS( \
82 [&](Qureg quregVar) { return apiExpr; }, \
83 [&](auto& stateVar) { return refExpr; } ) \
84
85
86void TEST_ON_MIXED_CACHED_QUREGS(quregCache cacheA, quregCache cacheB, auto refA, auto refB, auto apiFunc, auto refFunc) {
87
88 // test all combinations of deployments (where cacheA != cacheB)
89
90 for (auto& [labelA, quregA]: cacheA) {
91 for (auto& [labelB, quregB]: cacheB) {
92
93 // skip illegal (local densitymatrix, distributed statevector) combo
94 if (quregA.isDensityMatrix != quregB.isDensityMatrix && // (sv,dm) or (dm,sv)
95 quregA.isDistributed != quregB.isDistributed && // differing distributions
96 quregA.isDistributed == quregB.isDensityMatrix) // dm.dist=0
97 continue;
98
99 // skip illegal same-size different-GPU-accel combo
100 if (quregA.isDensityMatrix == quregB.isDensityMatrix && // (sv,sv) or (dm,dm)
101 quregA.isGpuAccelerated != quregB.isGpuAccelerated) // differing GPU-accel
102 continue;
103
104 DYNAMIC_SECTION( labelA + LABEL_DELIMITER + labelB ) {
105
106 // initialise to random states (rather than debug) since
107 // tested function will likely validate output domain
108 setToRandomState(refA); setQuregToReference(quregA, refA);
109 setToRandomState(refB); setQuregToReference(quregB, refB);
110
111 // results will always be a scalar
112 auto apiResult = apiFunc(quregA, quregB);
113 auto refResult = refFunc(refA, refB);
114 REQUIRE_AGREE( apiResult, refResult );
115 }
116 }
117 }
118}
119
120
121void TEST_ON_CACHED_QUREG_AND_MATRIX(quregCache quregs, matrixCache matrices, auto apiFunc, auto refState, auto refMatr, auto refFunc) {
122
123 // test all combinations of deployments (where cacheA != cacheB)
124
125 for (auto& [labelA, qureg]: quregs) {
126 for (auto& [labelB, matrix]: matrices) {
127
128 // all combinations are legal; none are skipped!
129
130 DYNAMIC_SECTION( labelA + LABEL_DELIMITER + labelB ) {
131
132 // set API matrix to pre-initialised reference matrix
133 setFullStateDiagMatr(matrix, 0, getDiagonals(refMatr));
134
135 // initialise to random states (rather than debug) since
136 // tested function will likely validate output domain
137 setToRandomState(refState);
138 setQuregToReference(qureg, refState);
139
140 // results will always be a scalar
141 auto apiResult = apiFunc(qureg, matrix);
142 auto refResult = refFunc(refState, refMatr);
143 REQUIRE_AGREE( apiResult, refResult );
144 }
145 }
146 }
147}
148
149
150
151/**
152 * TESTS
153 *
154 * @ingroup unitcalcs
155 * @{
156 */
157
158
159
160TEST_CASE( "calcExpecPauliStr", TEST_CATEGORY ) {
161
162 SECTION( LABEL_CORRECTNESS ) {
163
164 int numQubits = getNumCachedQubits();
165 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
166 auto targets = GENERATE_TARGS(numQubits, numTargs);
167
168 PauliStr str = getRandomPauliStr(targets);
169
170 TEST_ALL_QUREGS(
171 qureg, calcExpecPauliStr(qureg, str),
172 state, std::real(getReferenceExpectationValue(state, str))
173 );
174 }
175
176 /// @todo input validation
177}
178
179
180
181TEST_CASE( "calcExpecPauliStrSum", TEST_CATEGORY ) {
182
183 SECTION( LABEL_CORRECTNESS ) {
184
185 int numQubits = getNumCachedQubits();
186 int numTerms = GENERATE_COPY( 1, numQubits, getPow2(2*numQubits) );
187
188 GENERATE( range(0,10) );
189 PauliStrSum sum = createRandomPauliStrSum(numQubits, numTerms);
190
191 TEST_ALL_QUREGS(
192 qureg, calcExpecPauliStrSum(qureg, sum),
193 state, std::real(getReferenceExpectationValue(state, sum))
194 );
195
197 }
198
199 /// @todo input validation
200}
201
202
203
204TEST_CASE( "calcExpecNonHermitianPauliStrSum", TEST_CATEGORY ) {
205
206 SECTION( LABEL_CORRECTNESS ) {
207
208 GENERATE( range(0,10) );
209 int numQubits = getNumCachedQubits();
210 int numTerms = GENERATE_COPY( 1, numQubits, getPow2(2*numQubits) );
211
212 PauliStrSum sum = createRandomNonHermitianPauliStrSum(numQubits, numTerms);
213
214 TEST_ALL_QUREGS(
215 qureg, calcExpecNonHermitianPauliStrSum(qureg, sum),
216 state, getReferenceExpectationValue(state, sum)
217 );
218
220 }
221
222 /// @todo input validation
223}
224
225
226
227TEST_CASE( "calcProbOfBasisState", TEST_CATEGORY ) {
228
229 SECTION( LABEL_CORRECTNESS ) {
230
231 qindex index = GENERATE( range(0, 1 << getNumCachedQubits()) );
232
233 TEST_ALL_QUREGS(
234 qureg, calcProbOfBasisState(qureg, index),
235 state, getReferenceProbability(state, index)
236 );
237 }
238
239 /// @todo input validation
240}
241
242
243
244TEST_CASE( "calcProbOfQubitOutcome", TEST_CATEGORY ) {
245
246 SECTION( LABEL_CORRECTNESS ) {
247
248 int target = GENERATE( range(0, getNumCachedQubits()) );
249 int outcome = GENERATE( 0, 1 );
250
251 TEST_ALL_QUREGS(
252 qureg, calcProbOfQubitOutcome(qureg, target, outcome),
253 state, getReferenceProbability(state, {target}, {outcome})
254 );
255 }
256
257 /// @todo input validation
258}
259
260
261
262TEST_CASE( "calcProbOfMultiQubitOutcome", TEST_CATEGORY ) {
263
264 SECTION( LABEL_CORRECTNESS ) {
265
266 int numQubits = getNumCachedQubits();
267 int numTargs = GENERATE_COPY( range(1, numQubits+1) );
268 auto targets = GENERATE_TARGS(numQubits, numTargs);
269 auto outcomes = getRandomOutcomes(numTargs);
270
271 TEST_ALL_QUREGS(
272 qureg, calcProbOfMultiQubitOutcome(qureg, targets.data(), outcomes.data(), numTargs),
273 state, getReferenceProbability(state, targets, outcomes)
274 );
275 }
276
277 /// @todo input validation
278}
279
280
281
282TEST_CASE( "calcProbsOfAllMultiQubitOutcomes", TEST_CATEGORY ) {
283
284 SECTION( LABEL_CORRECTNESS ) {
285
286 int numQubits = getNumCachedQubits();
287 int numTargs = GENERATE_COPY( range(1,numQubits+1) );
288 auto targets = GENERATE_TARGS(numQubits, numTargs);
289
290 auto apiFunc = [&](Qureg qureg) {
291 vector<qreal> out(getPow2(numTargs));
292 calcProbsOfAllMultiQubitOutcomes(out.data(), qureg, targets.data(), numTargs);
293 return out;
294 };
295 auto refFunc = [&](auto& state) {
296 return getAllReferenceProbabilities(state, targets);
297 };
298
299 TEST_ON_CACHED_STATEVECS_AND_DENSMATRS( apiFunc, refFunc );
300 }
301
302 /// @todo input validation
303}
304
305
306
307TEST_CASE( "calcTotalProb", TEST_CATEGORY ) {
308
309 SECTION( LABEL_CORRECTNESS ) {
310
311 GENERATE( range(0,100) );
312
313 TEST_ALL_QUREGS(
314 qureg, calcTotalProb(qureg),
315 state, getReferenceProbability(state)
316 );
317 }
318
319 /// @todo input validation
320}
321
322
323
324TEST_CASE( "calcPurity", TEST_CATEGORY ) {
325
326 SECTION( LABEL_CORRECTNESS ) {
327
328 GENERATE( range(0,100) );
329
330 TEST_ALL_QUREGS(
331 qureg, calcPurity(qureg),
332 state, getReferencePurity(state)
333 );
334 }
335
336 /// @todo input validation
337}
338
339
340
341/// @private
342int getMaxNumTracedQubits(int numQubits) {
343
344 // cannot reduce all qubits, nor so many that the final qureg is
345 // illegally distributed (which we enforce even upon the testsed
346 // non-distributed Quregs for simplicity)
347
348 return std::min(
349 numQubits - 1,
350 numQubits - getLog2(getQuESTEnv().numNodes));
351}
352
353
354TEST_CASE( "calcPartialTrace", TEST_CATEGORY ) {
355
356 // no statevector equivalent
357
358 SECTION( LABEL_CORRECTNESS ) {
359
360 SECTION( LABEL_DENSMATR ) {
361
362 int numQubits = getNumCachedQubits();
363 int maxNumTargs = getMaxNumTracedQubits(numQubits);
364 int numTargs = GENERATE_COPY( range(1,maxNumTargs+1) );
365 auto targets = GENERATE_TARGS(numQubits, numTargs);
366
367 auto apiFunc = [&](Qureg qureg) { return calcPartialTrace(qureg, targets.data(), numTargs); };
368 auto refFunc = [&](qmatrix ref) { return getPartialTrace(ref, targets); };
369
370 TEST_ON_CACHED_QUREGS(getCachedDensmatrs(), getRefDensmatr(), apiFunc, refFunc);
371 }
372 }
373
374 /// @todo input validation
375}
376
377
378
379TEST_CASE( "calcReducedDensityMatrix", TEST_CATEGORY ) {
380
381 // no statevector equivalent
382
383 SECTION( LABEL_CORRECTNESS ) {
384
385 SECTION( LABEL_DENSMATR ) {
386
387 int numQubits = getNumCachedQubits();
388 int maxNumTraced = getMaxNumTracedQubits(numQubits);
389 int minNumRetained = numQubits - maxNumTraced;
390 int maxNumRetained = numQubits - 1;
391 int numRetained = GENERATE_COPY( range(minNumRetained, maxNumRetained+1) );
392 auto retains = GENERATE_TARGS(numQubits, numRetained);
393 auto targets = getComplement(getRange(numQubits), retains);
394
395 auto apiFunc = [&](Qureg qureg) { return calcReducedDensityMatrix(qureg, retains.data(), numRetained); };
396 auto refFunc = [&](qmatrix ref) { return getPartialTrace(ref, targets); };
397
398 TEST_ON_CACHED_QUREGS(getCachedDensmatrs(), getRefDensmatr(), apiFunc, refFunc);
399 }
400 }
401
402 /// @todo input validation
403}
404
405
406
407TEST_CASE( "calcInnerProduct", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
408
409 SECTION( LABEL_CORRECTNESS ) {
410
411 qvector refSV = getRefStatevec();
412 qmatrix refDM = getRefDensmatr();
413 auto apiFunc = calcInnerProduct;
414
415 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
416
417 SECTION( LABEL_STATEVEC LABEL_DELIMITER LABEL_STATEVEC ) {
418
419 // <a|b>
420 auto refFunc = [&](qvector a, qvector b) { return getInnerProduct (a,b); };
421
422 TEST_ON_MIXED_CACHED_QUREGS( getCachedStatevecs(), getAltCachedStatevecs(), refSV, refSV, apiFunc, refFunc );
423 }
424
425 SECTION( LABEL_STATEVEC LABEL_DELIMITER LABEL_DENSMATR ) {
426
427 // <A|B|A>
428 auto refFunc = [&](qvector a, qmatrix b) { return getInnerProduct(a, b * a); };
429
430 TEST_ON_MIXED_CACHED_QUREGS( getCachedStatevecs(), getAltCachedDensmatrs(), refSV, refDM, apiFunc, refFunc );
431 }
432
433 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_STATEVEC ) {
434
435 // <B|A^dagger|B>
436
437 auto refFunc = [&](qmatrix a, qvector b) { return getInnerProduct(b, getConjugateTranspose(a) * b); };
438
439 TEST_ON_MIXED_CACHED_QUREGS( getCachedDensmatrs(), getAltCachedStatevecs(), refDM, refSV, apiFunc, refFunc );
440 }
441
442 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_DENSMATR ) {
443
444 // Tr(a^dagger b)
445 auto refFunc = [&](qmatrix a, qmatrix b) { return getTrace(getConjugateTranspose(a) * b); };
446
447 TEST_ON_MIXED_CACHED_QUREGS( getCachedDensmatrs(), getAltCachedDensmatrs(), refDM, refDM, apiFunc, refFunc );
448 }
449 }
450
451 /// @todo input validation
452}
453
454
455
456TEST_CASE( "calcFidelity", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
457
458 SECTION( LABEL_CORRECTNESS ) {
459
460 qvector refSV = getRefStatevec();
461 qmatrix refDM = getRefDensmatr();
462 auto apiFunc = calcFidelity;
463
464 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
465
466 SECTION( LABEL_STATEVEC LABEL_DELIMITER LABEL_STATEVEC ) {
467
468 // |<a|b>|^2
469 auto refFunc = [&](qvector a, qvector b) { return std::norm(getInnerProduct(a,b)); };
470
471 TEST_ON_MIXED_CACHED_QUREGS( getCachedStatevecs(), getAltCachedStatevecs(), refSV, refSV, apiFunc, refFunc );
472 }
473
474 SECTION( LABEL_STATEVEC LABEL_DELIMITER LABEL_DENSMATR ) {
475
476 // Re[<A|B|A>]
477 auto refFunc = [&](qvector a, qmatrix b) { return std::real(getInnerProduct(a, b * a)); };
478
479 TEST_ON_MIXED_CACHED_QUREGS( getCachedStatevecs(), getAltCachedDensmatrs(), refSV, refDM, apiFunc, refFunc );
480 }
481
482 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_STATEVEC ) {
483
484 // Re[<B|A|B>]
485 auto refFunc = [&](qmatrix a, qvector b) { return std::real(getInnerProduct(b, a * b)); };
486
487 TEST_ON_MIXED_CACHED_QUREGS( getCachedDensmatrs(), getAltCachedStatevecs(), refDM, refSV, apiFunc, refFunc );
488 }
489
490 // (densitymatrix, densitymatrix) not supported
491 }
492
493 /// @todo input validation
494}
495
496
497
498TEST_CASE( "calcDistance", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
499
500 SECTION( LABEL_CORRECTNESS ) {
501
502 qvector refSV = getRefStatevec();
503 qmatrix refDM = getRefDensmatr();
504 auto apiFunc = calcDistance;
505
506 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
507
508 SECTION( LABEL_STATEVEC LABEL_DELIMITER LABEL_STATEVEC ) {
509
510 // sqrt(2 - 2 |<A|B>|)
511 auto refFunc = [&](qvector a, qvector b) { return std::sqrt(2 - 2 * std::abs(getInnerProduct(a,b))); };
512
513 TEST_ON_MIXED_CACHED_QUREGS( getCachedStatevecs(), getAltCachedStatevecs(), refSV, refSV, apiFunc, refFunc);
514 }
515
516 SECTION( LABEL_STATEVEC LABEL_DELIMITER LABEL_DENSMATR ) {
517
518 // sqrt(1 - <psi|rho|psi>)
519 auto refFunc = [&](qvector a, qmatrix b) { return std::sqrt(1 - std::real(getInnerProduct(a, b * a))); };
520
521 TEST_ON_MIXED_CACHED_QUREGS( getCachedStatevecs(), getAltCachedDensmatrs(), refSV, refDM, apiFunc, refFunc );
522 }
523
524 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_STATEVEC ) {
525
526 // sqrt(1 - <psi|rho|psi>)
527 auto refFunc = [&](qmatrix a, qvector b) { return std::sqrt(1 - std::real(getInnerProduct(b, a * b))); };
528
529 TEST_ON_MIXED_CACHED_QUREGS( getCachedDensmatrs(), getAltCachedStatevecs(), refDM, refSV, apiFunc, refFunc );
530 }
531
532 SECTION( LABEL_DENSMATR LABEL_DELIMITER LABEL_DENSMATR ) {
533
534 // sqrt(Tr((A-B)(A-B)^dagger)
535 auto refFunc = [&](qmatrix a, qmatrix b) { return std::sqrt(std::real(getTrace((a-b)*getConjugateTranspose(a-b)))); };
536
537 TEST_ON_MIXED_CACHED_QUREGS( getCachedDensmatrs(), getAltCachedDensmatrs(), refDM, refDM, apiFunc, refFunc );
538 }
539 }
540
541 /// @todo input validation
542}
543
544
545
546TEST_CASE( "calcExpecFullStateDiagMatr", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
547
548 SECTION( LABEL_CORRECTNESS ) {
549
550 qmatrix refMatr = getRandomDiagonalHermitian(getNumCachedQubits());
551 auto apiFunc = calcExpecFullStateDiagMatr;
552
553 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
554
555 SECTION( LABEL_STATEVEC ) {
556
557 auto refFunc = [&] (qvector state, qmatrix matr) { return getReferenceExpectationValue(state, matr); };
558
559 TEST_ON_CACHED_QUREG_AND_MATRIX( getCachedStatevecs(), getCachedFullStateDiagMatrs(), apiFunc, getRefStatevec(), refMatr, refFunc);
560 }
561
562 SECTION( LABEL_DENSMATR ) {
563
564 auto refFunc = [&] (qmatrix state, qmatrix matr) { return getReferenceExpectationValue(state, matr); };
565
566 TEST_ON_CACHED_QUREG_AND_MATRIX( getCachedDensmatrs(), getCachedFullStateDiagMatrs(), apiFunc, getRefDensmatr(), refMatr, refFunc);
567 }
568 }
569
570 /// @todo input validation
571}
572
573
574
575TEST_CASE( "calcExpecNonHermitianFullStateDiagMatr", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
576
577 SECTION( LABEL_CORRECTNESS ) {
578
579 qmatrix refMatr = getRandomDiagonalMatrix(getPow2(getNumCachedQubits()));
581
582 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
583
584 SECTION( LABEL_STATEVEC ) {
585
586 auto refFunc = [&] (qvector state, qmatrix matr) { return getReferenceExpectationValue(state, matr); };
587
588 TEST_ON_CACHED_QUREG_AND_MATRIX( getCachedStatevecs(), getCachedFullStateDiagMatrs(), apiFunc, getRefStatevec(), refMatr, refFunc);
589 }
590
591 SECTION( LABEL_DENSMATR ) {
592
593 auto refFunc = [&] (qmatrix state, qmatrix matr) { return getReferenceExpectationValue(state, matr); };
594
595 TEST_ON_CACHED_QUREG_AND_MATRIX( getCachedDensmatrs(), getCachedFullStateDiagMatrs(), apiFunc, getRefDensmatr(), refMatr, refFunc);
596 }
597 }
598
599 /// @todo input validation
600}
601
602
603
604TEST_CASE( "calcExpecFullStateDiagMatrPower", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
605
606 SECTION( LABEL_CORRECTNESS ) {
607
608 qmatrix refMatr = getRandomDiagonalHermitian(getNumCachedQubits());
609
610 // integer and non-integer exponents have different requirements
611 bool isIntegerExp = GENERATE( true, false );
612 qreal exponent = (isIntegerExp)?
613 getRandomInt(-3, 3):
614 getRandomReal(-3, 3);
615
616 // when exponent is non-integer, the matrix cannot contain negative
617 // numbers which otherwise become complex, making the matrix non-
618 // Hermitian and triggering validation
619 if (!isIntegerExp)
620 for (size_t i=0; i<refMatr.size(); i++)
621 refMatr[i][i] = std::abs(std::real(refMatr[i][i]));
622
623 // when exponent is negative, the matrix cannot contain near-zero
624 // magnitude numbers which create divergences and trigger validation.
625 // Negative exponents are particularly unstable (they can produce
626 // very large matrix elements which ergo have less post-decimal
627 // precision and sum catastrophically), so we scale up matrix.
628 if (exponent < 0)
629 for (size_t i=0; i<refMatr.size(); i++)
630 refMatr[i][i] *= 100;
631
632 auto apiFunc = [&](Qureg qureg, FullStateDiagMatr matr) {
633 return calcExpecFullStateDiagMatrPower(qureg, matr, exponent);
634 };
635
636 CAPTURE( exponent );
637
638 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
639
640 SECTION( LABEL_STATEVEC ) {
641
642 auto refFunc = [&] (qvector state, qmatrix matr) {
643 matr = getPowerOfDiagonalMatrix(matr, qcomp(exponent,0));
644 return getReferenceExpectationValue(state, matr);
645 };
646
647 TEST_ON_CACHED_QUREG_AND_MATRIX( getCachedStatevecs(), getCachedFullStateDiagMatrs(), apiFunc, getRefStatevec(), refMatr, refFunc);
648 }
649
650 SECTION( LABEL_DENSMATR ) {
651
652 auto refFunc = [&] (qmatrix state, qmatrix matr) {
653 matr = getPowerOfDiagonalMatrix(matr, qcomp(exponent,0));
654 return getReferenceExpectationValue(state, matr);
655 };
656
657 TEST_ON_CACHED_QUREG_AND_MATRIX( getCachedDensmatrs(), getCachedFullStateDiagMatrs(), apiFunc, getRefDensmatr(), refMatr, refFunc);
658 }
659 }
660
661 /// @todo input validation
662}
663
664
665
666TEST_CASE( "calcExpecNonHermitianFullStateDiagMatrPower", TEST_CATEGORY LABEL_MIXED_DEPLOY_TAG ) {
667
668 SECTION( LABEL_CORRECTNESS ) {
669
670 qmatrix refMatr = getRandomDiagonalMatrix(getPow2(getNumCachedQubits()));
671 qcomp exponent = getRandomComplex();
672
673 auto apiFunc = [&](Qureg qureg, FullStateDiagMatr matr) {
674 return calcExpecNonHermitianFullStateDiagMatrPower(qureg, matr, exponent);
675 };
676
677 CAPTURE( exponent );
678
679 GENERATE( range(0, TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS) );
680
681 SECTION( LABEL_STATEVEC ) {
682
683 auto refFunc = [&] (qvector state, qmatrix matr) {
684 matr = getPowerOfDiagonalMatrix(matr, exponent);
685 return getReferenceExpectationValue(state, matr);
686 };
687
688 TEST_ON_CACHED_QUREG_AND_MATRIX( getCachedStatevecs(), getCachedFullStateDiagMatrs(), apiFunc, getRefStatevec(), refMatr, refFunc);
689 }
690
691 SECTION( LABEL_DENSMATR ) {
692
693 auto refFunc = [&] (qmatrix state, qmatrix matr) {
694 matr = getPowerOfDiagonalMatrix(matr, exponent);
695 return getReferenceExpectationValue(state, matr);
696 };
697
698 TEST_ON_CACHED_QUREG_AND_MATRIX( getCachedDensmatrs(), getCachedFullStateDiagMatrs(), apiFunc, getRefDensmatr(), refMatr, refFunc);
699 }
700 }
701
702 /// @todo input validation
703}
704
705
706
707/** @} (end defgroup) */
qcomp calcInnerProduct(Qureg qureg1, Qureg qureg2)
qreal calcFidelity(Qureg qureg, Qureg other)
qreal calcDistance(Qureg qureg1, Qureg qureg2)
qreal calcExpecFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matr)
qreal calcExpecFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matr, qreal exponent)
qcomp calcExpecNonHermitianFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matr)
qreal calcExpecPauliStrSum(Qureg qureg, PauliStrSum sum)
qcomp calcExpecNonHermitianPauliStrSum(Qureg qureg, PauliStrSum sum)
qcomp calcExpecNonHermitianFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent)
qreal calcExpecPauliStr(Qureg qureg, PauliStr str)
Qureg calcReducedDensityMatrix(Qureg qureg, int *retainQubits, int numRetainQubits)
Qureg calcPartialTrace(Qureg qureg, int *traceOutQubits, int numTraceQubits)
qreal calcProbOfQubitOutcome(Qureg qureg, int qubit, int outcome)
void calcProbsOfAllMultiQubitOutcomes(qreal *outcomeProbs, Qureg qureg, int *qubits, int numQubits)
qreal calcProbOfBasisState(Qureg qureg, qindex index)
qreal calcProbOfMultiQubitOutcome(Qureg qureg, int *qubits, int *outcomes, int numQubits)
qreal calcPurity(Qureg qureg)
qreal calcTotalProb(Qureg qureg)
QuESTEnv getQuESTEnv()
void setFullStateDiagMatr(FullStateDiagMatr out, qindex startInd, qcomp *in, qindex numElems)
Definition matrices.cpp:441
void destroyPauliStrSum(PauliStrSum sum)
Definition paulis.cpp:481
void destroyQureg(Qureg qureg)
Definition qureg.cpp:333
qmatrix getConjugateTranspose(qmatrix m)
Definition linalg.cpp:291
const int TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS
Definition macros.hpp:63
qcomp getRandomComplex()
Definition random.cpp:107
qreal getRandomReal(qreal min, qreal maxExcl)
Definition random.cpp:63
int getRandomInt(int min, int maxExcl)
Definition random.cpp:90
TEST_CASE("calcExpecPauliStr", TEST_CATEGORY)
Definition qureg.h:49