The Quantum Exact Simulation Toolkit v4.0.0
Loading...
Searching...
No Matches
Deprecated utilities

Utilities for testing QuEST's deprecated v3 API functions. More...

Typedefs

typedef vector< vector< qcomp > > QMatrix
 
typedef vector< qcomp > QVector
 

Functions

void applyReferenceMatrix (QMatrix &state, int *ctrls, int numCtrls, int *targs, int numTargs, QMatrix op)
 
void applyReferenceMatrix (QMatrix &state, int *targs, int numTargs, QMatrix op)
 
void applyReferenceMatrix (QVector &state, int *ctrls, int numCtrls, int *targs, int numTargs, QMatrix op)
 
void applyReferenceMatrix (QVector &state, int *targs, int numTargs, QMatrix op)
 
void applyReferenceOp (QMatrix &state, int *ctrls, int numCtrls, int *targs, int numTargs, QMatrix op)
 
void applyReferenceOp (QMatrix &state, int *ctrls, int numCtrls, int targ1, int targ2, QMatrix op)
 
void applyReferenceOp (QMatrix &state, int *ctrls, int numCtrls, int target, QMatrix op)
 
void applyReferenceOp (QMatrix &state, int *targs, int numTargs, QMatrix op)
 
void applyReferenceOp (QMatrix &state, int ctrl, int *targs, int numTargs, QMatrix op)
 
void applyReferenceOp (QMatrix &state, int ctrl, int targ, QMatrix op)
 
void applyReferenceOp (QMatrix &state, int ctrl, int targ1, int targ2, QMatrix op)
 
void applyReferenceOp (QMatrix &state, int targ, QMatrix op)
 
void applyReferenceOp (QVector &state, int *ctrls, int numCtrls, int *targs, int numTargs, QMatrix op)
 
void applyReferenceOp (QVector &state, int *ctrls, int numCtrls, int targ1, int targ2, QMatrix op)
 
void applyReferenceOp (QVector &state, int *ctrls, int numCtrls, int target, QMatrix op)
 
void applyReferenceOp (QVector &state, int *targs, int numTargs, QMatrix op)
 
void applyReferenceOp (QVector &state, int ctrl, int *targs, int numTargs, QMatrix op)
 
void applyReferenceOp (QVector &state, int ctrl, int targ, QMatrix op)
 
void applyReferenceOp (QVector &state, int ctrl, int targ1, int targ2, QMatrix op)
 
void applyReferenceOp (QVector &state, int targ, QMatrix op)
 
bool areEqual (QMatrix a, QMatrix b)
 
bool areEqual (Qureg qureg, QMatrix matr)
 
bool areEqual (Qureg qureg, QMatrix matr, qreal precision)
 
bool areEqual (Qureg qureg, QVector vec)
 
bool areEqual (Qureg qureg, QVector vec, qreal precision)
 
bool areEqual (Qureg qureg1, Qureg qureg2)
 
bool areEqual (Qureg qureg1, Qureg qureg2, qreal precision)
 
bool areEqual (QVector a, QVector b)
 
bool areEqual (QVector vec, qreal *reals)
 
bool areEqual (QVector vec, qreal *reals, qreal *imags)
 
void assertQuregAndRefInDebugState (Qureg qureg, QMatrix ref)
 
void assertQuregAndRefInDebugState (Qureg qureg, QVector ref)
 
CatchGen< int * > bitsets (int numBits)
 
unsigned int calcLog2 (long unsigned int res)
 
void deleteFilesWithPrefixSynch (char *prefix)
 
QMatrix getConjugateTranspose (QMatrix a)
 
QVector getDFT (QVector in)
 
QVector getDFT (QVector in, int *targs, int numTargs)
 
QMatrix getExponentialOfDiagonalMatrix (QMatrix a)
 
QMatrix getExponentialOfPauliMatrix (qreal angle, QMatrix a)
 
QMatrix getFullOperatorMatrix (int *ctrls, int numCtrls, int *targs, int numTargs, QMatrix op, int numQubits)
 
QMatrix getIdentityMatrix (size_t dim)
 
QMatrix getKetBra (QVector ket, QVector bra)
 
QMatrix getKroneckerProduct (QMatrix a, QMatrix b)
 
QVector getKroneckerProduct (QVector b, QVector a)
 
QVector getMatrixDiagonal (QMatrix matr)
 
QMatrix getMixedDensityMatrix (vector< qreal > probs, vector< QVector > states)
 
QVector getNormalised (QVector vec)
 
QMatrix getPureDensityMatrix (QVector state)
 
qcomp getRandomComplex ()
 
QMatrix getRandomDensityMatrix (int numQb)
 
int getRandomInt (int min, int max)
 
vector< QMatrixgetRandomKrausMap (int numQb, int numOps)
 
vector< QVectorgetRandomOrthonormalVectors (int numQb, int numStates)
 
vector< qreal > getRandomProbabilities (int numProbs)
 
QMatrix getRandomPureDensityMatrix (int numQb)
 
QMatrix getRandomQMatrix (int dim)
 
QVector getRandomQVector (int dim)
 
qreal getRandomReal (qreal min, qreal max)
 
QVector getRandomStateVector (int numQb)
 
QMatrix getRandomUnitary (int numQb)
 
QMatrix getSwapMatrix (int qb1, int qb2, int numQb)
 
long long int getTwosComplement (long long int decimal, int numBits)
 
long long int getUnsigned (long long int twosComp, int numBits)
 
long long int getValueOfTargets (long long int ind, int *targs, int numTargs)
 
QMatrix getZeroMatrix (size_t dim)
 
CatchGen< pauliOpType * > pauliseqs (int numPaulis)
 
CatchGen< int * > sequences (int base, int numDigits)
 
void setRandomDiagPauliHamil (PauliHamil hamil, int numQubits)
 
void setRandomPauliSum (PauliHamil hamil, int numQubits)
 
void setRandomPauliSum (qreal *coeffs, pauliOpType *codes, int numQubits, int numTerms)
 
void setRandomTargets (int *targs, int numTargs, int numQb)
 
void setRandomTargets (vector< int > &targs, int numQb)
 
void setRandomTestStateSeeds ()
 
void setSubMatrix (QMatrix &dest, QMatrix sub, size_t r, size_t c)
 
void setUniqueFilename (char *outFn, int maxlen, char *prefix)
 
CatchGen< int * > sublists (CatchGen< int > &&gen, int numSamps, const int *exclude, int numExclude)
 
CatchGen< int * > sublists (CatchGen< int > &&gen, int numSamps, int excluded)
 
CatchGen< int * > sublists (CatchGen< int > &&gen, int sublen)
 
CatchGen< int * > sublists (int *list, int len, int sublen)
 
ComplexMatrix2 toComplexMatrix2 (QMatrix qm)
 
ComplexMatrix4 toComplexMatrix4 (QMatrix qm)
 
void toComplexMatrixN (QMatrix qm, ComplexMatrixN cm)
 
QMatrix toDiagonalQMatrix (QVector vec)
 
QMatrix toQMatrix (CompMatr src)
 
QMatrix toQMatrix (CompMatr1 src)
 
QMatrix toQMatrix (CompMatr2 src)
 
QMatrix toQMatrix (DiagMatr matr)
 
QMatrix toQMatrix (FullStateDiagMatr matr)
 
QMatrix toQMatrix (PauliHamil hamil)
 
QMatrix toQMatrix (PauliStrSum sum)
 
QMatrix toQMatrix (qreal *coeffs, pauliOpType *paulis, int numQubits, int numTerms)
 
QMatrix toQMatrix (Qureg qureg)
 
void toQureg (Qureg qureg, QMatrix mat)
 
void toQureg (Qureg qureg, QVector vec)
 
QVector toQVector (DiagMatr op)
 
QVector toQVector (FullStateDiagMatr op)
 
QVector toQVector (Qureg qureg)
 
void writeToFileSynch (char *fn, const string &contents)
 

Detailed Description

Utilities for testing QuEST's deprecated v3 API functions.

Typedef Documentation

◆ QMatrix

typedef vector<vector<qcomp> > QMatrix

A complex square matrix. Should be initialised with getZeroMatrix(). These have all the natural linear-algebra operator overloads, including left-multiplication onto a vector.

This data-structure is not partitioned between nodes in distributed mode. That is, every node has a complete copy, allowing for safe comparisons.

Author
Tyson Jones

Definition at line 60 of file test_utilities.hpp.

◆ QVector

typedef vector<qcomp> QVector

A complex vector, which can be zero-initialised with QVector(numAmps). These have all the natural linear-algebra operator overloads.

This data-structure is not partitioned between nodes in distributed mode. That is, every node has a complete copy, allowing for safe comparisons.

Author
Tyson Jones

Definition at line 71 of file test_utilities.hpp.

Function Documentation

◆ applyReferenceMatrix() [1/4]

void applyReferenceMatrix ( QMatrix & state,
int * ctrls,
int numCtrls,
int * targs,
int numTargs,
QMatrix op )

Modifies the density matrix state to be the result of left-multiplying the multi-target operator matrix op, with the specified control and target qubits (in ctrls and targs respectively). Here, op is treated like a simple matrix and is hence left-multiplied onto the state once.

Author
Tyson Jones

Definition at line 997 of file test_utilities.cpp.

999 {
1000 // for density matrices, op is left-multiplied only
1001 int numQubits = calcLog2(state.size());
1002 QMatrix leftOp = getFullOperatorMatrix(ctrls, numCtrls, targs, numTargs, op, numQubits);
1003 state = leftOp * state;
1004}
QMatrix getFullOperatorMatrix(int *ctrls, int numCtrls, int *targs, int numTargs, QMatrix op, int numQubits)
unsigned int calcLog2(long unsigned int res)
vector< vector< qcomp > > QMatrix

◆ applyReferenceMatrix() [2/4]

void applyReferenceMatrix ( QMatrix & state,
int * targs,
int numTargs,
QMatrix op )

Modifies the density matrix state to be the result of left-multiplying the multi-target operator matrix op, with the target qubits (assuming no control qubits). Here, op is treated like a simple matrix and is hence left-multiplied onto the state once.

Author
Tyson Jones

Definition at line 1005 of file test_utilities.cpp.

1007 {
1008 applyReferenceMatrix(state, NULL, 0, targs, numTargs, op);
1009}
void applyReferenceMatrix(QVector &state, int *ctrls, int numCtrls, int *targs, int numTargs, QMatrix op)

◆ applyReferenceMatrix() [3/4]

void applyReferenceMatrix ( QVector & state,
int * ctrls,
int numCtrls,
int * targs,
int numTargs,
QMatrix op )

Modifies the state-vector state to be the result of left-multiplying the multi-target operator matrix op, with the specified control and target qubits (in ctrls and targs respectively). This is an alias of applyReferenceOp(), since operators are always left-multiplied as matrices onto state-vectors.

Author
Tyson Jones

Definition at line 985 of file test_utilities.cpp.

987 {
988 // for state-vectors, the op is always just left-multiplied
989 applyReferenceOp(state, ctrls, numCtrls, targs, numTargs, op);
990}
void applyReferenceOp(QVector &state, int *ctrls, int numCtrls, int *targs, int numTargs, QMatrix op)

