Non-physical operators which may be non-unitary, non-norm-preserving, even non-Hermitian. More...
Functions | |
| void | applyDiagonalOp (Qureg qureg, DiagonalOp op) |
Apply a diagonal complex operator, which is possibly non-unitary and non-Hermitian, on the entire qureg, More... | |
| void | applyMatrix2 (Qureg qureg, int targetQubit, ComplexMatrix2 u) |
| Apply a general 2-by-2 matrix, which may be non-unitary. More... | |
| void | applyMatrix4 (Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u) |
| Apply a general 4-by-4 matrix, which may be non-unitary. More... | |
| void | applyMatrixN (Qureg qureg, int *targs, int numTargs, ComplexMatrixN u) |
| Apply a general N-by-N matrix, which may be non-unitary, on any number of target qubits. More... | |
| void | applyMultiControlledMatrixN (Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs, ComplexMatrixN u) |
| Apply a general N-by-N matrix, which may be non-unitary, with additional controlled qubits. More... | |
| void | applyPauliHamil (Qureg inQureg, PauliHamil hamil, Qureg outQureg) |
Modifies outQureg to be the result of applying PauliHamil (a Hermitian but not necessarily unitary operator) to inQureg. More... | |
| 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... | |
| void | applyTrotterCircuit (Qureg qureg, PauliHamil hamil, qreal time, int order, int reps) |
Applies a trotterisation of unitary evolution to qureg. More... | |
Detailed Description
Non-physical operators which may be non-unitary, non-norm-preserving, even non-Hermitian.
Function Documentation
◆ applyDiagonalOp()
| void applyDiagonalOp | ( | Qureg | qureg, |
| DiagonalOp | op | ||
| ) |
Apply a diagonal complex operator, which is possibly non-unitary and non-Hermitian, on the entire qureg,
- Parameters
-
[in,out] qureg the state to operate the diagonal operator upon [in] op the diagonal operator to apply
- Exceptions
-
invalidQuESTInputError if opwas not created, or ifopacts on a different number of qubits thanquregrepresents
Definition at line 887 of file QuEST.c.
References densmatr_applyDiagonalOp(), Qureg::isDensityMatrix, qasm_recordComment(), statevec_applyDiagonalOp(), and validateDiagonalOp().
Referenced by TEST_CASE().
◆ applyMatrix2()
| void applyMatrix2 | ( | Qureg | qureg, |
| int | targetQubit, | ||
| ComplexMatrix2 | u | ||
| ) |
Apply a general 2-by-2 matrix, which may be non-unitary.
The matrix is left-multiplied onto the state, for both state-vectors and density matrices. Hence, this function differs from unitary() by more than just permitting a non-unitary matrix.
This function may leave qureg is an unnormalised state.
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate uupon[in] u matrix to apply
- Exceptions
-
invalidQuESTInputError if targetQubitis outside [0,qureg.numQubitsRepresented).
Definition at line 844 of file QuEST.c.
References qasm_recordComment(), statevec_unitary(), and validateTarget().
Referenced by TEST_CASE().
◆ applyMatrix4()
| void applyMatrix4 | ( | Qureg | qureg, |
| int | targetQubit1, | ||
| int | targetQubit2, | ||
| ComplexMatrix4 | u | ||
| ) |
Apply a general 4-by-4 matrix, which may be non-unitary.
The matrix is left-multiplied onto the state, for both state-vectors and density matrices. Hence, this function differs from twoQubitUnitary() by more than just permitting a non-unitary matrix.
targetQubit1 is treated as the least significant qubit in u, such that a row in u is dotted with the vector 
For example,
applyMatrix4(qureg, a, b, u);
will invoke multiplication
This function may leave qureg is an unnormalised state.
Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes. This means an q-qubit register (state vector or density matrix) can be distributed by at most 2^q/4 nodes.
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit1 first qubit to operate on, treated as least significant in u[in] targetQubit2 second qubit to operate on, treated as most significant in u[in] u matrix to apply
- Exceptions
-
invalidQuESTInputError if targetQubit1ortargetQubit2are outside [0,qureg.numQubitsRepresented), or iftargetQubit1equalstargetQubit2, or if each node cannot fit 4 amplitudes in distributed mode.
Definition at line 853 of file QuEST.c.
References qasm_recordComment(), statevec_twoQubitUnitary(), validateMultiQubitMatrixFitsInNode(), and validateMultiTargets().
Referenced by TEST_CASE().
◆ applyMatrixN()
| void applyMatrixN | ( | Qureg | qureg, |
| int * | targs, | ||
| int | numTargs, | ||
| ComplexMatrixN | u | ||
| ) |
Apply a general N-by-N matrix, which may be non-unitary, on any number of target qubits.
The matrix is left-multiplied onto the state, for both state-vectors and density matrices. Hence, this function differs from multiQubitUnitary() by more than just permitting a non-unitary matrix.
The first target qubit in targs is treated as least significant in u. For example,
applyMatrixN(qureg, (int []) {a, b, c}, 3, u);
will invoke multiplication
This function may leave qureg is an unnormalised state.
The passed ComplexMatrix must be a compatible size with the specified number of target qubits, otherwise an error is thrown.
Note that in multithreaded mode, each thread will clone 2^numTargs amplitudes, and store these in the runtime stack. Using t threads, the total memory overhead of this function is t*2^numTargs. For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault (e.g. on a 1 MiB stack).
Note too that in distributed mode, this routine requires that each node contains at least 2^numTargs amplitudes in the register. This means an q-qubit register (state vector or density matrix) can be distributed by at most 2^q / 2^numTargs nodes.
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targs a list of the target qubits, ordered least significant to most in u[in] numTargs the number of target qubits [in] u matrix to apply
- Exceptions
-
invalidQuESTInputError if any index in targsis outside of [0,qureg.numQubitsRepresented), or iftargsare not unique, or ifuis not of a compatible size withnumTargs, or if a node cannot fit the required number of target amplitudes in distributed mode.
Definition at line 863 of file QuEST.c.
References qasm_recordComment(), statevec_multiQubitUnitary(), validateMultiQubitMatrix(), and validateMultiTargets().
Referenced by TEST_CASE().
◆ applyMultiControlledMatrixN()
| void applyMultiControlledMatrixN | ( | Qureg | qureg, |
| int * | ctrls, | ||
| int | numCtrls, | ||
| int * | targs, | ||
| int | numTargs, | ||
| ComplexMatrixN | u | ||
| ) |
Apply a general N-by-N matrix, which may be non-unitary, with additional controlled qubits.
The matrix is left-multiplied onto the state, for both state-vectors and density matrices. Hence, this function differs from multiControlledMultiQubitUnitary() by more than just permitting a non-unitary matrix.
This function may leave qureg is an unnormalised state.
Any number of control and target qubits can be specified. This effects the many-qubit matrix
on the control and target qubits.
The target qubits in targs are treated as ordered least significant to most significant in u.
The passed ComplexMatrix must be a compatible size with the specified number of target qubits, otherwise an error is thrown.
Note that in multithreaded mode, each thread will clone 2^numTargs amplitudes, and store these in the runtime stack. Using t threads, the total memory overhead of this function is t*2^numTargs. For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault (e.g. on a 1 MiB stack).
Note that in distributed mode, this routine requires that each node contains at least 2^numTargs amplitudes. This means an q-qubit register (state vector or density matrix) can be distributed by at most 2^q / 2^numTargs nodes.
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] ctrls a list of the control qubits [in] numCtrls the number of control qubits [in] targs a list of the target qubits, ordered least to most significant [in] numTargs the number of target qubits [in] u matrix to apply
- Exceptions
-
invalidQuESTInputError if any index in ctrlsandtargsis outside of [0,qureg.numQubitsRepresented), or ifctrlsandtargsare not unique, or if matrixuis not a compatible size withnumTargs, or if a node cannot fit the required number of target amplitudes in distributed mode.
Definition at line 874 of file QuEST.c.
References getQubitBitMask(), qasm_recordComment(), statevec_multiControlledMultiQubitUnitary(), validateMultiControlsMultiTargets(), and validateMultiQubitMatrix().
Referenced by TEST_CASE().
◆ applyPauliHamil()
| void applyPauliHamil | ( | Qureg | inQureg, |
| PauliHamil | hamil, | ||
| Qureg | outQureg | ||
| ) |
Modifies outQureg to be the result of applying PauliHamil (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.
This is merely an encapsulation of applyPauliSum(), which can refer to for elaborated doc.
Letting hamil be expressed as
(where
hamil.termCoeffs and
hamil.numQubits), this function effects
on statevector
and
(left matrix multiplication) on density matrix
.
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 to hamil. inQureg cannot be outQureg.
This function works by applying each Pauli product in hamil 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] inQureg the register containing the state which outQuregwill be set to, under the action ofhamil.inQuregshould be unchanged, though may vary slightly due to numerical error.[in] hamil a weighted sum of products of pauli operators [out] outQureg the qureg to modify to be the result of applyling hamilto the state ininQureg
- Exceptions
-
invalidQuESTInputError if any code in hamil.pauliCodesis not a valid Pauli code, or ifnumSumTerms<= 0, or ifinQuregis not of the same type and dimensions asoutQuregandhamil
Definition at line 819 of file QuEST.c.
References PauliHamil::numSumTerms, PauliHamil::pauliCodes, qasm_recordComment(), statevec_applyPauliSum(), PauliHamil::termCoeffs, validateMatchingQuregDims(), validateMatchingQuregPauliHamilDims(), validateMatchingQuregTypes(), and validatePauliHamil().
Referenced by TEST_CASE().
◆ 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
be the operators indicated by allPauliCodes (where
termCoeffs and
qureg.numQubitsRepresented), this function effects
on statevector
and
(left matrix multiplication) on density matrix
.
allPauliCodes is an array of length numSumTerms* specifies which Pauli operators to apply, where 0 = qureg.numQubitsRepresented whichPAULI_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
(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] inQureg the register containing the state which outQuregwill be set to, under the action of the Hermitiain operator specified by the Pauli codes.inQuregshould be unchanged, though may vary slightly due to numerical error.[in] allPauliCodes a 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] termCoeffs The coefficients of each term in the sum of Pauli products [in] numSumTerms The total number of Pauli products specified [out] outQureg the qureg to modify to be the result of applyling the weighted Pauli sum operator to the state in inQureg
- Exceptions
-
invalidQuESTInputError if any code in allPauliCodesis not in {0,1,2,3}, or if numSumTerms <= 0, or ifinQuregis not of the same type and dimensions asoutQureg
Definition at line 808 of file QuEST.c.
References Qureg::numQubitsRepresented, qasm_recordComment(), statevec_applyPauliSum(), validateMatchingQuregDims(), validateMatchingQuregTypes(), validateNumPauliSumTerms(), and validatePauliCodes().
Referenced by TEST_CASE().
◆ applyTrotterCircuit()
| void applyTrotterCircuit | ( | Qureg | qureg, |
| PauliHamil | hamil, | ||
| qreal | time, | ||
| int | order, | ||
| int | reps | ||
| ) |
Applies a trotterisation of unitary evolution
to qureg.
This is a sequence of unitary operators, effected by multiRotatePauli(), which together approximate the action of full unitary-time evolution under the given Hamiltonian.
Notate
where
is a real coefficient in hamil,
is the corresponding product of Pauli operators, of which there are a total
. Then, order=1 performs first-order Trotterisation, whereby
order=2 performs the lowest order "symmetrized" Suzuki decomposition, whereby
Greater even values of order specify higher-order symmetrized decompositions
which satisfy
and
where
.
These formulations are taken from 'Finding Exponential Product Formulas of Higher Orders', Naomichi Hatano and Masuo Suzuki (2005) (arXiv).
Note that the applied Trotter circuit is captured by QASM, if QASM logging is enabled on qureg.
- Parameters
-
[in,out] qureg the register to modify under the approximate unitary-time evolution [in] hamil the hamiltonian under which to approxiamte unitary-time evolution [in] time the target evolution time, which is permitted to be both positive and negative. [in] order the order of Trotter-Suzuki decomposition to use. Higher orders (necessarily even) are more accurate but prescribe an exponentially increasing number of gates. [in] reps the number of repetitions of the decomposition of the given order. This improves the accuracy but prescribes a linearly increasing number of gates.
- Exceptions
-
invalidQuESTInputError if qureg.numQubitsRepresented!=hamil.numQubits, orhamilcontains invalid parameters or Pauli codes, or iforderis not in {1, 2, 4, 6, ...} or ifreps<= 0.
Definition at line 830 of file QuEST.c.
References agnostic_applyTrotterCircuit(), qasm_recordComment(), validateMatchingQuregPauliHamilDims(), validatePauliHamil(), and validateTrotterParams().
Referenced by TEST_CASE().