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 ![]() 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 op
was not created, or ifop
acts on a different number of qubits thanqureg
represents
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 u
upon[in] u matrix to apply
- Exceptions
-
invalidQuESTInputError if targetQubit
is 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 targetQubit1
ortargetQubit2
are outside [0,qureg.numQubitsRepresented
), or iftargetQubit1
equalstargetQubit2
, 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 targs
is outside of [0,qureg.numQubitsRepresented
), or iftargs
are not unique, or ifu
is 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 ctrls
andtargs
is outside of [0,qureg.numQubitsRepresented
), or ifctrls
andtargs
are not unique, or if matrixu
is 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 outQureg
will be set to, under the action ofhamil
.inQureg
should 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 hamil
to the state ininQureg
- Exceptions
-
invalidQuESTInputError if any code in hamil.pauliCodes
is not a valid Pauli code, or ifnumSumTerms
<= 0, or ifinQureg
is not of the same type and dimensions asoutQureg
andhamil
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 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] 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 allPauliCodes
is not in {0,1,2,3}, or if numSumTerms <= 0, or ifinQureg
is 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
, orhamil
contains invalid parameters or Pauli codes, or iforder
is 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().