Referenced by applyReferenceMatrix(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ applyReferenceMatrix() [4/4]

void applyReferenceMatrix ( QVector & state,
int * targs,
int numTargs,
QMatrix op )

Modifies the state-vector state to be the result of left-multiplying the multi-target operator matrix op, with the specified target qubits (assuming no control qubits). T

Author
Tyson Jones

Definition at line 991 of file test_utilities.cpp.

993 {
994 // for state-vectors, the op is always just left-multiplied
995 applyReferenceOp(state, targs, numTargs, op);
996}

◆ applyReferenceOp() [1/16]

void applyReferenceOp ( QMatrix & state,
int * ctrls,
int numCtrls,
int * targs,
int numTargs,
QMatrix op )

Modifies the density matrix state to be the result of applying the multi-target operator matrix op, with the specified control and target qubits (in ctrls and targs respectively). This updates state under

\[ \text{state} \to \text{op} \, \text{state} \, \text{op}^\dagger \]

even if op is not unitary (which is useful for applying Kraus operators).

op must be a 2^numTargs-by-2^numTargs matrix. Furthermore, every element of targs must not appear in ctrls (and vice-versa), though this is not explicitly checked. Elements of targs and ctrls should be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multipling it to state, then right-multiplying its conjugate transpose onto the result.

Author
Tyson Jones

Definition at line 928 of file test_utilities.cpp.

930 {
931 int numQubits = calcLog2(state.size());
932 QMatrix leftOp = getFullOperatorMatrix(ctrls, numCtrls, targs, numTargs, op, numQubits);
933 QMatrix rightOp = getConjugateTranspose(leftOp);
934 state = leftOp * state * rightOp;
935}
QMatrix getConjugateTranspose(QMatrix a)

◆ applyReferenceOp() [2/16]

void applyReferenceOp ( QMatrix & state,
int * ctrls,
int numCtrls,
int targ1,
int targ2,
QMatrix op )

Modifies the density matrix state to be the result of applying the two-target operator matrix op, with the specified control qubits (in ctrls). This updates state under

\[ \text{state} \to \text{op} \, \text{state} \, \text{op}^\dagger \]

even if op is not unitary (which is useful for applying Kraus operators).

op must be a 4-by-4 matrix. Both targ1 and targ2 must not appear in ctrls, though this is not explicitly checked. Elements of ctrls, and targ1 and targ2, should be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multipling it to state, then right-multiplying its conjugate transpose onto the result.

Author
Tyson Jones

Definition at line 936 of file test_utilities.cpp.

938 {
939 int targs[2] = {targ1, targ2};
940 applyReferenceOp(state, ctrls, numCtrls, targs, 2, op);
941}

◆ applyReferenceOp() [3/16]

void applyReferenceOp ( QMatrix & state,
int * ctrls,
int numCtrls,
int target,
QMatrix op )

Modifies the density matrix state to be the result of applying the single-target operator matrix op, with the specified control qubits (in ctrls). This updates state under

\[ \text{state} \to \text{op} \, \text{state} \, \text{op}^\dagger \]

even if op is not unitary (which is useful for applying Kraus operators).

op must be a 2-by-2 matrix. target must not appear in ctrls, though this is not explicitly checked.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multipling it to state, then right-multiplying its conjugate transpose onto the result.

Author
Tyson Jones

Definition at line 942 of file test_utilities.cpp.

944 {
945 int targs[1] = {target};
946 applyReferenceOp(state, ctrls, numCtrls, targs, 1, op);
947}

◆ applyReferenceOp() [4/16]

void applyReferenceOp ( QMatrix & state,
int * targs,
int numTargs,
QMatrix op )

Modifies the density matrix state to be the result of applying the multi-target operator matrix op, with no control qubits. This updates state under

\[ \text{state} \to \text{op} \, \text{state} \, \text{op}^\dagger \]

even if op is not unitary (which is useful for applying Kraus operators).

op must be a 2^numTargs-by-2^numTargs matrix. Every element in targs should be unique, though this is not explicitly checked.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multipling it to state, then right-multiplying its conjugate transpose onto the result.

Author
Tyson Jones

Definition at line 948 of file test_utilities.cpp.

950 {
951 applyReferenceOp(state, NULL, 0, targs, numTargs, op);
952}

◆ applyReferenceOp() [5/16]

void applyReferenceOp ( QMatrix & state,
int ctrl,
int * targs,
int numTargs,
QMatrix op )

Modifies the density matrix state to be the result of applying the multi-target operator matrix op, with a single control qubit ctrl. This updates state under

\[ \text{state} \to \text{op} \, \text{state} \, \text{op}^\dagger \]

even if op is not unitary (which is useful for applying Kraus operators).

op must be a 2^numTargs-by-2^numTargs matrix, and ctrl must not appear in targs (though this is not explicitly checked).

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multipling it to state, then right-multiplying its conjugate transpose onto the result.

Author
Tyson Jones

Definition at line 960 of file test_utilities.cpp.

962 {
963 int ctrls[1] = {ctrl};
964 applyReferenceOp(state, ctrls, 1, targs, numTargs, op);
965}

◆ applyReferenceOp() [6/16]

void applyReferenceOp ( QMatrix & state,
int ctrl,
int targ,
QMatrix op )

Modifies the density matrix state to be the result of applying the single-control single-target operator matrix op. This updates state under

\[ \text{state} \to \text{op} \, \text{state} \, \text{op}^\dagger \]

even if op is not unitary (which is useful for applying Kraus operators).

op must be a 2-by-2 matrix, and ctrl and targ should be different.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multipling it to state, then right-multiplying its conjugate transpose onto the result.

Author
Tyson Jones

Definition at line 953 of file test_utilities.cpp.

955 {
956 int ctrls[1] = {ctrl};
957 int targs[1] = {targ};
958 applyReferenceOp(state, ctrls, 1, targs, 1, op);
959}

◆ applyReferenceOp() [7/16]

void applyReferenceOp ( QMatrix & state,
int ctrl,
int targ1,
int targ2,
QMatrix op )

Modifies the density matrix state to be the result of applying the two-target operator matrix op, with a single control qubit ctrl. This updates state under

\[ \text{state} \to \text{op} \, \text{state} \, \text{op}^\dagger \]

even if op is not unitary (which is useful for applying Kraus operators).

op must be a 4-by-4 matrix, and ctrl, targ1 and targ2 must be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multipling it to state, then right-multiplying its conjugate transpose onto the result.

Author
Tyson Jones

Definition at line 966 of file test_utilities.cpp.

968 {
969 int ctrls[1] = {ctrl};
970 int targs[2] = {targ1, targ2};
971 applyReferenceOp(state, ctrls, 1, targs, 2, op);
972}

◆ applyReferenceOp() [8/16]

void applyReferenceOp ( QMatrix & state,
int targ,
QMatrix op )

Modifies the density matrix state to be the result of applying the single-target operator matrix op, with no control qubit. This updates state under

\[ \text{state} \to \text{op} \, \text{state} \, \text{op}^\dagger \]

even if op is not unitary (which is useful for applying Kraus operators).

op must be a 2-by-2 matrix.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multipling it to state, then right-multiplying its conjugate transpose onto the result.

Author
Tyson Jones

Definition at line 973 of file test_utilities.cpp.

975 {
976 int targs[1] = {targ};
977 applyReferenceOp(state, NULL, 0, targs, 1, op);
978}

◆ applyReferenceOp() [9/16]

void applyReferenceOp ( QVector & state,
int * ctrls,
int numCtrls,
int * targs,
int numTargs,
QMatrix op )

Modifies the state-vector state to be the result of applying the multi-target operator matrix op, with the specified control and target qubits (in ctrls and targs respectively). This updates state under

\[ \text{state} \to \text{op} \, \text{state} \]

even if op is not unitary.

op must be a 2^numTargs-by-2^numTargs matrix. Furthermore, every element of targs must not appear in ctrls (and vice-versa), though this is not explicitly checked. Elements of targs and ctrls should be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multiplying it onto state.

Author
Tyson Jones

Definition at line 872 of file test_utilities.cpp.

874 {
875 int numQubits = calcLog2(state.size());
876 QMatrix fullOp = getFullOperatorMatrix(ctrls, numCtrls, targs, numTargs, op, numQubits);
877 state = fullOp * state;
878}

Referenced by applyReferenceMatrix(), applyReferenceMatrix(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), applyReferenceOp(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ applyReferenceOp() [10/16]

void applyReferenceOp ( QVector & state,
int * ctrls,
int numCtrls,
int targ1,
int targ2,
QMatrix op )

Modifies the state-vector state to be the result of applying the two-target operator matrix op, with the specified control qubits (in ctrls). This updates state under

\[ \text{state} \to \text{op} \, \text{state} \]

even if op is not unitary.

op must be a 4-by-4 matrix. Furthermore, ctrls, targ1 and targ2 should all be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multiplying it onto state.

Author
Tyson Jones

Definition at line 879 of file test_utilities.cpp.

881 {
882 int targs[2] = {targ1, targ2};
883 applyReferenceOp(state, ctrls, numCtrls, targs, 2, op);
884}

◆ applyReferenceOp() [11/16]

void applyReferenceOp ( QVector & state,
int * ctrls,
int numCtrls,
int target,
QMatrix op )

Modifies the state-vector state to be the result of applying the single-target operator matrix op, with the specified control qubits (in ctrls). This updates state under

\[ \text{state} \to \text{op} \, \text{state} \]

even if op is not unitary.

op must be a 2-by-2 matrix. Furthermore, elements in ctrls and target should all be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multiplying it onto state.

Author
Tyson Jones

Definition at line 885 of file test_utilities.cpp.

887 {
888 int targs[1] = {target};
889 applyReferenceOp(state, ctrls, numCtrls, targs, 1, op);
890}

◆ applyReferenceOp() [12/16]

void applyReferenceOp ( QVector & state,
int * targs,
int numTargs,
QMatrix op )

Modifies the state-vector state to be the result of applying the multi-target operator matrix op, with no contorl qubits. This updates state under

\[ \text{state} \to \text{op} \, \text{state} \]

even if op is not unitary.

op must be a 2^numTargs-by-2^numTargs matrix. Furthermore, elements in targs should be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multiplying it onto state.

Author
Tyson Jones

Definition at line 891 of file test_utilities.cpp.

893 {
894 applyReferenceOp(state, NULL, 0, targs, numTargs, op);
895}

◆ applyReferenceOp() [13/16]

void applyReferenceOp ( QVector & state,
int ctrl,
int * targs,
int numTargs,
QMatrix op )

Modifies the state-vector state to be the result of applying the multi-target operator matrix op, with a single control qubit (ctrl) This updates state under

\[ \text{state} \to \text{op} \, \text{state} \]

even if op is not unitary.

op must be a 2^numTargs-by-2^numTargs matrix. Furthermore, elements in targs and ctrl should be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multiplying it onto state.

Author
Tyson Jones

Definition at line 903 of file test_utilities.cpp.

905 {
906 int ctrls[1] = {ctrl};
907 applyReferenceOp(state, ctrls, 1, targs, numTargs, op);
908}

◆ applyReferenceOp() [14/16]

void applyReferenceOp ( QVector & state,
int ctrl,
int targ,
QMatrix op )

Modifies the state-vector state to be the result of applying the single-target operator matrix op, with a single control qubit (ctrl). This updates state under

\[ \text{state} \to \text{op} \, \text{state} \]

even if op is not unitary.

op must be a 2-by-2 matrix. Furthermore, ctrl and targ must be different.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multiplying it onto state.

Author
Tyson Jones

Definition at line 896 of file test_utilities.cpp.

898 {
899 int ctrls[1] = {ctrl};
900 int targs[1] = {targ};
901 applyReferenceOp(state, ctrls, 1, targs, 1, op);
902}

◆ applyReferenceOp() [15/16]

void applyReferenceOp ( QVector & state,
int ctrl,
int targ1,
int targ2,
QMatrix op )

Modifies the state-vector state to be the result of applying the two-target operator matrix op, with a single control qubit (ctrl). This updates state under

\[ \text{state} \to \text{op} \, \text{state} \]

even if op is not unitary.

op must be a 4-by-4 matrix. Furthermore, ctrl, targ1 and targ2 should all be unique.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multiplying it onto state.

Author
Tyson Jones

Definition at line 909 of file test_utilities.cpp.

911 {
912 int ctrls[1] = {ctrl};
913 int targs[2] = {targ1, targ2};
914 applyReferenceOp(state, ctrls, 1, targs, 2, op);
915}

◆ applyReferenceOp() [16/16]

void applyReferenceOp ( QVector & state,
int targ,
QMatrix op )

Modifies the state-vector state to be the result of applying the single-target operator matrix op, with no contorl qubits. This updates state under

\[ \text{state} \to \text{op} \, \text{state} \]

even if op is not unitary.

op must be a 2-by-2 matrix.

This function works by computing getFullOperatorMatrix() from the given arguments, and left-multiplying it onto state.

Author
Tyson Jones

Definition at line 916 of file test_utilities.cpp.

918 {
919 int targs[1] = {targ};
920 applyReferenceOp(state, NULL, 0, targs, 1, op);
921}

◆ areEqual() [1/10]

bool areEqual ( QMatrix a,
QMatrix b )

Returns true if the absolute value of the difference between every amplitude in matrices a and b is less than REAL_EPS.

Author
Tyson Jones

Definition at line 524 of file test_utilities.cpp.

524 {
525 DEMAND( a.size() == b.size() );
526
527 for (size_t i=0; i<a.size(); i++)
528 for (size_t j=0; j<b.size(); j++)
529 if (abs(a[i][j] - b[i][j]) > REAL_EPS)
530 return false;
531 return true;
532}

◆ areEqual() [2/10]

bool areEqual ( Qureg qureg,
QMatrix matr )

Performs a hardware-agnostic comparison of density-matrix qureg to matr, checking whether the difference between the real and imaginary components of every amplitude is smaller than the QuEST_PREC-specific REAL_EPS (defined in QuEST_precision) precision. This function demands qureg is a density matrix, and that qureg and matr have equal dimensions.

In GPU mode, this function involves a GPU to CPU memory copy overhead. In distributed mode, it involves a all-to-all single-int broadcast.

Author
Tyson Jones

Definition at line 1139 of file test_utilities.cpp.

1139 {
1140 return areEqual(qureg, matr, REAL_EPS);
1141}
bool areEqual(QVector a, QVector b)

◆ areEqual() [3/10]

bool areEqual ( Qureg qureg,
QMatrix matr,
qreal precision )

Performs a hardware-agnostic comparison of density-matrix qureg to matr, checking whether the difference between the real and imaginary components of every amplitude is smaller than precision. This function demands qureg is a density matrix, and that qureg and matr have equal dimensions.

In GPU mode, this function involves a GPU to CPU memory copy overhead. In distributed mode, it involves a all-to-all single-int broadcast.

Author
Tyson Jones

Definition at line 1080 of file test_utilities.cpp.

1080 {
1081 DEMAND( qureg.isDensityMatrix );
1082 DEMAND( (long long int) (matr.size()*matr.size()) == qureg.numAmps );
1083
1084 // ensure local qureg amps is up to date
1085 copyStateFromGPU(qureg);
1086 syncQuESTEnv();
1087
1088 // the starting index in vec of this node's qureg partition.
1089 long long int startInd = qureg.rank * qureg.numAmpsPerNode;
1090 long long int globalInd, row, col, i;
1091 int ampsAgree;
1092
1093 // compare each of this node's amplitude to the corresponding matr sub-matrix
1094 for (i=0; i<qureg.numAmpsPerNode; i++) {
1095 globalInd = startInd + i;
1096 row = globalInd % matr.size();
1097 col = globalInd / matr.size();
1098
1099 qreal realDif = absReal(real(qureg.cpuAmps[i]) - real(matr[row][col]));
1100 qreal imagDif = absReal(imag(qureg.cpuAmps[i]) - imag(matr[row][col]));
1101 ampsAgree = (realDif < precision && imagDif < precision);
1102
1103 // DEBUG
1104 if (!ampsAgree) {
1105 char buff[200];
1106 snprintf(buff, 200, "[msg from utilities.cpp] node %d has a disagreement at %lld of (%s) + i(%s):\n\t[qureg] %s + i(%s) VS [ref] %s + i(%s)\n",
1107 qureg.rank, startInd+i,
1110 printf(buff,
1111 realDif, imagDif,
1112 real(qureg.cpuAmps[i]), imag(qureg.cpuAmps[i]),
1113 real(matr[row][col]), imag(matr[row][col]));
1114 }
1115
1116 // break loop as soon as amplitudes disagree
1117 if (!ampsAgree)
1118 break;
1119
1120 /* TODO:
1121 * of the nodes which disagree, the lowest-rank should send its
1122 * disagreeing (i, row, col, stateVec[i]) to rank 0 which should
1123 * report it immediately (before the impending DEMAND failure)
1124 * using FAIL_CHECK, so users can determine nature of disagreement
1125 * (e.g. numerical precision).
1126 * Note FAIL_CHECK accepts << like cout, e.g.
1127 * FAIL_CHECK( "Amp at (" << row << ", " << col ") disagreed" );
1128 */
1129 }
1130
1131 // if one node's partition wasn't equal, all-nodes must report not-equal
1132 int allAmpsAgree = ampsAgree;
1133#if COMPILE_MPI
1134 MPI_Allreduce(&ampsAgree, &allAmpsAgree, 1, MPI_INT, MPI_LAND, MPI_COMM_WORLD);
1135#endif
1136
1137 return allAmpsAgree;
1138}
void syncQuESTEnv()
const char * QREAL_FORMAT_SPECIFIER
Definition precision.h:177

◆ areEqual() [4/10]

bool areEqual ( Qureg qureg,
QVector vec )

Performs a hardware-agnostic comparison of state-vector qureg to vec, checking whether the difference between the real and imaginary components of every amplitude is smaller than the QuEST_PREC-specific REAL_EPS (defined in QuEST_precision) precision. This function demands qureg is a state-vector, and that qureg and vec have the same number of amplitudes.

In GPU mode, this function involves a GPU to CPU memory copy overhead. In distributed mode, it involves a all-to-all single-int broadcast.

Author
Tyson Jones

Definition at line 1076 of file test_utilities.cpp.

1076 {
1077 return areEqual(qureg, vec, REAL_EPS);
1078}

◆ areEqual() [5/10]

bool areEqual ( Qureg qureg,
QVector vec,
qreal precision )

Performs a hardware-agnostic comparison of state-vector qureg to vec, checking whether the difference between the real and imaginary components of every amplitude is smaller than precision. This function demands qureg is a state-vector, and that qureg and vec have the same number of amplitudes.

In GPU mode, this function involves a GPU to CPU memory copy overhead. In distributed mode, it involves a all-to-all single-int broadcast.

Author
Tyson Jones

Definition at line 1036 of file test_utilities.cpp.

1036 {
1037 DEMAND( !qureg.isDensityMatrix );
1038 DEMAND( (int) vec.size() == qureg.numAmps );
1039
1040 copyStateFromGPU(qureg);
1041 syncQuESTEnv();
1042
1043 // the starting index in vec of this node's qureg partition.
1044 long long int startInd = qureg.rank * qureg.numAmpsPerNode;
1045
1046 int ampsAgree = 1;
1047 for (long long int i=0; i<qureg.numAmpsPerNode; i++) {
1048 qcomp dif = (qureg.cpuAmps[i] - vec[startInd+i]);
1049
1050 if (absComp(dif) > precision) {
1051 ampsAgree = 0;
1052
1053 // debug
1054 char buff[200];
1055 snprintf(buff, 200, "Disagreement at %lld of (%s) + i(%s):\n\t%s + i(%s) VS %s + i(%s)\n",
1056 startInd+i,
1059 printf(buff,
1060 real(dif), imag(dif),
1061 real(qureg.cpuAmps[i]), imag(qureg.cpuAmps[i]),
1062 real(vec[startInd+i]), imag(vec[startInd+i]));
1063
1064 break;
1065 }
1066 }
1067
1068 // if one node's partition wasn't equal, all-nodes must report not-equal
1069 int allAmpsAgree = ampsAgree;
1070#if COMPILE_MPI
1071 MPI_Allreduce(&ampsAgree, &allAmpsAgree, 1, MPI_INT, MPI_LAND, MPI_COMM_WORLD);
1072#endif
1073
1074 return allAmpsAgree;
1075}

◆ areEqual() [6/10]

bool areEqual ( Qureg qureg1,
Qureg qureg2 )

Performs a hardware-agnostic comparison of the given quregs, checking whether the difference between the real and imaginary components of every amplitude is smaller than the QuEST_PREC-specific REAL_EPS (defined in QuEST_precision) precision. This function demands that qureg1 and qureg2 are of the same type (i.e. both state-vectors or both density matrices), and of an equal number of qubits.

In GPU mode, this function involves a GPU to CPU memory copy overhead. In distributed mode, it involves a all-to-all single-int broadcast.

Author
Tyson Jones

Definition at line 1032 of file test_utilities.cpp.

1032 {
1033 return areEqual(qureg1, qureg2, REAL_EPS);
1034}

◆ areEqual() [7/10]

bool areEqual ( Qureg qureg1,
Qureg qureg2,
qreal precision )

Performs a hardware-agnostic comparison of the given quregs, checking whether the difference between the real and imaginary components of every amplitude is smaller than precision. This function demands that qureg1 and qureg2 are of the same type (i.e. both state-vectors or both density matrices), and of an equal number of qubits.

In GPU mode, this function involves a GPU to CPU memory copy overhead. In distributed mode, it involves a all-to-all single-int broadcast.

Author
Tyson Jones

Definition at line 1011 of file test_utilities.cpp.

1011 {
1012 DEMAND( qureg1.isDensityMatrix == qureg2.isDensityMatrix );
1013 DEMAND( qureg1.numAmps == qureg2.numAmps );
1014
1015 copyStateFromGPU(qureg1);
1016 copyStateFromGPU(qureg2);
1017 syncQuESTEnv();
1018
1019 // loop terminates when areEqual = 0
1020 int ampsAgree = 1;
1021 for (long long int i=0; ampsAgree && i<qureg1.numAmpsPerNode; i++)
1022 ampsAgree = absComp(qureg1.cpuAmps[i] - qureg2.cpuAmps[i]) < precision;
1023
1024 // if one node's partition wasn't equal, all-nodes must report not-equal
1025 int allAmpsAgree = ampsAgree;
1026#if COMPILE_MPI
1027 MPI_Allreduce(&ampsAgree, &allAmpsAgree, 1, MPI_INT, MPI_LAND, MPI_COMM_WORLD);
1028#endif
1029
1030 return allAmpsAgree;
1031}

◆ areEqual() [8/10]

bool areEqual ( QVector a,
QVector b )

Returns true if the absolute value of the difference between every amplitude in vectors a and b is less than REAL_EPS.

Author
Tyson Jones

Definition at line 515 of file test_utilities.cpp.

515 {
516 DEMAND( a.size() == b.size() );
517
518 for (size_t i=0; i<a.size(); i++)
519 if (abs(a[i] - b[i]) > REAL_EPS)
520 return false;
521 return true;
522}

Referenced by areEqual(), areEqual(), areEqual(), assertQuregAndRefInDebugState(), assertQuregAndRefInDebugState(), getRandomKrausMap(), getRandomUnitary(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ areEqual() [9/10]

bool areEqual ( QVector vec,
qreal * reals )

Returns true if the absolute value of the difference between every element in vec (which must be strictly real) and those implied by reals, is less than REAL_EPS.

Author
Tyson Jones

Definition at line 1157 of file test_utilities.cpp.

1157 {
1158 for (size_t i=0; i<vec.size(); i++) {
1159 DEMAND( imag(vec[i]) == 0. );
1160
1161 qreal dif = abs(real(vec[i]) - reals[i]);
1162 if (dif > REAL_EPS)
1163 return false;
1164 }
1165 return true;
1166}

◆ areEqual() [10/10]

bool areEqual ( QVector vec,
qreal * reals,
qreal * imags )

Returns true if the absolute value of the difference between every element in vec and those implied by reals and imags, is less than REAL_EPS.

Author
Tyson Jones

Definition at line 1143 of file test_utilities.cpp.

1143 {
1144
1145 qreal dif;
1146 for (size_t i=0; i<vec.size(); i++) {
1147 dif = absReal(real(vec[i]) - reals[i]);
1148 if (dif > REAL_EPS)
1149 return false;
1150 dif = absReal(imag(vec[i]) - imags[i]);
1151 if (dif > REAL_EPS)
1152 return false;
1153 }
1154 return true;
1155}

◆ assertQuregAndRefInDebugState() [1/2]

void assertQuregAndRefInDebugState ( Qureg qureg,
QMatrix ref )

Asserts the given density qureg and reference agree, and are properly initialised in the debug state. Assertion uses the DEMAND() macro, calling Catch2's FAIL() if unsatisfied, so does not contribute toward unit test statistics. This should be called within every PREPARE_TEST macro, to ensure that the test states themselves are initially correct, and do not accidentally agree by (e.g.) being all-zero.

Author
Tyson Jones

Definition at line 233 of file test_utilities.cpp.

233 {
234 DEMAND( qureg.isDensityMatrix == 1 );
235 DEMAND( (1LL << qureg.numQubits) == (long long int) ref.size() );
236
237 // assert ref is in the (column-wise) debug state (else initDebugState failed)
238 size_t i = 0;
239 for (size_t c=0; c<ref.size(); c++) {
240 for (size_t r=0; r<ref.size(); r++) {
241 qcomp val = qcomp(.2*i, .2*i+.1);
242 DEMAND( abs(ref[r][c] - val) < REAL_EPS );
243 i++;
244 }
245 }
246
247 // check qureg and ref agree
248 DEMAND( areEqual(qureg, ref) );
249}

◆ assertQuregAndRefInDebugState() [2/2]

void assertQuregAndRefInDebugState ( Qureg qureg,
QVector ref )

Asserts the given statevector qureg and reference agree, and are properly initialised in the debug state. Assertion uses the DEMAND() macro, calling Catch2's FAIL() if unsatisfied, so does not contribute toward unit test statistics. This should be called within every PREPARE_TEST macro, to ensure that the test states themselves are initially correct, and do not accidentally agree by (e.g.) being all-zero.

Author
Tyson Jones

Definition at line 219 of file test_utilities.cpp.

219 {
220 DEMAND( qureg.isDensityMatrix == 0 );
221 DEMAND( qureg.numAmps == (long long int) ref.size() );
222
223 // assert ref is in the debug state (else initDebugState failed)
224 for (size_t i=0; i<ref.size(); i++) {
225 qcomp val = qcomp(.2*i, .2*i+.1);
226 DEMAND( abs(ref[i] - val) < REAL_EPS );
227 }
228
229 // check qureg and ref agree
230 DEMAND( areEqual(qureg, ref) );
231}

◆ bitsets()

CatchGen< int * > bitsets ( int numBits)

Returns a Catch2 generator of every numBits-length bit-set, in increasing lexographic order, where left-most (zero index) bit is treated as LEAST significant (opposite typical convention). Note that the produced bitset must not be modified during generation.

This function can be used like

int* bits = GENERATE( bitsets(3) );

to produce {0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}, {0,0,1}, {1,0,1}, {0,1,1}, {1,1,1}.

Author
Tyson Jones

Definition at line 1723 of file test_utilities.cpp.

1723 {
1724 return Catch::Generators::GeneratorWrapper<int*>(
1725 Catch::Detail::make_unique<SequenceGenerator<int>>(1, numBits));
1726}

Referenced by TEST_CASE().

◆ calcLog2()

unsigned int calcLog2 ( long unsigned int res)

Returns log2 of numbers which must be gauranteed to be 2^n

Author
Tyson Jones

Definition at line 488 of file test_utilities.cpp.

488 {
489 unsigned int n = 0;
490 while (res >>= 1)
491 n++;
492 return n;
493}

Referenced by applyReferenceMatrix(), applyReferenceOp(), applyReferenceOp(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ deleteFilesWithPrefixSynch()

void deleteFilesWithPrefixSynch ( char * prefix)

Deletes all files with filename starting with prefix. In distributed mode, the master node deletes while the other nodes wait until complete.

Author
Tyson Jones

Definition at line 1543 of file test_utilities.cpp.

1543 {
1544
1545 // master node deletes all files
1546 if (getQuESTEnv().rank == 0) {
1547 char cmd[200];
1548 snprintf(cmd, 200, "exec rm %s*", prefix);
1549 system(cmd);
1550 }
1551
1552 // other nodes wait
1553 syncQuESTEnv();
1554}
QuESTEnv getQuESTEnv()

◆ getConjugateTranspose()

QMatrix getConjugateTranspose ( QMatrix a)

Returns the conjugate transpose of the complex square matrix a

Author
Tyson Jones

Definition at line 291 of file linalg.cpp.

291 {
292 DEMAND( m.size() > 0 );
293
294 // unlike most functions which assume qmatrix
295 // is square, this one cheekily handles when
296 // 'm' is non-square, since necessary for
297 // computing partial traces
298
299 qmatrix out(m[0].size(), qvector(m.size()));
300
301 for (size_t r=0; r<out.size(); r++)
302 for (size_t c=0; c<out[0].size(); c++)
303 out[r][c] = std::conj(m[c][r]);
304
305 return out;
306}

Referenced by applyReferenceOp(), getRandomKrausMap(), getRandomUnitary(), TEST_CASE(), and TEST_CASE().

◆ getDFT() [1/2]

QVector getDFT ( QVector in)

Returns the discrete fourier transform of vector in

Author
Tyson Jones

Definition at line 795 of file test_utilities.cpp.

795 {
796 REQUIRE( in.size() > 0 );
797
798 size_t dim = in.size();
799 qreal ampFac = 1 / sqrt( dim );
800 qreal phaseFac = 2 * M_PI / dim;
801
802 QVector dftVec = QVector(dim);
803
804 for (size_t x=0; x<dim; x++) {
805 dftVec[x] = 0;
806 for (size_t y=0; y<dim; y++)
807 dftVec[x] += expI(phaseFac * x * y) * in[y];
808 dftVec[x] *= ampFac;
809 }
810 return dftVec;
811}
vector< qcomp > QVector

Referenced by TEST_CASE(), and TEST_CASE().

◆ getDFT() [2/2]

QVector getDFT ( QVector in,
int * targs,
int numTargs )

Returns the discrete fourier transform of a sub-partition of the vector in.

Author
Tyson Jones

Definition at line 843 of file test_utilities.cpp.

843 {
844
845 QVector out = QVector(in.size());
846 long long int inDim = (long long int) in.size();
847 long long int targDim = (1LL << numTargs);
848
849 for (long long int j=0; j<inDim; j++) {
850
851 // |j> = |x> (x) |...>, but mixed (not separated)
852 long long int x = getValueOfTargets(j, targs, numTargs);
853
854 for (long long int y=0; y<targDim; y++) {
855
856 // modifies sum_y |y> (x) ...
857 long long int outInd = getIndexOfTargetValues(j, targs, numTargs, y);
858
859 qcomp elem = (in[j] / sqrt(pow(2,numTargs))) * expI(2*M_PI * x * y / pow(2,numTargs));
860 out[outInd] += elem;
861 }
862 }
863
864 return out;
865}
long long int getValueOfTargets(long long int ind, int *targs, int numTargs)

◆ getExponentialOfDiagonalMatrix()

QMatrix getExponentialOfDiagonalMatrix ( QMatrix a)

Returns the matrix exponential of a diagonal, square, complex matrix. This method explicitly checks that the passed matrix a is diagonal.

Author
Tyson Jones

Definition at line 336 of file linalg.cpp.

336 {
337 DEMAND( isDiagonal(m) );
338
339 qmatrix out = getZeroMatrix(m.size());
340
341 for (size_t i=0; i<m.size(); i++)
342 out[i][i] = std::exp(m[i][i]);
343
344 return out;
345}
qmatrix getZeroMatrix(size_t dim)
Definition qmatrix.cpp:18

Referenced by TEST_CASE(), and TEST_CASE().

◆ getExponentialOfPauliMatrix()

QMatrix getExponentialOfPauliMatrix ( qreal angle,
QMatrix a )

Returns the matrix exponential of a kronecker product of pauli matrices (or of any involutory matrices), with exponent factor (-i angle / 2). This method will not explicitly check that the passed matrix a is kronecker product of involutory matrices, but will otherwise return an incorrect exponential.

Author
Tyson Jones

Definition at line 348 of file linalg.cpp.

348 {
349
350 // exp(-i arg/2 m) where m = prod(paulis)
351 qmatrix id = getIdentityMatrix(m.size());
352 qmatrix out = std::cos(arg/2)*id - 1_i*std::sin(arg/2)*m;
353 return out;
354}
qmatrix getIdentityMatrix(size_t dim)
Definition qmatrix.cpp:30

Referenced by TEST_CASE(), and TEST_CASE().

◆ getFullOperatorMatrix()

QMatrix getFullOperatorMatrix ( int * ctrls,
int numCtrls,
int * targs,
int numTargs,
QMatrix op,
int numQubits )

Takes a 2^numTargs-by-2^numTargs matrix op and a returns a 2^numQubits-by-2^numQubits matrix where op is controlled on the given ctrls qubits. The union of {ctrls} and {targs} must be unique (though this is not explicitly checked), and every element must be >= 0 (not checked). The passed {ctrls} and {targs} arrays are unmodified.

This funciton works by first swapping {targs} and {ctrls} (via swap unitaries) to be strictly increasing {0,1,...}, building controlled(op), tensoring it to the full Hilbert space, and then 'unswapping'. The returned matrix has form: swap1 ... swapN . controlled(op) . swapN ... swap1

Author
Tyson Jones

Definition at line 420 of file test_utilities.cpp.

422 {
423 DEMAND( numCtrls >= 0 );
424 DEMAND( numTargs >= 0 );
425 DEMAND( numQubits >= (numCtrls+numTargs) );
426 DEMAND( op.size() == (1u << numTargs) );
427
428 // copy {ctrls} and {targs}to restore at end
429 vector<int> ctrlsCopy(ctrls, ctrls+numCtrls);
430 vector<int> targsCopy(targs, targs+numTargs);
431
432 // full-state matrix of qubit swaps
433 QMatrix swaps = getIdentityMatrix(1 << numQubits);
434 QMatrix unswaps = getIdentityMatrix(1 << numQubits);
435 QMatrix matr;
436
437 // swap targs to {0, ..., numTargs-1}
438 for (int i=0; i<numTargs; i++) {
439 if (i != targs[i]) {
440 matr = getSwapMatrix(i, targs[i], numQubits);
441 swaps = matr * swaps;
442 unswaps = unswaps * matr;
443
444 // even if this is the last targ, ctrls might still need updating
445 updateIndices(
446 i, targs[i], (i < numTargs-1)? &targs[i+1] : NULL,
447 numTargs-i-1, ctrls, numCtrls);
448 }
449 }
450
451 // swap ctrls to {numTargs, ..., numTargs+numCtrls-1}
452 for (int i=0; i<numCtrls; i++) {
453 int newInd = numTargs+i;
454 if (newInd != ctrls[i]) {
455 matr = getSwapMatrix(newInd, ctrls[i], numQubits);
456 swaps = matr * swaps;
457 unswaps = unswaps * matr;
458
459 // update remaining ctrls (if any exist)
460 if (i < numCtrls-1)
461 updateIndices(newInd, ctrls[i], NULL, 0, &ctrls[i+1], numCtrls-i-1);
462 }
463 }
464
465 // construct controlled-op matrix for qubits {0, ..., numCtrls+numTargs-1}
466 size_t dim = 1 << (numCtrls+numTargs);
467 QMatrix fullOp = getIdentityMatrix(dim);
468 setSubMatrix(fullOp, op, dim-op.size(), dim-op.size());
469
470 // create full-state controlled-op matrix (left-pad identities)
471 if (numQubits > numCtrls+numTargs) {
472 size_t pad = 1 << (numQubits - numCtrls - numTargs);
473 fullOp = getKroneckerProduct(getIdentityMatrix(pad), fullOp);
474 }
475
476 // apply swap to either side (to swap qubits back and forth)
477 fullOp = unswaps * fullOp * swaps;
478
479 // restore {ctrls and targs}
480 for (int i=0; i<numCtrls; i++)
481 ctrls[i] = ctrlsCopy[i];
482 for (int i=0; i<numTargs; i++)
483 targs[i] = targsCopy[i];
484
485 return fullOp;
486}
QMatrix getSwapMatrix(int qb1, int qb2, int numQb)
QVector getKroneckerProduct(QVector b, QVector a)
void setSubMatrix(QMatrix &dest, QMatrix sub, size_t r, size_t c)

Referenced by applyReferenceMatrix(), applyReferenceOp(), applyReferenceOp(), TEST_CASE(), and TEST_CASE().

◆ getIdentityMatrix()

QMatrix getIdentityMatrix ( size_t dim)

Returns a dim-by-dim identity matrix

Author
Tyson Jones

Definition at line 30 of file qmatrix.cpp.

30 {
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}

Referenced by getExponentialOfPauliMatrix(), getExponentialOfPauliMatrix(), getFullOperatorMatrix(), getRandomKrausMap(), getRandomUnitary(), getSwapMatrix(), and TEST_CASE().

◆ getKetBra()

QMatrix getKetBra ( QVector ket,
QVector bra )

Returns the matrix |ket><bra|, with ith-jth element ket(i) conj(bra(j)), since |ket><bra| = sum_i a_i|i> sum_j b_j* <j| = sum_{ij} a_i b_j* |i><j|. The dimensions of bra and ket must agree, and the returned square complex matrix has dimensions size(bra) x size(bra).

Author
Tyson Jones

Definition at line 277 of file test_utilities.cpp.

277 {
278 DEMAND( ket.size() == bra.size() );
279 QMatrix mat = getZeroMatrix(ket.size());
280
281 for (size_t r=0; r<ket.size(); r++)
282 for (size_t c=0; c<ket.size(); c++)
283 mat[r][c] = ket[r] * conj(bra[c]);
284 return mat;
285}

Referenced by getPureDensityMatrix(), getRandomDensityMatrix(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getKroneckerProduct() [1/2]

QMatrix getKroneckerProduct ( QMatrix a,
QMatrix b )

Returns the kronecker product of a and b, where a and b are square but possibly differently-sized complex matrices.

Author
Tyson Jones

Definition at line 523 of file linalg.cpp.

523 {
524
525 // we permit the matrices to be non-square which is
526 // pretty cheeky (since qmatrix is assumed square with
527 // a 2^N dimension by most other functions), but is
528 // necessary for us to compute partial traces
529
530 size_t aRows = a.size();
531 size_t bRows = b.size();
532 size_t aCols = a[0].size();
533 size_t bCols = b[0].size();
534
535 qmatrix out(aRows * bRows, qvector(aCols * bCols));
536
537 for (size_t r=0; r<bRows; r++)
538 for (size_t c=0; c<bCols; c++)
539 for (size_t i=0; i<aRows; i++)
540 for (size_t j=0; j<aCols; j++)
541 out[r+bRows*i][c+bCols*j] = a[i][j] * b[r][c];
542
543 return out;
544}

Referenced by getSwapMatrix(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getKroneckerProduct() [2/2]

QVector getKroneckerProduct ( QVector b,
QVector a )

Returns b (otimes) a. If b and a are state-vectors, the resulting kronecker product is the seperable state formed by joining the qubits in the state-vectors, producing |b>|a> (a is least significant)

Author
Tyson Jones

Definition at line 251 of file test_utilities.cpp.

251 {
252
253 QVector prod = QVector(a.size() * b.size());
254
255 for (size_t i=0; i<prod.size(); i++)
256 prod[i] = b[i / a.size()] * a[i % a.size()];
257
258 return prod;
259}

Referenced by getFullOperatorMatrix(), getSwapMatrix(), and toQMatrix().

◆ getMatrixDiagonal()

QVector getMatrixDiagonal ( QMatrix matr)

Returns the diagonal vector of the given matrix

Author
Tyson Jones

Definition at line 633 of file test_utilities.cpp.

633 {
634
635 QVector vec = QVector(matr.size());
636 for (size_t i=0; i<vec.size(); i++)
637 vec[i] = matr[i][i];
638
639 return vec;
640}

◆ getMixedDensityMatrix()

QMatrix getMixedDensityMatrix ( vector< qreal > probs,
vector< QVector > states )

Returns a mixed density matrix formed from mixing the given pure states, which are assumed normalised, but not necessarily orthogonal.

Author
Tyson Jones

Definition at line 783 of file test_utilities.cpp.

783 {
784 DEMAND( probs.size() == states.size() );
785 DEMAND( probs.size() >= 1 );
786
787 QMatrix matr = getZeroMatrix(states[0].size());
788
789 for (size_t i=0; i<probs.size(); i++)
790 matr += probs[i] * getPureDensityMatrix(states[i]);
791
792 return matr;
793}
QMatrix getPureDensityMatrix(QVector state)

Referenced by TEST_CASE(), and TEST_CASE().

◆ getNormalised()

QVector getNormalised ( QVector vec)

Returns an L2-normalised copy of vec, using Kahan summation for improved accuracy.

Author
Tyson Jones

Definition at line 560 of file test_utilities.cpp.

560 {
561
562 // compute the vec norm via Kahan summation to suppress numerical error
563 qreal norm = 0;
564 qreal y, t, c;
565 c = 0;
566
567 for (size_t i=0; i<vec.size(); i++) {
568 y = real(vec[i])*real(vec[i]) - c;
569 t = norm + y;
570 c = ( t - norm ) - y;
571 norm = t;
572
573 y = imag(vec[i])*imag(vec[i]) - c;
574 t = norm + y;
575 c = ( t - norm ) - y;
576 norm = t;
577 }
578
579 for (size_t i=0; i<vec.size(); i++)
580 vec[i] /= sqrt(norm);
581 return vec;
582}

Referenced by getRandomOrthonormalVectors(), and getRandomStateVector().

◆ getPureDensityMatrix()

QMatrix getPureDensityMatrix ( QVector state)

Returns a density matrix initialised into the given pure state

Author
Tyson Jones

Definition at line 623 of file test_utilities.cpp.

623 {
624 return getKetBra(state, state);
625}
QMatrix getKetBra(QVector ket, QVector bra)

Referenced by getMixedDensityMatrix(), getRandomPureDensityMatrix(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomComplex()

qcomp getRandomComplex ( )

Returns a random complex number within the square closing (-1-i) and (1+i), from a distribution uniformly randomising the individual real and imaginary components in their domains.

Author
Tyson Jones

Definition at line 107 of file random.cpp.

107 {
108 qreal re = getRandomReal(-1,1);
109 qreal im = getRandomReal(-1,1);
110 return qcomp(re, im);
111}
qreal getRandomReal(qreal min, qreal maxExcl)
Definition random.cpp:63

Referenced by getRandomQVector(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomDensityMatrix()

QMatrix getRandomDensityMatrix ( int numQb)

Returns a random numQb-by-numQb density matrix, from an undisclosed distribution, in a very mixed state. This function works by generating 2^numQb random pure states, and mixing them with random probabilities.

Author
Tyson Jones

Definition at line 308 of file random.cpp.

308 {
309 DEMAND( numQb > 0 );
310
311 // generate random probabilities to weight random pure states
312 int dim = getPow2(numQb);
313 vector<qreal> probs = getRandomProbabilities(dim);
314
315 // add random pure states
316 qmatrix dens = getZeroMatrix(dim);
317 for (int i=0; i<dim; i++) {
318 qvector pure = getRandomStateVector(numQb);
319 dens += probs[i] * getOuterProduct(pure, pure);
320 }
321
322 return dens;
323}
qvector getRandomStateVector(int numQb)
Definition random.cpp:296
vector< qreal > getRandomProbabilities(int numProbs)
Definition random.cpp:160

Referenced by TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomInt()

int getRandomInt ( int min,
int max )

Returns a random integer between min (inclusive) and max (exclusive), from the uniform distribution. Demands that max > min.

Author
Tyson Jones

Definition at line 90 of file random.cpp.

90 {
91 DEMAND( maxExcl >= min );
92
93 // permit this out of convenience
94 // for some test generators
95 if (min == maxExcl)
96 return min;
97
98 qreal r = std::floor(getRandomReal(min, maxExcl));
99 int out = static_cast<int>(r);
100
101 DEMAND( out >= min );
102 DEMAND( out < maxExcl );
103 return out;
104}

Referenced by setRandomPauliSum(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomKrausMap()

vector< QMatrix > getRandomKrausMap ( int numQb,
int numOps )

Returns a random Kraus map of #numOps 2^numQb-by-2^numQb operators, from an undisclosed distribution. Note this method is very simple and cannot generate all possible Kraus maps. It works by generating numOps random unitary matrices, and randomly re-normalising them, such that the sum of ops[j]^dagger ops[j] = 1

Author
Tyson Jones

Definition at line 405 of file random.cpp.

405 {
406 DEMAND( numOps >= 1 );
407
408 // generate random unitaries
409 vector<qmatrix> ops(numOps);
410 for (auto& u : ops)
411 u = getRandomUnitary(numQb);
412
413 // generate random weights
414 vector<qreal> weights(numOps);
415 for (auto& w : weights)
416 w = getRandomReal(0, 1);
417
418 // normalise random weights
419 qreal sum = 0;
420 for (auto& w : weights)
421 sum += w;
422 for (auto& w : weights)
423 w = std::sqrt(w/sum);
424
425 // normalise unitaries according to weights
426 for (int i=0; i<numOps; i++)
427 ops[i] *= weights[i];
428
429 DEMAND( isApproxCPTP(ops) );
430 return ops;
431}
qmatrix getRandomUnitary(int numQb)
Definition random.cpp:348

Referenced by TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomOrthonormalVectors()

vector< QVector > getRandomOrthonormalVectors ( int numQb,
int numStates )

Returns a list of random orthonormal complex vectors, from an undisclosed distribution.

Author
Tyson Jones

Definition at line 756 of file test_utilities.cpp.

756 {
757 DEMAND( numQb >= 1 );
758 DEMAND( numStates >= 1);
759
760 // set of orthonormal vectors
761 vector<QVector> vecs;
762
763 for (int n=0; n<numStates; n++) {
764
765 QVector vec = getRandomStateVector(numQb);
766
767 // orthogonalise by substracting projections of existing vectors
768 for (int m=0; m<n; m++) {
769 qcomp prod = vec * vecs[m];
770 vec -= (prod * vecs[m]);
771 }
772
773 // renormalise
774 vec = getNormalised(vec);
775
776 // add to orthonormal set
777 vecs.push_back(vec);
778 }
779
780 return vecs;
781}
QVector getNormalised(QVector vec)

◆ getRandomProbabilities()

vector< qreal > getRandomProbabilities ( int numProbs)

Returns a list of random real scalars, each in [0, 1], which sum to unity.

Author
Tyson Jones

Definition at line 160 of file random.cpp.

160 {
161
162 vector<qreal> probs(numProbs, 0);
163
164 // generate random unnormalised scalars
165 for (auto& p : probs)
166 p = getRandomReal(0, 1);
167
168 // normalise
169 qreal total = 0;
170 for (auto& p : probs)
171 total += p;
172
173 for (auto& p : probs)
174 p /= total;
175
176 return probs;
177}

Referenced by getRandomDensityMatrix(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomPureDensityMatrix()

QMatrix getRandomPureDensityMatrix ( int numQb)

Returns a random numQb-by-numQb density matrix, from an undisclosed distribution, which is pure (corresponds to a random state-vector)

Author
Tyson Jones

Definition at line 326 of file random.cpp.

326 {
327
328 qvector vec = getRandomStateVector(numQb);
329 qmatrix mat = getOuterProduct(vec, vec);
330 return mat;
331}

◆ getRandomQMatrix()

QMatrix getRandomQMatrix ( int dim)

Returns a dim-by-dim complex matrix, where the real and imaginary value of each element are independently random, under the standard normal distribution (mean 0, standard deviation 1).

Author
Tyson Jones

Definition at line 495 of file test_utilities.cpp.

495 {
496 DEMAND( dim > 1 );
497
498 QMatrix matr = getZeroMatrix(dim);
499 for (int i=0; i<dim; i++) {
500 for (int j=0; j<dim; j++) {
501
502 // generate 2 normally-distributed random numbers via Box-Muller
503 qreal a = rand()/(qreal) RAND_MAX;
504 qreal b = rand()/(qreal) RAND_MAX;
505 if (a == 0) a = REAL_EPS; // prevent rand()=0 creation of NaN
506 qreal r1 = sqrt(-2 * log(a)) * cos(2 * 3.14159265 * b);
507 qreal r2 = sqrt(-2 * log(a)) * sin(2 * 3.14159265 * b);
508
509 matr[i][j] = r1 + r2 * (qcomp) 1i;
510 }
511 }
512 return matr;
513}

Referenced by getRandomUnitary(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomQVector()

QVector getRandomQVector ( int dim)

Returns a dim-length vector with random complex amplitudes in the square joining {-1-i, 1+i}, of an undisclosed distribution. The resulting vector is NOT L2-normalised.

Author
Tyson Jones

Definition at line 552 of file test_utilities.cpp.

552 {
553 QVector vec = QVector(dim);
554 for (int i=0; i<dim; i++)
555 vec[i] = getRandomComplex();
556
557 return vec;
558}
qcomp getRandomComplex()

Referenced by getRandomStateVector(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomReal()

qreal getRandomReal ( qreal min,
qreal max )

Returns a random real between min (inclusive) and max (exclusive), from the uniform distribution. Demands that max > min.

Author
Tyson Jones

Definition at line 63 of file random.cpp.

63 {
64 DEMAND( min < maxExcl );
65
66 // advance RNG on every node, identically
67 std::uniform_real_distribution<qreal> dist(min,maxExcl);
68 qreal out = dist(RNG);
69
70 // note despite the doc asserting maxExcl is exclusive,
71 // uniform_real_distribution() can indeed return it! In that
72 // case, we substract machine-eps for caller integrity
73 if (out >= maxExcl)
74 out = std::nextafter(maxExcl, min);
75
76 DEMAND( out >= min );
77 DEMAND( out < maxExcl );
78 return out;
79}

Referenced by getRandomComplex(), getRandomInt(), getRandomInt(), getRandomKrausMap(), getRandomProbabilities(), setRandomDiagPauliHamil(), setRandomPauliSum(), setRandomPauliSum(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomStateVector()

QVector getRandomStateVector ( int numQb)

Returns a random numQb-length L2-normalised state-vector from an undisclosed distribution. This function works by randomly generating each complex amplitude, then L2-normalising.

Author
Tyson Jones

Definition at line 296 of file random.cpp.

296 {
297
298 return getNormalised(getRandomVector(getPow2(numQb)));
299}

Referenced by getRandomDensityMatrix(), getRandomOrthonormalVectors(), getRandomPureDensityMatrix(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getRandomUnitary()

QMatrix getRandomUnitary ( int numQb)

Returns a uniformly random (under Haar) 2^numQb-by-2^numQb unitary matrix. This function works by first generating a complex matrix where each element is independently random; the real and imaginary component thereof are independent standard normally-distributed (mean 0, standard-dev 1). Then, the matrix is orthonormalised via the Gram Schmidt algorithm. The resulting unitary matrix MAY be uniformly distributed under the Haar measure, but we make no assurance. This routine may return an identity matrix if it was unable to sufficiently precisely produce a unitary of the given size.

Author
Tyson Jones

Definition at line 348 of file random.cpp.

348 {
349 DEMAND( numQb >= 1 );
350
351 // create Z ~ random complex matrix (distribution not too important)
352 size_t dim = getPow2(numQb);
353 qmatrix matrZ = getRandomMatrix(dim);
354 qmatrix matrZT = getTranspose(matrZ);
355
356 // create Z = Q R (via QR decomposition) ...
357 qmatrix matrQT = getOrthonormalisedRows(matrZ);
358 qmatrix matrQ = getTranspose(matrQT);
359 qmatrix matrR = getZeroMatrix(dim);
360
361 // ... where R_rc = (columm c of Z) . (column r of Q) = (row c of ZT) . (row r of QT) = <r|c>
362 for (size_t r=0; r<dim; r++)
363 for (size_t c=r; c<dim; c++)
364 matrR[r][c] = getInnerProduct(matrQT[r], matrZT[c]);
365
366 // create D = normalised diagonal of R
367 qmatrix matrD = getZeroMatrix(dim);
368 for (size_t i=0; i<dim; i++)
369 matrD[i][i] = matrR[i][i] / std::abs(matrR[i][i]);
370
371 // create U = Q D
372 qmatrix matrU = matrQ * matrD;
373
374 DEMAND( isApproxUnitary(matrU) );
375 return matrU;
376}

Referenced by getRandomKrausMap(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ getSwapMatrix()

QMatrix getSwapMatrix ( int qb1,
int qb2,
int numQb )

Returns the 2^numQb-by-2^numQb unitary matrix which swaps qubits qb1 and qb2; the SWAP gate of not-necessarily-adjacent qubits. If qb1 == qb2, returns the identity matrix.

Author
Tyson Jones

Definition at line 28 of file evolve.cpp.

28 {
29 DEMAND( numQb > 1 );
30 DEMAND( (qb1 >= 0 && qb1 < numQb) );
31 DEMAND( (qb2 >= 0 && qb2 < numQb) );
32
33 if (qb1 == qb2)
34 return getIdentityMatrix(getPow2(numQb));
35
36 if (qb1 > qb2)
37 std::swap(qb1, qb2);
38
39 qmatrix out;
40
41 // qubits are either adjacent
42 if (qb2 == qb1 + 1) {
43 out = qmatrix{{1,0,0,0},{0,0,1,0},{0,1,0,0},{0,0,0,1}};
44
45 // or distant
46 } else {
47 int block = getPow2(qb2 - qb1);
48 out = getZeroMatrix(block*2);
49 qmatrix iden = getIdentityMatrix(block/2);
50
51 // Lemma 3.1 of arxiv.org/pdf/1711.09765.pdf
52 qmatrix p0{{1,0},{0,0}};
53 qmatrix l0{{0,1},{0,0}};
54 qmatrix l1{{0,0},{1,0}};
55 qmatrix p1{{0,0},{0,1}};
56
57 // notating a^(n+1) = identity(getPow2(n)) (otimes) a, we construct the matrix
58 // [ p0^(N) l1^N ]
59 // [ l0^(N) p1^N ]
60 // where N = qb2 - qb1 */
61 setSubMatrix(out, getKroneckerProduct(iden, p0), 0, 0);
62 setSubMatrix(out, getKroneckerProduct(iden, l0), block, 0);
63 setSubMatrix(out, getKroneckerProduct(iden, l1), 0, block);
64 setSubMatrix(out, getKroneckerProduct(iden, p1), block, block);
65 }
66
67 // pad swap with outer identities
68 if (qb1 > 0)
69 out = getKroneckerProduct(out, getIdentityMatrix(getPow2(qb1)));
70
71 if (qb2 < numQb-1)
72 out = getKroneckerProduct(getIdentityMatrix(getPow2(numQb-qb2-1)), out);
73
74 return out;
75}
qmatrix getKroneckerProduct(qmatrix a, qmatrix b)
Definition linalg.cpp:523

Referenced by getFullOperatorMatrix().

◆ getTwosComplement()

long long int getTwosComplement ( long long int decimal,
int numBits )

Returns the two's complement signed encoding of the unsigned number decimal, which must be a number between 0 and 2^numBits (exclusive). The returned number lies in [-2^(numBits-1), 2^(numBits-1)-1]

Author
Tyson Jones

Definition at line 1454 of file test_utilities.cpp.

1454 {
1455 DEMAND( decimal >= 0 );
1456 DEMAND( numBits >= 2 );
1457 DEMAND( decimal < (1LL << numBits) );
1458
1459 long long int maxMag = 1LL << (numBits-1);
1460 if (decimal >= maxMag)
1461 return -maxMag + (decimal - maxMag);
1462 else
1463 return decimal;
1464}

◆ getUnsigned()

long long int getUnsigned ( long long int twosComp,
int numBits )

Return the unsigned value of a number, made of #numBits bits, which under two's complement, encodes the signed number twosComp. The returned number lies in [0, 2^(numBits)-1]

Author
Tyson Jones

Definition at line 1466 of file test_utilities.cpp.

1466 {
1467 DEMAND( numBits >= 2 );
1468 DEMAND( twosComp < (1LL << (numBits-1)) );
1469 DEMAND( twosComp >= - (1LL << (numBits-1)) );
1470
1471 if (twosComp >= 0)
1472 return twosComp;
1473 else
1474 return (1<<numBits) + twosComp;
1475}

◆ getValueOfTargets()

long long int getValueOfTargets ( long long int ind,
int * targs,
int numTargs )

Returns the integer value of the targeted sub-register for the given full state index ind.

Author
Tyson Jones

Definition at line 813 of file test_utilities.cpp.

813 {
814 DEMAND( ind >= 0 );
815
816 long long int val = 0;
817
818 for (int t=0; t<numTargs; t++)
819 val += ((ind >> targs[t]) & 1) * (1LL << t);
820
821 return val;
822}

Referenced by getDFT().

◆ getZeroMatrix()

◆ pauliseqs()

CatchGen< pauliOpType * > pauliseqs ( int numPaulis)

Returns a Catch2 generator of every numPaulis-length set of Pauli-matrix types (or base-4 integers). Generates in increasing lexographic order, where the left-most (zero index) pauli is treated as LEAST significant. Note that the sequence must not be modified during generation.

This function can be used like

pauliOpType* set = GENERATE( pauliseqs(2) );

to produce {I,I}, {X,I}, {Y,I}, {Z,I}, {I,X}, {X,X}, {Y,X}, {Z,X}, {I,Y}, {X,Y}, {Y,Y}, {Z,Y}, {I,Z}, {X,Z}, {Y,Z}, {Z,Z}/

Author
Tyson Jones

Definition at line 1731 of file test_utilities.cpp.

1731 {
1732 return Catch::Generators::GeneratorWrapper<pauliOpType*>(
1733 Catch::Detail::make_unique<SequenceGenerator<pauliOpType>>(PAULI_Z, numPaulis));
1734}

◆ sequences()

CatchGen< int * > sequences ( int base,
int numDigits )

Returns a Catch2 generator of every numDigits-length sequence in the given base, in increasing lexographic order, where left-most (zero index) bit is treated as LEAST significant (opposite typical convention). Note that the sequence must not be modified during generation.

This function can be used like

int base = 3;
int numDigits = 2;
int* seq = GENERATE_COPY( sequences(base, numDigits) );

to produce {0,0}, {1,0}, {2,0}, {0,1}, {1,1}, {2,1}, {0,2}, {1,2}, {2,2}.

Author
Tyson Jones

Definition at line 1727 of file test_utilities.cpp.

1727 {
1728 return Catch::Generators::GeneratorWrapper<int*>(
1729 Catch::Detail::make_unique<SequenceGenerator<int>>(base-1, numDigits));
1730}

◆ setRandomDiagPauliHamil()

void setRandomDiagPauliHamil ( PauliHamil hamil,
int numQubits )

Populates hamil with random coefficients and a random amount number of PAULI_I and PAULI_Z operators.

Author
Tyson Jones

Definition at line 1390 of file test_utilities.cpp.

1390 {
1391 for (int n=0; n<hamil.numTerms; n++) {
1392 hamil.coeffs[n] = getRandomReal(-5, 5);
1393 hamil.strings[n] = getRandomDiagPauliStr(numQubits);
1394 }
1395}

◆ setRandomPauliSum() [1/2]

void setRandomPauliSum ( PauliHamil hamil,
int numQubits )

Populates hamil with random coefficients and pauli codes

Author
Tyson Jones

Definition at line 1382 of file test_utilities.cpp.

1382 {
1383
1384 for (int n=0; n<hamil.numTerms; n++) {
1385 hamil.coeffs[n] = getRandomReal(-5, 5);
1386 hamil.strings[n] = getRandomPauliStr(numQubits);
1387 }
1388}

◆ setRandomPauliSum() [2/2]

void setRandomPauliSum ( qreal * coeffs,
pauliOpType * codes,
int numQubits,
int numTerms )

Populates the coeffs array with random qreals in (-5, 5), and populates codes with random Pauli codes

Author
Tyson Jones

Definition at line 1373 of file test_utilities.cpp.

1373 {
1374 int i=0;
1375 for (int n=0; n<numTerms; n++) {
1376 coeffs[n] = getRandomReal(-5, 5);
1377 for (int q=0; q<numQubits; q++)
1378 codes[i++] = (pauliOpType) getRandomInt(0,4);
1379 }
1380}
int getRandomInt(int min, int max)

Referenced by TEST_CASE().

◆ setRandomTargets() [1/2]

void setRandomTargets ( int * targs,
int numTargs,
int numQb )

Populates targs with a random selection of numTargs elements from [0,numQb-1]. List targs does not need to be initialised and its elements are overwritten.

Author
Tyson Jones

Definition at line 1397 of file test_utilities.cpp.

1397 {
1398 DEMAND( numQb >= 1 );
1399 DEMAND( numTargs >= 1);
1400 DEMAND( numTargs <= numQb );
1401
1402 // create an ordered list of all possible qubits
1403 vector<int> allQb(numQb);
1404 for (int q=0; q<numQb; q++)
1405 allQb[q] = q;
1406
1407 // shuffle all qubits (must be consistent on each node)
1408 std::shuffle(&allQb[0], &allQb[numQb], randomGenerator);
1409
1410 // select numTargs of all qubits
1411 for (int i=0; i<numTargs; i++)
1412 targs[i] = allQb[i];
1413}

Referenced by setRandomTargets(), TEST_CASE(), and TEST_CASE().

◆ setRandomTargets() [2/2]

void setRandomTargets ( vector< int > & targs,
int numQb )

Populates targs with a random selection of elements from [0,numQb-1]. List targs does not need to be initialised and its elements are overwritten.

Author
Tyson Jones

Definition at line 1414 of file test_utilities.cpp.

1414 {
1415
1416 setRandomTargets(targs.data(), targs.size(), numQb);
1417}
void setRandomTargets(int *targs, int numTargs, int numQb)

◆ setRandomTestStateSeeds()

void setRandomTestStateSeeds ( )

Seed the C and C++ RNGs using hardware CSPRNG

Author
Tyson Jones

Definition at line 39 of file random.cpp.

39 {
40 DEMAND( isQuESTEnvInit() );
41
42 // generate a random seed from hardware rng
43 std::random_device cspnrg;
44 unsigned seed = cspnrg();
45
46 // seed QuEST, which uses only the root node's seed
47 setSeeds(&seed, 1);
48
49 // broadcast root node seed to all nodes
50 getSeeds(&seed);
51
52 // seed RNG
53 RNG.seed(seed);
54}
std::vector< unsigned > getSeeds()
Definition debug.cpp:197
void setSeeds(unsigned *seeds, int numSeeds)
Definition debug.cpp:37
int isQuESTEnvInit()

◆ setSubMatrix()

void setSubMatrix ( QMatrix & dest,
QMatrix sub,
size_t r,
size_t c )

Modifies dest by overwriting its submatrix (from top-left corner (r, c) to bottom-right corner (r + dest.size(), c + dest.size()) with the complete elements of sub. This demands that dest.size() >= sub.size() + max(r,c).

Author
Tyson Jones

Definition at line 203 of file qmatrix.cpp.

203 {
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}

Referenced by getFullOperatorMatrix(), getSwapMatrix(), TEST_CASE(), and TEST_CASE().

◆ setUniqueFilename()

void setUniqueFilename ( char * outFn,
int maxlen,
char * prefix )

Modifies the given diagonal matrix such that the diagonal elements which correspond to the coordinates in overrideInds are replaced with exp(i phase), as prescribed by overridePhases. This function assumes that the given registers are contiguous, are in order of increasing significance, and that the matrix is proportionately sized and structured to act on the space of all registers combined. Overrides can be repeated, and only the first encountered for a given index will be effected (much like applyMultiVarPhaseFuncOverrides()).

Author
Tyson Jones Modifies outFn to be a filename of format prefix_NUM.txt where NUM is a new unique integer so far. This is useful for getting unique filenames for independent test cases of functions requiring reading/writing to file, to avoid IO locks (especially common in distributed mode).
Tyson Jones

Definition at line 1526 of file test_utilities.cpp.

1526 {
1527 snprintf(outFn, maxlen, "%s_%d.txt", prefix, fn_unique_suffix_id++);
1528}

◆ sublists() [1/4]

CatchGen< int * > sublists ( CatchGen< int > && gen,
int numSamps,
const int * exclude,
int numExclude )

Returns a Catch2 generator of every length-sublen sublist of the elements generated by gen, which exclude all elements in exclude, in increasing lexographic order. This generates every fixed-length combination of gen's elements the nominated exclusions, and every permutation of each.

There is on need for the elements of exclude to actually appear in those of gen. sublen must less than or equal to the number of elements in gen, after the nominated exclusions.

Note that the sublist must not be modified, else further generation may break (QuEST's internal functions will indeed modify but restore the qubit index lists given to them, which is ok). Assumes list contains no duplicates, otherwise the generated sublists may be duplicated.

This function can be used like

int sublen = 2;
int exclude[2] = {3,4};
int* sublist = GENERATE_COPY( sublists(range(1,6), sublen, exclude, 2) );

to generate {1,2}, {1,5}, {2,1}, {2,5}, {5,1}, {5,2}

Author
Tyson Jones

◆ sublists() [2/4]

CatchGen< int * > sublists ( CatchGen< int > && gen,
int numSamps,
int excluded )

Returns a Catch2 generator of every length-sublen sublist of the elements generated by gen which exclude element excluded, in increasing lexographic order. This generates every fixed-length combination of gen's elements the nominated exclusions, and every permutation of each.

sublen must less than or equal to the number of elements in gen, after the nominated exclusion. There is no need for excluded to actually appear in the elements of gen.

Note that the sublist must not be modified, else further generation may break (QuEST's internal functions will indeed modify but restore the qubit index lists given to them, which is ok). Assumes list contains no duplicates, otherwise the generated sublists may be duplicated.

This function can be used like

int sublen = 2;
int excluded = 1;
int* sublist = GENERATE_COPY( sublists(range(1,4), sublen, excluded) );

to generate {2,3}, {3,2}.

Author
Tyson Jones

◆ sublists() [3/4]

CatchGen< int * > sublists ( CatchGen< int > && gen,
int sublen )

Returns a Catch2 generator of every length-sublen sublist of the elements generated by gen, in increasing lexographic order. This generates every fixed-length combination of gen's elements, and every permutation of each. Note that the produced sublist must not be modified, else further generation may break (QuEST's internal functions will indeed modify but restore the qubit index lists given to them, which is ok). Assumes list contains no duplicates, otherwise the generated sublists may be duplicated.

This function can be used like

int sublen = 2;
int* sublist = GENERATE_COPY( sublists(list, 4, sublen) );

to generate {1,2}, {1,3}, {1,4}, {2,1}, {2,3}, {2,4}, {3,1}, {3,2}, {3, 4}, {4,1}, {4,2}, {4, 3}.

Author
Tyson Jones

◆ sublists() [4/4]

CatchGen< int * > sublists ( int * list,
int len,
int sublen )

Returns a Catch2 generator of every length-sublen sublist of length-len list, in increasing lexographic order. This generates every fixed-length combination of the given list and every permutation of each. & If the sublist length is the full list length, this generator produces every permutation correctly. Note that the sublist must not be modified, else further & generation may break (QuEST's internal functions will indeed modify but restore the qubit index lists given to them, which is ok). Assumes list contains no duplicates, otherwise the generated sublists may be duplicated.

This function can be used like

int list[4] = {1,2,3,4};
int sublen = 2;
int* sublist = GENERATE_COPY( sublists(list, 4, sublen) );

to generate {1,2}, {1,3}, {1,4}, {2,1}, {2,3}, {2,4}, {3,1}, {3,2}, {3, 4}, {4,1}, {4,2}, {4, 3}.

Author
Tyson Jones

Definition at line 1657 of file test_utilities.cpp.

1659 {
1660 return Catch::Generators::GeneratorWrapper<int*>(
1661 Catch::Detail::make_unique<SubListGenerator>(list, len, sublen));
1662}

◆ toComplexMatrix2()

ComplexMatrix2 toComplexMatrix2 ( QMatrix qm)

Returns a ComplexMatrix2 copy of QMatix qm. Demands that qm is a 2-by-2 matrix.

Author
Tyson Jones

Definition at line 1177 of file test_utilities.cpp.

1177 {
1178 DEMAND( qm.size() == 2 );
1179 ComplexMatrix2 cm;
1180 macro_copyQMatrixToDeprecatedComplexMatrix(cm, qm);
1181 return cm;
1182}

Referenced by TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ toComplexMatrix4()

ComplexMatrix4 toComplexMatrix4 ( QMatrix qm)

Returns a ComplexMatrix4 copy of QMatix qm. Demands that qm is a 4-by-4 matrix.

Author
Tyson Jones

Definition at line 1183 of file test_utilities.cpp.

1183 {
1184 DEMAND( qm.size() == 4 );
1185 ComplexMatrix4 cm;
1186 macro_copyQMatrixToDeprecatedComplexMatrix(cm, qm);
1187 return cm;
1188}

Referenced by TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ toComplexMatrixN()

void toComplexMatrixN ( QMatrix qm,
ComplexMatrixN cm )

Populates the ComplexMatrixN with the contents of a QMatrix. In GPU-mode, this will then sync the elements ot the matrix's persistent GPU memory

Author
Tyson Jones

Definition at line 1196 of file test_utilities.cpp.

1196 {
1197 DEMAND( qm.size() == (1u<<cm.numQubits) );
1198 macro_copyComplexMatrix(cm.cpuElems, qm, qm.size());
1199 syncCompMatr(cm);
1200}
void syncCompMatr(CompMatr matr)
Definition matrices.cpp:377

Referenced by TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ toDiagonalQMatrix()

QMatrix toDiagonalQMatrix ( QVector vec)

Returns a diagonal complex matrix formed by the given vector

Author
Tyson Jones

Definition at line 1477 of file test_utilities.cpp.

1477 {
1478 QMatrix mat = getZeroMatrix(vec.size());
1479 for (size_t i=0; i<vec.size(); i++)
1480 mat[i][i] = vec[i];
1481 return mat;
1482}

◆ toQMatrix() [1/9]

QMatrix toQMatrix ( CompMatr src)

Returns a copy of the given matrix

Author
Tyson Jones

Definition at line 1212 of file test_utilities.cpp.

1212 {
1213 QMatrix dest = getZeroMatrix(1 << src.numQubits);
1214 macro_copyComplexMatrix(dest, src.cpuElems, dest.size());
1215 return dest;
1216}

◆ toQMatrix() [2/9]

QMatrix toQMatrix ( CompMatr1 src)

Returns a copy of the given 2-by-2 matrix.

Author
Tyson Jones

Definition at line 1202 of file test_utilities.cpp.

1202 {
1203 QMatrix dest = getZeroMatrix(2);
1204 macro_copyComplexMatrix(dest, src.elems, dest.size());
1205 return dest;
1206}

Referenced by TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ toQMatrix() [3/9]

QMatrix toQMatrix ( CompMatr2 src)

Returns a copy of the given 4-by-4 matrix.

Author
Tyson Jones

Definition at line 1207 of file test_utilities.cpp.

1207 {
1208 QMatrix dest = getZeroMatrix(4);
1209 macro_copyComplexMatrix(dest, src.elems, dest.size());
1210 return dest;
1211}

◆ toQMatrix() [4/9]

QMatrix toQMatrix ( DiagMatr matr)

Returns a dense matrix equivalent to the given diagonal

Author
Tyson Jones

Definition at line 1323 of file test_utilities.cpp.

1323 {
1324 QMatrix mat = getZeroMatrix(in.numElems);
1325 for (size_t i=0; i<mat.size(); i++)
1326 mat[i][i] = in.cpuElems[i];
1327 return mat;
1328}

◆ toQMatrix() [5/9]

QMatrix toQMatrix ( FullStateDiagMatr matr)

Returns a dense matrix equivalent to the given diagonal

Author
Tyson Jones

Definition at line 1315 of file test_utilities.cpp.

1315 {
1316 QVector vec = toQVector(in);
1317 QMatrix mat = getZeroMatrix(in.numElems);
1318 for (size_t i=0; i<mat.size(); i++)
1319 mat[i][i] = vec[i];
1320 return mat;
1321}
QVector toQVector(Qureg qureg)

◆ toQMatrix() [6/9]

QMatrix toQMatrix ( PauliHamil hamil)

Returns a 2^N-by-2^N Hermitian matrix form of the PauliHamil

Author
Tyson Jones

◆ toQMatrix() [7/9]

QMatrix toQMatrix ( PauliStrSum sum)

Returns a 2^N-by-2^N Hermitian Z-basis matrix of the given complex-weighted sum of Pauli strings, where N is the number of non-Identity operators.

Author
Tyson Jones

◆ toQMatrix() [8/9]

QMatrix toQMatrix ( qreal * coeffs,
pauliOpType * paulis,
int numQubits,
int numTerms )

Returns a 2^N-by-2^N Hermitian matrix form of the specified weighted sum of Pauli products

Author
Tyson Jones

Definition at line 1419 of file test_utilities.cpp.

1419 {
1420
1421 // produce a numTargs-big matrix 'pauliSum' by pauli-matrix tensoring and summing
1422 QMatrix iMatr{{1,0},{0,1}};
1423 QMatrix xMatr{{0,1},{1,0}};
1424 QMatrix yMatr{{0,-qcomp(0,1)},{qcomp(0,1),0}};
1425 QMatrix zMatr{{1,0},{0,-1}};
1426 QMatrix pauliSum = getZeroMatrix(1<<numQubits);
1427
1428 for (int t=0; t<numTerms; t++) {
1429 QMatrix pauliProd = QMatrix{{1}};
1430
1431 for (int q=0; q<numQubits; q++) {
1432 int i = q + t*numQubits;
1433
1434 QMatrix fac;
1435 pauliOpType code = paulis[i];
1436 if (code == PAULI_I) fac = iMatr;
1437 if (code == PAULI_X) fac = xMatr;
1438 if (code == PAULI_Y) fac = yMatr;
1439 if (code == PAULI_Z) fac = zMatr;
1440 pauliProd = getKroneckerProduct(fac, pauliProd);
1441 }
1442 pauliSum += coeffs[t] * pauliProd;
1443 }
1444
1445 // a now 2^numQubits by 2^numQubits Hermitian matrix
1446 return pauliSum;
1447}

◆ toQMatrix() [9/9]

QMatrix toQMatrix ( Qureg qureg)

Returns an equal-size copy of the given density matrix qureg. In GPU mode, this function involves a copy of qureg from GPU memory to RAM. In distributed mode, this involves an all-to-all broadcast of qureg.

Author
Tyson Jones

Definition at line 1218 of file test_utilities.cpp.

1218 {
1219 DEMAND( qureg.isDensityMatrix );
1220#if COMPILE_MPI
1221 DEMAND( qureg.numAmps < MPI_MAX_AMPS_IN_MSG );
1222#endif
1223
1224 // ensure local qureg amps are up to date
1225 copyStateFromGPU(qureg);
1226 syncQuESTEnv();
1227
1228 // collect all amps between all nodes
1229 qcomp* allAmps = qureg.cpuAmps;
1230
1231 // in distributed mode, give every node the full state vector
1232#if COMPILE_MPI
1233 if (qureg.isDistributed) {
1234 allAmps = (qcomp*) malloc(qureg.numAmps * sizeof *allAmps);
1235 MPI_Allgather(
1236 qureg.cpuAmps, qureg.numAmpsPerNode, MPI_QCOMP,
1237 allAmps, qureg.numAmpsPerNode, MPI_QCOMP, MPI_COMM_WORLD);
1238 }
1239#endif
1240
1241 // copy full state vector into a QVector
1242 long long int dim = (1LL << qureg.numQubits);
1243 QMatrix matr = getZeroMatrix(dim);
1244 for (long long int n=0; n<qureg.numAmps; n++)
1245 matr[n%dim][n/dim] = allAmps[n];
1246
1247 // clean up if we malloc'd the distributed array
1248 if (qureg.isDistributed)
1249 free(allAmps);
1250 return matr;
1251}

◆ toQureg() [1/2]

void toQureg ( Qureg qureg,
QMatrix mat )

Initialises the density matrix qureg to have the same amplitudes as mat. Demands qureg is a density matrix of equal dimensions to mat. In GPU mode, this function involves a copy from RAM to GPU memory. This function has no communication cost in distributed mode.

Author
Tyson Jones

Definition at line 1342 of file test_utilities.cpp.

1342 {
1343 DEMAND( qureg.isDensityMatrix );
1344 DEMAND( (1LL << qureg.numQubits) == (long long int) mat.size() );
1345
1346 syncQuESTEnv();
1347
1348 int len = (1 << qureg.numQubits);
1349 for (int i=0; i<qureg.numAmpsPerNode; i++) {
1350 int ind = qureg.rank*qureg.numAmpsPerNode + i;
1351 qureg.cpuAmps[i] = mat[ind%len][ind/len];
1352 }
1353 copyStateToGPU(qureg);
1354}

◆ toQureg() [2/2]

void toQureg ( Qureg qureg,
QVector vec )

Initialises the state-vector qureg to have the same amplitudes as vec. Demands qureg is a state-vector of an equal size to vec. In GPU mode, this function involves a copy from RAM to GPU memory. This function has no communication cost in distributed mode.

Author
Tyson Jones

Definition at line 1330 of file test_utilities.cpp.

1330 {
1331 DEMAND( !qureg.isDensityMatrix );
1332 DEMAND( qureg.numAmps == (long long int) vec.size() );
1333
1334 syncQuESTEnv();
1335
1336 for (int i=0; i<qureg.numAmpsPerNode; i++) {
1337 int ind = qureg.rank*qureg.numAmpsPerNode + i;
1338 qureg.cpuAmps[i] = vec[ind];
1339 }
1340 copyStateToGPU(qureg);
1341}

Referenced by TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and TEST_CASE().

◆ toQVector() [1/3]

QVector toQVector ( DiagMatr op)

Returns a vector with the given diagonal's elements. In distributed mode, this involves an all-to-all broadcast of op.

Author
Tyson Jones

Definition at line 1288 of file test_utilities.cpp.

1288 {
1289
1290 return vector<qcomp>(matr.cpuElems, matr.cpuElems + matr.numElems);
1291}

◆ toQVector() [2/3]

QVector toQVector ( FullStateDiagMatr op)

Returns a vector with the given diagonal's elements. In distributed mode, this involves an all-to-all broadcast of op.

Author
Tyson Jones

Definition at line 1293 of file test_utilities.cpp.

1293 {
1294
1295#if COMPILE_MPI
1296 DEMAND( matr.numElems < MPI_MAX_AMPS_IN_MSG );
1297#endif
1298
1299 vector<qcomp> vec(matr.numElems);
1300
1301 // in distributed mode, give every node the full diagonal operator
1302 if (matr.isDistributed) {
1303 #if COMPILE_MPI
1304 MPI_Allgather(
1305 matr.cpuElems, matr.numElemsPerNode, MPI_QCOMP,
1306 vec.data(), matr.numElemsPerNode, MPI_QCOMP, MPI_COMM_WORLD);
1307 #endif
1308 } else {
1309 vec.assign(matr.cpuElems, matr.cpuElems + matr.numElems);
1310 }
1311
1312 return vec;
1313}

◆ toQVector() [3/3]

QVector toQVector ( Qureg qureg)

Returns an equal-size copy of the given state-vector qureg. In GPU mode, this function involves a copy of qureg from GPU memory to RAM. In distributed mode, this involves an all-to-all broadcast of qureg.

Author
Tyson Jones

Definition at line 1253 of file test_utilities.cpp.

1253 {
1254 DEMAND( !qureg.isDensityMatrix );
1255#if COMPILE_MPI
1256 DEMAND( qureg.numAmps < MPI_MAX_AMPS_IN_MSG );
1257#endif
1258
1259 // ensure local qureg amps are up to date
1260 copyStateFromGPU(qureg);
1261 syncQuESTEnv();
1262
1263 qcomp* allAmps = qureg.cpuAmps;
1264
1265 // in distributed mode, give every node the full state vector
1266#if COMPILE_MPI
1267 if (qureg.isDistributed) {
1268 allAmps = (qcomp*) malloc(qureg.numAmps * sizeof *allAmps);
1269
1270 MPI_Allgather(
1271 qureg.cpuAmps, qureg.numAmpsPerNode, MPI_QCOMP,
1272 allAmps, qureg.numAmpsPerNode, MPI_QCOMP, MPI_COMM_WORLD);
1273 }
1274#endif
1275
1276 // copy full state vector into a QVector
1277 QVector vec = QVector(qureg.numAmps);
1278 for (long long int i=0; i<qureg.numAmps; i++)
1279 vec[i] = allAmps[i];
1280
1281 // clean up if we malloc'd distrib array
1282 if (qureg.isDistributed)
1283 free(allAmps);
1284
1285 return vec;
1286}

Referenced by TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), TEST_CASE(), and toQMatrix().

◆ writeToFileSynch()

void writeToFileSynch ( char * fn,
const string & contents )

Writes contents to the file with filename fn, which is created and/or overwritten. In distributed mode, the master node writes while the other nodes wait until complete.

Author
Tyson Jones

Definition at line 1530 of file test_utilities.cpp.

1530 {
1531
1532 // master node writes
1533 if (getQuESTEnv().rank == 0) {
1534 FILE* file = fopen(fn, "w");
1535 fputs(contents.c_str(), file);
1536 fclose(file);
1537 }
1538
1539 // other nodes wait
1540 syncQuESTEnv();
1541}