Operators

Non-physical operators which may be non-unitary, non-norm-preserving, even non-Hermitian. More...

Functions

void applyPauliSum (Qureg inQureg, enum pauliOpType *allPauliCodes, qreal *termCoeffs, int numSumTerms, Qureg outQureg)
 Modifies outQureg to be the result of applying the weighted sum of Pauli products (a Hermitian but not necessarily unitary operator) to inQureg. More...
 

Detailed Description

Non-physical operators which may be non-unitary, non-norm-preserving, even non-Hermitian.

Function Documentation

◆ applyPauliSum()

void applyPauliSum ( Qureg  inQureg,
enum pauliOpType allPauliCodes,
qreal termCoeffs,
int  numSumTerms,
Qureg  outQureg 
)

Modifies outQureg to be the result of applying the weighted sum of Pauli products (a Hermitian but not necessarily unitary operator) to inQureg.

Note that afterward, outQureg may no longer be normalised and ergo not a statevector or density matrix. Users must therefore be careful passing outQureg to other QuEST functions which assume normalisation in order to function correctly.

Letting $ \alpha = \sum_i c_i \otimes_j^{N} \hat{\sigma}_{i,j} $ be the operators indicated by allPauliCodes (where $ c_i \in $ termCoeffs and $ N = $ qureg.numQubitsRepresented), this function effects $ \alpha | \psi \rangle $ on statevector $ |\psi\rangle $ and $\alpha \rho$ (left matrix multiplication) on density matrix $ \rho $.

allPauliCodes is an array of length numSumTerms*qureg.numQubitsRepresented which specifies which Pauli operators to apply, where 0 = PAULI_I, 1 = PAULI_X, 2 = PAULI_Y, 3 = PAULI_Z. For each sum term, a Pauli operator must be specified for EVERY qubit in qureg; each set of numSumTerms operators will be grouped into a product. termCoeffs is an arrray of length numSumTerms containing the term coefficients. For example, on a 3-qubit statevector,

int paulis[6] = {PAULI_X, PAULI_I, PAULI_I,  PAULI_X, PAULI_Y, PAULI_Z};
qreal coeffs[2] = {1.5, -3.6};
applyPauliSum(inQureg, paulis, coeffs, 2, outQureg);

will apply Hermitian operation $ (1.5 X I I - 3.6 X Y Z) $ (where in this notation, the left-most operator applies to the least-significant qubit, i.e. that with index 0).

In theory, inQureg is unchanged though its state is temporarily modified and is reverted by re-applying Paulis (XX=YY=ZZ=I), so may see a change by small numerical errors. The initial state in outQureg is not used.

inQureg and outQureg must both be state-vectors, or both density matrices, of equal dimensions. inQureg cannot be outQureg.

This function works by applying each Pauli product to inQureg in turn, and adding the resulting state (weighted by a coefficient in termCoeffs) to the initially-blanked outQureg. Ergo it should scale with the total number of Pauli operators specified (excluding identities), and the qureg dimension.

Parameters
[in]inQuregthe register containing the state which outQureg will be set to, under the action of the Hermitiain operator specified by the Pauli codes. inQureg should be unchanged, though may vary slightly due to numerical error.
[in]allPauliCodesa list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z) of all Paulis involved in the products of terms. A Pauli must be specified for each qubit in the register, in every term of the sum.
[in]termCoeffsThe coefficients of each term in the sum of Pauli products
[in]numSumTermsThe total number of Pauli products specified
[out]outQuregthe qureg to modify to be the result of applyling the weighted Pauli sum operator to the state in inQureg
Exceptions
exitWithErrorif any code in allPauliCodes is not in {0,1,2,3}, or if numSumTerms <= 0, or if inQureg is not of the same type and dimensions as outQureg
Author
Tyson Jones

Definition at line 806 of file QuEST.c.

806  {
807  validateMatchingQuregTypes(inQureg, outQureg, __func__);
808  validateMatchingQuregDims(inQureg, outQureg, __func__);
809  validateNumPauliSumTerms(numSumTerms, __func__);
810  validatePauliCodes(allPauliCodes, numSumTerms*inQureg.numQubitsRepresented, __func__);
811 
812  statevec_applyPauliSum(inQureg, allPauliCodes, termCoeffs, numSumTerms, outQureg);
813 
814  qasm_recordComment(outQureg, "Here, the register was modified to an undisclosed and possibly unphysical state (applyPauliSum).");
815 }

References Qureg::numQubitsRepresented, qasm_recordComment(), statevec_applyPauliSum(), validateMatchingQuregDims(), validateMatchingQuregTypes(), validateNumPauliSumTerms(), and validatePauliCodes().

Referenced by TEST_CASE().

void validateNumPauliSumTerms(int numTerms, const char *caller)
void validateMatchingQuregDims(Qureg qureg1, Qureg qureg2, const char *caller)
void qasm_recordComment(Qureg qureg, char *comment,...)
Definition: QuEST_qasm.c:120
void statevec_applyPauliSum(Qureg inQureg, enum pauliOpType *allCodes, qreal *termCoeffs, int numSumTerms, Qureg outQureg)
Definition: QuEST_common.c:493
void validateMatchingQuregTypes(Qureg qureg1, Qureg qureg2, const char *caller)
int numQubitsRepresented
The number of qubits represented in either the state-vector or density matrix.
Definition: QuEST.h:165
void validatePauliCodes(enum pauliOpType *pauliCodes, int numPauliCodes, const char *caller)