test_state_initialisations.cpp
Go to the documentation of this file.
1 
2 #include "catch.hpp"
3 #include "QuEST.h"
4 #include "utilities.hpp"
5 
6 /* allows concise use of Contains in catch's REQUIRE_THROWS_WITH */
7 using Catch::Matchers::Contains;
8 
9 
10 
15 TEST_CASE( "cloneQureg", "[state_initialisations]" ) {
16 
19 
20  SECTION( "correctness" ) {
21 
22  SECTION( "state-vector" ) {
23 
25 
26  // make sure states start differently
27  initDebugState(vec1);
28  initBlankState(vec2);
29  REQUIRE( !areEqual(vec1, vec2) );
30 
31  // make sure vec2 is changed
32  QVector copy1 = toQVector(vec1);
33  cloneQureg(vec2, vec1);
34  REQUIRE( areEqual(vec1, vec2) );
35 
36  // make sure vec1 unaffected
37  REQUIRE( areEqual(vec1, copy1) );
38 
39  destroyQureg(vec2, QUEST_ENV);
40  }
41  SECTION( "density-matrix" ) {
42 
44 
45  // make sure states start differently
46  initDebugState(mat1);
47  initBlankState(mat2);
48  REQUIRE( !areEqual(mat1, mat2) );
49 
50  // make sure vec2 is changed
51  QMatrix copy1 = toQMatrix(mat1);
52  cloneQureg(mat2, mat1);
53  REQUIRE( areEqual(mat1, mat2) );
54 
55  // make sure vec1 unaffected
56  REQUIRE( areEqual(mat1, copy1) );
57 
58  destroyQureg(mat2, QUEST_ENV);
59  }
60  }
61  SECTION( "input validation" ) {
62 
63  SECTION( "qureg type" ) {
64 
65  REQUIRE_THROWS_WITH( cloneQureg(mat1, vec1), Contains("both be state-vectors") && Contains("density matrices") );
66  REQUIRE_THROWS_WITH( cloneQureg(vec1, mat1), Contains("both be state-vectors") && Contains("density matrices") );
67  }
68  SECTION( "qureg dimensions" ) {
69 
72 
73  REQUIRE_THROWS_WITH( cloneQureg(vec1, vec3), Contains("Dimensions") && Contains("don't match") );
74  REQUIRE_THROWS_WITH( cloneQureg(mat1, mat3), Contains("Dimensions") && Contains("don't match") );
75 
76  destroyQureg(vec3, QUEST_ENV);
77  destroyQureg(mat3, QUEST_ENV);
78  }
79  }
80  destroyQureg(vec1, QUEST_ENV);
81  destroyQureg(mat1, QUEST_ENV);
82 }
83 
84 
85 
90 TEST_CASE( "initBlankState", "[state_initialisations]" ) {
91 
94 
95  SECTION( "correctness" ) {
96 
97  SECTION( "state-vector" ) {
98 
99  initBlankState(vec);
100  REQUIRE( areEqual(vec, QVector(1<<NUM_QUBITS)) );
101  }
102  SECTION( "density-matrix" ) {
103 
104  initBlankState(mat);
105  REQUIRE( areEqual(mat, getZeroMatrix(1<<NUM_QUBITS)) );
106  }
107  }
108  SECTION( "input validation" ) {
109 
110  // no user validation
111  SUCCEED( );
112  }
113  destroyQureg(vec, QUEST_ENV);
114  destroyQureg(mat, QUEST_ENV);
115 }
116 
117 
118 
123 TEST_CASE( "initClassicalState", "[state_initialisations]" ) {
124 
127 
128  SECTION( "correctness" ) {
129 
130  int numInds = (1<<NUM_QUBITS);
131  int ind = GENERATE_COPY( range(0,numInds) );
132 
133  SECTION( "state-vector" ) {
134 
135  initClassicalState(vec, ind);
136  QVector vecRef = QVector(1<<NUM_QUBITS);
137  vecRef[ind] = 1;
138  REQUIRE( areEqual(vec, vecRef) );
139  }
140  SECTION( "density-matrix" ) {
141 
142  initClassicalState(mat, ind);
143  QMatrix matRef = getZeroMatrix(1<<NUM_QUBITS);
144  matRef[ind][ind] = 1;
145  REQUIRE( areEqual(mat, matRef) );
146  }
147  }
148  SECTION( "input validation" ) {
149 
150  SECTION( "state index" ) {
151 
152  int ind = GENERATE( -1, (1<<NUM_QUBITS) );
153  REQUIRE_THROWS_WITH( initClassicalState(vec, ind), Contains("Invalid state index") );
154  }
155  }
156  destroyQureg(vec, QUEST_ENV);
157  destroyQureg(mat, QUEST_ENV);
158 }
159 
160 
161 
166 TEST_CASE( "initPlusState", "[state_initialisations]" ) {
167 
170 
171  SECTION( "correctness" ) {
172 
173  SECTION( "state-vector" ) {
174 
175  // |+> = 1/sqrt(N^2) sum_i |i>
176  // = 1/sqrt(N^2) {1, ..., 1}
177  initPlusState(vec);
178  QVector vecRef = QVector(1<<NUM_QUBITS);
179  for (size_t i=0; i<vecRef.size(); i++)
180  vecRef[i] = 1./sqrt(pow(2,NUM_QUBITS));
181  REQUIRE( areEqual(vec, vecRef) );
182  }
183  SECTION( "density-matrix" ) {
184 
185  // |+><+| = 1/sqrt(N^2) sum_i |i> 1/sqrt(N^2) sum_j <j|
186  // = 1/(N^2) sum_{ij} |i><j|
187  // = 1/(N^2) {{1, ..., 1}, ...}
188  initPlusState(mat);
189  QMatrix matRef = getZeroMatrix(1<<NUM_QUBITS);
190  for (size_t i=0; i<matRef.size(); i++)
191  for (size_t j=0; j<matRef.size(); j++)
192  matRef[i][j] = 1./pow(2, NUM_QUBITS);
193  REQUIRE( areEqual(mat, matRef) );
194  }
195  }
196  SECTION( "input validation" ) {
197 
198  // no user validation
199  SUCCEED( );
200  }
201  destroyQureg(vec, QUEST_ENV);
202  destroyQureg(mat, QUEST_ENV);
203 }
204 
205 
206 
211 TEST_CASE( "initPureState", "[state_initialisations]" ) {
212 
215 
216  SECTION( "correctness" ) {
217 
218  SECTION( "state-vector" ) {
219 
220  /* state-vector version just performs cloneQureg */
221 
223 
224  // make sure states start differently
225  initDebugState(vec1);
226  initBlankState(vec2);
227  REQUIRE( !areEqual(vec1, vec2) );
228 
229  // make sure vec2 is overwritten with vec1
230  QVector copy1 = toQVector(vec1);
231  initPureState(vec2, vec1);
232  REQUIRE( areEqual(vec1, vec2) );
233 
234  // make sure vec1 was not modified
235  REQUIRE( areEqual(vec1, copy1) );
236 
237  destroyQureg(vec2, QUEST_ENV);
238  }
239  SECTION( "density-matrix" ) {
240 
241  /* density matrix version initialises matrix in |pure><pure| */
242 
243  initDebugState(vec1); // |vec1> = sum_i a_i |i>
244  QVector copy1 = toQVector(vec1);
245 
246  // make sure mat1 is modified correctly
247  initBlankState(mat1);
248  initPureState(mat1, vec1); // mat1 = |vec1><vec1| = sum_{ij} a_i a_j* |i><j|
249 
250  QMatrix matRef = getZeroMatrix(1<<NUM_QUBITS);
251  for (size_t i=0; i<matRef.size(); i++)
252  for (size_t j=0; j<matRef.size(); j++)
253  matRef[i][j] = copy1[i] * conj(copy1[j]);
254  REQUIRE( areEqual(mat1, matRef) );
255 
256  // make sure vec1 was not modified
257  REQUIRE( areEqual(vec1, copy1) );
258  }
259  }
260  SECTION( "input validation" ) {
261 
262  SECTION( "qureg types" ) {
263 
264  // density matrix as second arg is illegal (regardless of first arg)
265  REQUIRE_THROWS_WITH( initPureState(vec1, mat1), Contains("Second argument must be a state-vector") );
266  REQUIRE_THROWS_WITH( initPureState(mat1, mat1), Contains("Second argument must be a state-vector") );
267  }
268  SECTION( "qureg dimensions" ) {
269 
270  Qureg vec2 = createQureg(NUM_QUBITS + 1, QUEST_ENV);
271  REQUIRE_THROWS_WITH( initPureState(vec1, vec2), Contains("Dimensions") && Contains("don't match") );
272  REQUIRE_THROWS_WITH( initPureState(mat1, vec2), Contains("Dimensions") && Contains("don't match") );
273  destroyQureg(vec2, QUEST_ENV);
274  }
275  }
276  destroyQureg(vec1, QUEST_ENV);
277  destroyQureg(mat1, QUEST_ENV);
278 }
279 
280 
281 
286 TEST_CASE( "initStateFromAmps", "[state_initialisations]" ) {
287 
289 
290  SECTION( "correctness" ) {
291 
292  SECTION( "state-vector" ) {
293 
294  // create arbitrary (but distinctly non-zero) amplitudes
295  qreal ampsRe[vec.numAmpsTotal];
296  qreal ampsIm[vec.numAmpsTotal];
297  QVector vecRef = QVector(vec.numAmpsTotal);
298  for (int i=0; i<vec.numAmpsTotal; i++) {
299  ampsRe[i] = 2*i;
300  ampsIm[i] = 2*i + 1;
301  vecRef[i] = (ampsRe[i]) + 1i*(ampsIm[i]);
302  }
303 
304  initBlankState(vec);
305  initStateFromAmps(vec, ampsRe, ampsIm);
306  REQUIRE( areEqual(vec, vecRef) );
307  }
308  }
309  SECTION( "input validation" ) {
310 
311  SECTION( "density-matrix" ) {
312 
314  REQUIRE_THROWS_WITH( initStateFromAmps(mat, NULL, NULL), Contains("valid only for state-vectors") );
315  destroyQureg(mat, QUEST_ENV);
316  }
317  }
318  destroyQureg(vec, QUEST_ENV);
319 }
320 
321 
322 
327 TEST_CASE( "initZeroState", "[state_initialisations]" ) {
328 
331 
332  SECTION( "correctness" ) {
333 
334  SECTION( "state-vector" ) {
335 
336  initBlankState(vec);
337  initZeroState(vec);
338 
339  QVector refVec = QVector(vec.numAmpsTotal);
340  refVec[0] = 1;
341  REQUIRE( areEqual(vec, refVec) );
342  }
343  SECTION( "density-matrix" ) {
344 
345  initBlankState(mat);
346  initZeroState(mat);
347 
348  QMatrix refMat = getZeroMatrix(1<<mat.numQubitsRepresented);
349  refMat[0][0] = 1;
350  REQUIRE( areEqual(mat, refMat) );
351  }
352  }
353  SECTION( "input validation" ) {
354 
355  // no input validation
356  SUCCEED( );
357  }
358  destroyQureg(vec, QUEST_ENV);
359  destroyQureg(mat, QUEST_ENV);
360 }
361 
362 
363 
368 TEST_CASE( "setAmps", "[state_initialisations]" ) {
369 
371 
372  int maxInd = vec.numAmpsTotal;
373  qreal reals[maxInd];
374  qreal imags[maxInd];
375 
376  SECTION( "correctness" ) {
377 
378  SECTION( "state-vector" ) {
379 
380  // all valid number of amplitudes and offsets
381  int startInd = GENERATE_COPY( range(0,maxInd) );
382  int numAmps = GENERATE_COPY( range(0,1+maxInd-startInd) ); // upper-bound allows all amps specified
383 
384  // generate random amplitudes
385  for (int i=0; i<numAmps; i++) {
386  reals[i] = getRandomReal(-5,5);
387  imags[i] = getRandomReal(-5,5);
388  }
389 
390  // check both specified and un-specified amplitudes are correctly handled
391  initDebugState(vec);
392  QVector vecRef = toQVector(vec);
393 
394  setAmps(vec, startInd, reals, imags, numAmps);
395  for (int i=0; i<numAmps; i++)
396  vecRef[startInd+i] = reals[i] + 1i*(imags[i]);
397 
398  REQUIRE( areEqual(vec, vecRef) );
399  }
400  }
401  SECTION( "input validation" ) {
402 
403  SECTION( "start index" ) {
404 
405  int startInd = GENERATE_COPY( -1, maxInd );
406  int numAmps = 0;
407  REQUIRE_THROWS_WITH( setAmps(vec, startInd, reals, imags, numAmps), Contains("Invalid amplitude index") );
408  }
409 
410  SECTION( "number of amplitudes" ) {
411 
412  // independent
413  int startInd = 0;
414  int numAmps = GENERATE_COPY( -1, maxInd+1 );
415  REQUIRE_THROWS_WITH( setAmps(vec, startInd, reals, imags, numAmps), Contains("Invalid number of amplitudes") );
416 
417  // invalid considering start-index
418  startInd = maxInd - 1;
419  numAmps = 2;
420  REQUIRE_THROWS_WITH( setAmps(vec, startInd, reals, imags, numAmps), Contains("More amplitudes given than exist") );
421  }
422  SECTION( "density-matrix" ) {
423 
425  REQUIRE_THROWS_WITH( setAmps(mat, 0, reals, imags, 0), Contains("valid only for state-vectors") );
426  destroyQureg(mat, QUEST_ENV);
427  }
428  }
429  destroyQureg(vec, QUEST_ENV);
430 }
431 
432 
433 
438 TEST_CASE( "setWeightedQureg", "[state_initialisations]" ) {
439 
440  SECTION( "correctness" ) {
441 
442  // repeat each test below 10 times
443  GENERATE( range(0,10) );
444 
445  /* note tolerance in areEqual increases with tests, since
446  * small differences propogate in vecC which is not re-initialised
447  */
448 
449  SECTION( "state-vector" ) {
450 
451  // make three random vectors
455  for (int j=0; j<vecA.numAmpsPerChunk; j++) {
456  vecA.stateVec.real[j] = getRandomReal(-5,5); vecA.stateVec.imag[j] = getRandomReal(-5,5);
457  vecB.stateVec.real[j] = getRandomReal(-5,5); vecB.stateVec.imag[j] = getRandomReal(-5,5);
458  vecC.stateVec.real[j] = getRandomReal(-5,5); vecC.stateVec.imag[j] = getRandomReal(-5,5);
459  }
460  copyStateToGPU(vecA); copyStateToGPU(vecB); copyStateToGPU(vecC);
461  QVector refA = toQVector(vecA);
462  QVector refB = toQVector(vecB);
463  QVector refC = toQVector(vecC);
464  QVector refOut;
465 
466  // get three random factors
467  qcomp numA = getRandomReal(-5,5) + 1i*getRandomReal(-5,5);
468  qcomp numB = getRandomReal(-5,5) + 1i*getRandomReal(-5,5);
469  qcomp numC = getRandomReal(-5,5) + 1i*getRandomReal(-5,5);
470  Complex facA = toComplex(numA);
471  Complex facB = toComplex(numB);
472  Complex facC = toComplex(numC);
473 
474  // check out-qureg is correct, when all quregs are unique...
475  setWeightedQureg(facA, vecA, facB, vecB, facC, vecC);
476  refOut = numA*refA + numB*refB + numC*refC;
477  REQUIRE( areEqual(vecC, refOut) );
478 
479  // ... and that other qureg's aren't modified
480  REQUIRE( areEqual(vecA, refA) );
481  REQUIRE( areEqual(vecB, refB) );
482 
483  // check quregOut correct, when it's also qureg2
484  refC = toQVector(vecC);
485  setWeightedQureg(facB, vecB, facC, vecC, facA, vecC);
486  refOut = numB*refB + numC*refC + numA*refC;
487  REQUIRE( areEqual(vecC, refOut, 10*REAL_EPS) );
488 
489  // ... and that the remaining qureg is not modified
490  REQUIRE( areEqual(vecB, refB) );
491 
492  // check quregOut correct, when it's also qureg1
493  refC = toQVector(vecC);
494  setWeightedQureg(facC, vecC, facB, vecB, facA, vecC);
495  refOut = numC*refC + numB*refB + numA*refC;
496  REQUIRE( areEqual(vecC, refOut, 10*REAL_EPS) );
497 
498  // ... and that the remaining qureg is not modified
499  REQUIRE( areEqual(vecB, refB) );
500 
501  // check quregOut is correct when it's both input quregs
502  refC = toQVector(vecC);
503  setWeightedQureg(facA, vecC, facB, vecC, facC, vecC);
504  refOut = numA*refC + numB*refC + numC*refC;
505  REQUIRE( areEqual(vecC, refOut, 1E3*REAL_EPS) );
506 
507  // cleanup
508  destroyQureg(vecA, QUEST_ENV);
509  destroyQureg(vecB, QUEST_ENV);
510  destroyQureg(vecC, QUEST_ENV);
511  }
512  SECTION( "density-matrix" ) {
513 
514  // make three random matrices
518  for (int j=0; j<matA.numAmpsPerChunk; j++) {
519  matA.stateVec.real[j] = getRandomReal(-5,5); matA.stateVec.imag[j] = getRandomReal(-5,5);
520  matB.stateVec.real[j] = getRandomReal(-5,5); matB.stateVec.imag[j] = getRandomReal(-5,5);
521  matC.stateVec.real[j] = getRandomReal(-5,5); matC.stateVec.imag[j] = getRandomReal(-5,5);
522  }
523  copyStateToGPU(matA); copyStateToGPU(matB); copyStateToGPU(matC);
524  QMatrix refA = toQMatrix(matA);
525  QMatrix refB = toQMatrix(matB);
526  QMatrix refC = toQMatrix(matC);
527  QMatrix refOut;
528 
529  // get three random factors
530  qcomp numA = getRandomReal(-5,5) + 1i*getRandomReal(-5,5);
531  qcomp numB = getRandomReal(-5,5) + 1i*getRandomReal(-5,5);
532  qcomp numC = getRandomReal(-5,5) + 1i*getRandomReal(-5,5);
533  Complex facA = toComplex(numA);
534  Complex facB = toComplex(numB);
535  Complex facC = toComplex(numC);
536 
537  // check out-qureg is correct, when all quregs are unique...
538  setWeightedQureg(facA, matA, facB, matB, facC, matC);
539  refOut = numA*refA + numB*refB + numC*refC;
540  REQUIRE( areEqual(matC, refOut) );
541 
542  // ... and that other qureg's aren't modified
543  REQUIRE( areEqual(matA, refA) );
544  REQUIRE( areEqual(matB, refB) );
545 
546  // check quregOut correct, when it's also qureg2
547  refC = toQMatrix(matC);
548  setWeightedQureg(facB, matB, facC, matC, facA, matC);
549  refOut = numB*refB + numC*refC + numA*refC;
550  REQUIRE( areEqual(matC, refOut, 10*REAL_EPS) );
551 
552  // ... and that the remaining qureg is not modified
553  REQUIRE( areEqual(matB, refB) );
554 
555  // check quregOut correct, when it's also qureg1
556  refC = toQMatrix(matC);
557  setWeightedQureg(facC, matC, facB, matB, facA, matC);
558  refOut = numC*refC + numB*refB + numA*refC;
559  REQUIRE( areEqual(matC, refOut, 1E2*REAL_EPS) );
560 
561  // ... and that the remaining qureg is not modified
562  REQUIRE( areEqual(matB, refB) );
563 
564  // check quregOut is correct when it's both input quregs
565  refC = toQMatrix(matC);
566  setWeightedQureg(facA, matC, facB, matC, facC, matC);
567  refOut = numA*refC + numB*refC + numC*refC;
568  REQUIRE( areEqual(matC, refOut, 1E3*REAL_EPS) );
569 
570  // cleanup
571  destroyQureg(matA, QUEST_ENV);
572  destroyQureg(matB, QUEST_ENV);
573  destroyQureg(matC, QUEST_ENV);
574  }
575  }
576  SECTION( "input validation" ) {
577 
578  SECTION( "qureg types" ) {
579 
582  Complex f = {.real=0, .imag=0};
583 
584  // two state-vecs, one density-matrix
585  REQUIRE_THROWS_WITH( setWeightedQureg(f, mat, f, vec, f, vec), Contains("state-vectors or") && Contains("density matrices") );
586  REQUIRE_THROWS_WITH( setWeightedQureg(f, vec, f, mat, f, vec), Contains("state-vectors or") && Contains("density matrices") );
587  REQUIRE_THROWS_WITH( setWeightedQureg(f, vec, f, vec, f, mat), Contains("state-vectors or") && Contains("density matrices") );
588 
589  // one state-vec, two density-matrices
590  REQUIRE_THROWS_WITH( setWeightedQureg(f, vec, f, mat, f, mat), Contains("state-vectors or") && Contains("density matrices") );
591  REQUIRE_THROWS_WITH( setWeightedQureg(f, mat, f, vec, f, mat), Contains("state-vectors or") && Contains("density matrices") );
592  REQUIRE_THROWS_WITH( setWeightedQureg(f, mat, f, mat, f, vec), Contains("state-vectors or") && Contains("density matrices") );
593 
594  destroyQureg(vec, QUEST_ENV);
595  destroyQureg(mat, QUEST_ENV);
596  }
597  SECTION( "qureg dimensions" ) {
598 
600  Qureg vecB = createQureg(NUM_QUBITS + 1, QUEST_ENV);
603  Complex f = {.real=0, .imag=0};
604 
605  // state-vecs
606  REQUIRE_THROWS_WITH( setWeightedQureg(f, vecA, f, vecB, f, vecB), Contains("Dimensions") );
607  REQUIRE_THROWS_WITH( setWeightedQureg(f, vecB, f, vecA, f, vecB), Contains("Dimensions") );
608  REQUIRE_THROWS_WITH( setWeightedQureg(f, vecB, f, vecB, f, vecA), Contains("Dimensions") );
609 
610  // density-matrices
611  REQUIRE_THROWS_WITH( setWeightedQureg(f, matA, f, matB, f, matB), Contains("Dimensions") );
612  REQUIRE_THROWS_WITH( setWeightedQureg(f, matB, f, matA, f, matB), Contains("Dimensions") );
613  REQUIRE_THROWS_WITH( setWeightedQureg(f, matB, f, matB, f, matA), Contains("Dimensions") );
614 
615  destroyQureg(vecA, QUEST_ENV);
616  destroyQureg(vecB, QUEST_ENV);
617  destroyQureg(matA, QUEST_ENV);
618  destroyQureg(matB, QUEST_ENV);
619  }
620  }
621 }
622 
void initBlankState(Qureg qureg)
Initialises a qureg to have all-zero-amplitudes.
Definition: QuEST.c:119
QuESTEnv QUEST_ENV
The global QuESTEnv instance, to be created and destroyed once in this main(), so that the MPI enviro...
Definition: main.cpp:20
void initPureState(Qureg qureg, Qureg pure)
Initialise a set of qubits, which can be a state vector or density matrix, to a given pure state.
Definition: QuEST.c:145
#define NUM_QUBITS
The default number of qubits in the registers created for unit testing (both statevectors and density...
Definition: utilities.hpp:36
qreal getRandomReal(qreal min, qreal max)
Returns a random real between min (inclusive) and max (exclusive), from the uniform distribution.
Definition: utilities.cpp:410
void cloneQureg(Qureg targetQureg, Qureg copyQureg)
Set targetQureg to be a clone of copyQureg.
Definition: QuEST.c:165
#define qreal
QMatrix toQMatrix(ComplexMatrix2 src)
Returns a copy of the given 2-by-2 matrix.
Definition: utilities.cpp:869
void setAmps(Qureg qureg, long long int startInd, qreal *reals, qreal *imags, long long int numAmps)
Overwrites a subset of the amplitudes in qureg, with those passed in reals and imags.
Definition: QuEST.c:781
void setWeightedQureg(Complex fac1, Qureg qureg1, Complex fac2, Qureg qureg2, Complex facOut, Qureg out)
Modifies qureg out to the result of (facOut out + fac1 qureg1 + fac2 qureg2), imposing no constraints...
Definition: QuEST.c:797
std::vector< qcomp > QVector
A complex vector, which can be zero-initialised with QVector(numAmps).
Definition: utilities.hpp:60
QVector toQVector(Qureg qureg)
Returns an equal-size copy of the given state-vector qureg.
Definition: utilities.cpp:938
long long int numAmpsPerChunk
Number of probability amplitudes held in stateVec by this process In the non-MPI version,...
Definition: QuEST.h:213
#define qcomp
void initStateFromAmps(Qureg qureg, qreal *reals, qreal *imags)
Initialise qureg by specifying the complete statevector.
Definition: QuEST.c:157
void copyStateToGPU(Qureg qureg)
In GPU mode, this copies the state-vector (or density matrix) from RAM (qureg.stateVec) to VRAM / GPU...
Definition: QuEST_cpu.c:36
#define toComplex(scalar)
void destroyQureg(Qureg qureg, QuESTEnv env)
Deallocate a Qureg object representing a set of qubits.
Definition: QuEST.c:77
void initDebugState(Qureg qureg)
Initialises qureg to be in the un-normalised, non-physical state with with n-th complex amplitude (2n...
Definition: QuEST.c:1308
void initClassicalState(Qureg qureg, long long int stateInd)
Initialise a set of qubits to the classical state (also known as a "computational basis state") with...
Definition: QuEST.c:134
Represents a system of qubits.
Definition: QuEST.h:203
ComplexArray stateVec
Computational state amplitudes - a subset thereof in the MPI version.
Definition: QuEST.h:222
std::vector< std::vector< qcomp > > QMatrix
A complex square matrix.
Definition: utilities.hpp:49
int numQubitsRepresented
The number of qubits represented in either the state-vector or density matrix.
Definition: QuEST.h:208
long long int numAmpsTotal
Total number of amplitudes, which are possibly distributed among machines.
Definition: QuEST.h:215
qreal real
Definition: QuEST.h:105
Qureg createQureg(int numQubits, QuESTEnv env)
Create a Qureg object representing a set of qubits which will remain in a pure state.
Definition: QuEST.c:36
QMatrix getZeroMatrix(size_t dim)
Returns a dim-by-dim square complex matrix, initialised to all zeroes.
Definition: utilities.cpp:143
Represents one complex number.
Definition: QuEST.h:103
void initZeroState(Qureg qureg)
Initialise a set of qubits to the classical zero state .
Definition: QuEST.c:113
bool areEqual(QVector a, QVector b)
Returns true if the absolute value of the difference between every amplitude in vectors a and b is le...
Definition: utilities.cpp:387
Qureg createDensityQureg(int numQubits, QuESTEnv env)
Create a Qureg for qubits which are represented by a density matrix, and can be in mixed states.
Definition: QuEST.c:50
void initPlusState(Qureg qureg)
Initialise a set of qubits to the plus state (and similarly for density matrices).
Definition: QuEST.c:125
TEST_CASE("cloneQureg", "[state_initialisations]")