Unitary gates. More...
Functions | |
void | applyMultiControlledGateMatrixN (Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs, ComplexMatrixN m) |
Apply a general multi-controlled multi-qubit gate specified as an (possibly non-unitary) arbitrary complex matrix. More... | |
void | compactUnitary (Qureg qureg, int targetQubit, Complex alpha, Complex beta) |
Apply a single-qubit unitary parameterised by two given complex scalars. More... | |
void | controlledCompactUnitary (Qureg qureg, int controlQubit, int targetQubit, Complex alpha, Complex beta) |
Apply a controlled unitary (single control, single target) parameterised by two given complex scalars. More... | |
void | controlledMultiQubitUnitary (Qureg qureg, int ctrl, int *targs, int numTargs, ComplexMatrixN u) |
Apply a general controlled multi-qubit unitary (including a global phase factor). More... | |
void | controlledNot (Qureg qureg, int controlQubit, int targetQubit) |
Apply the controlled not (single control, single target) gate, also known as the c-X, c-sigma-X, c-Pauli-X and c-bit-flip gate. More... | |
void | controlledPauliY (Qureg qureg, int controlQubit, int targetQubit) |
Apply the controlled pauliY (single control, single target) gate, also known as the c-Y and c-sigma-Y gate. More... | |
void | controlledPhaseFlip (Qureg qureg, int idQubit1, int idQubit2) |
Apply the (two-qubit) controlled phase flip gate, also known as the controlled pauliZ gate. More... | |
void | controlledPhaseShift (Qureg qureg, int idQubit1, int idQubit2, qreal angle) |
Introduce a phase factor \( \exp(i \theta) \) on state \( |11\rangle \) of qubits idQubit1 and idQubit2 . More... | |
void | controlledRotateAroundAxis (Qureg qureg, int controlQubit, int targetQubit, qreal angle, Vector axis) |
Applies a controlled rotation by a given angle around a given vector on the Bloch-sphere. More... | |
void | controlledRotateX (Qureg qureg, int controlQubit, int targetQubit, qreal angle) |
Applies a controlled rotation by a given angle around the X-axis of the Bloch-sphere. More... | |
void | controlledRotateY (Qureg qureg, int controlQubit, int targetQubit, qreal angle) |
Applies a controlled rotation by a given angle around the Y-axis of the Bloch-sphere. More... | |
void | controlledRotateZ (Qureg qureg, int controlQubit, int targetQubit, qreal angle) |
Applies a controlled rotation by a given angle around the Z-axis of the Bloch-sphere. More... | |
void | controlledTwoQubitUnitary (Qureg qureg, int controlQubit, int targetQubit1, int targetQubit2, ComplexMatrix4 u) |
Apply a general controlled two-qubit unitary (including a global phase factor). More... | |
void | controlledUnitary (Qureg qureg, int controlQubit, int targetQubit, ComplexMatrix2 u) |
Apply a general controlled unitary (single control, single target), which can include a global phase factor. More... | |
void | diagonalUnitary (Qureg qureg, int *targets, int numTargets, SubDiagonalOp op) |
Apply a many-qubit unitary specified as a diagonal matrix upon a specific set of qubits of a quantum register. More... | |
void | hadamard (Qureg qureg, int targetQubit) |
Apply the single-qubit Hadamard gate. More... | |
void | multiControlledMultiQubitNot (Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs) |
Apply a NOT (or Pauli X) gate with multiple control and target qubits. More... | |
void | multiControlledMultiQubitUnitary (Qureg qureg, int *ctrls, int numCtrls, int *targs, int numTargs, ComplexMatrixN u) |
Apply a general multi-controlled multi-qubit unitary (including a global phase factor). More... | |
void | multiControlledMultiRotatePauli (Qureg qureg, int *controlQubits, int numControls, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle) |
Apply a multi-controlled multi-target multi-Pauli rotation, also known as a controlled Pauli gadget. More... | |
void | multiControlledMultiRotateZ (Qureg qureg, int *controlQubits, int numControls, int *targetQubits, int numTargets, qreal angle) |
Apply a multi-controlled multi-target Z rotation, also known as a controlled phase gadget. More... | |
void | multiControlledPhaseFlip (Qureg qureg, int *controlQubits, int numControlQubits) |
Apply the multiple-qubit controlled phase flip gate, also known as the multiple-qubit controlled pauliZ gate. More... | |
void | multiControlledPhaseShift (Qureg qureg, int *controlQubits, int numControlQubits, qreal angle) |
Introduce a phase factor \( \exp(i \theta) \) on state \( |1 \dots 1 \rangle \) of the passed qubits. More... | |
void | multiControlledTwoQubitUnitary (Qureg qureg, int *controlQubits, int numControlQubits, int targetQubit1, int targetQubit2, ComplexMatrix4 u) |
Apply a general multi-controlled two-qubit unitary (including a global phase factor). More... | |
void | multiControlledUnitary (Qureg qureg, int *controlQubits, int numControlQubits, int targetQubit, ComplexMatrix2 u) |
Apply a general multiple-control single-target unitary, which can include a global phase factor. More... | |
void | multiQubitNot (Qureg qureg, int *targs, int numTargs) |
Apply a NOT (or Pauli X) gate with multiple target qubits, which has the same effect as (but is much faster than) applying each single-qubit NOT gate in turn. More... | |
void | multiQubitUnitary (Qureg qureg, int *targs, int numTargs, ComplexMatrixN u) |
Apply a general multi-qubit unitary (including a global phase factor) with any number of target qubits. More... | |
void | multiRotatePauli (Qureg qureg, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle) |
Apply a multi-qubit multi-Pauli rotation, also known as a Pauli gadget, on a selected number of qubits. More... | |
void | multiRotateZ (Qureg qureg, int *qubits, int numQubits, qreal angle) |
Apply a multi-qubit Z rotation, also known as a phase gadget, on a selected number of qubits. More... | |
void | multiStateControlledUnitary (Qureg qureg, int *controlQubits, int *controlState, int numControlQubits, int targetQubit, ComplexMatrix2 u) |
Apply a general single-qubit unitary with multiple control qubits, conditioned upon a specific bit sequence. More... | |
void | pauliX (Qureg qureg, int targetQubit) |
Apply the single-qubit Pauli-X (also known as the X, sigma-X, NOT or bit-flip) gate. More... | |
void | pauliY (Qureg qureg, int targetQubit) |
Apply the single-qubit Pauli-Y (also known as the Y or sigma-Y) gate. More... | |
void | pauliZ (Qureg qureg, int targetQubit) |
Apply the single-qubit Pauli-Z (also known as the Z, sigma-Z or phase-flip) gate. More... | |
void | phaseShift (Qureg qureg, int targetQubit, qreal angle) |
Shift the phase between \( |0\rangle \) and \( |1\rangle \) of a single qubit by a given angle. More... | |
void | rotateAroundAxis (Qureg qureg, int rotQubit, qreal angle, Vector axis) |
Rotate a single qubit by a given angle around a given Vector on the Bloch-sphere. More... | |
void | rotateX (Qureg qureg, int rotQubit, qreal angle) |
Rotate a single qubit by a given angle around the X-axis of the Bloch-sphere. More... | |
void | rotateY (Qureg qureg, int rotQubit, qreal angle) |
Rotate a single qubit by a given angle around the Y-axis of the Bloch-sphere. More... | |
void | rotateZ (Qureg qureg, int rotQubit, qreal angle) |
Rotate a single qubit by a given angle around the Z-axis of the Bloch-sphere (also known as a phase shift gate). More... | |
void | sGate (Qureg qureg, int targetQubit) |
Apply the single-qubit S gate. More... | |
void | sqrtSwapGate (Qureg qureg, int qb1, int qb2) |
Performs a sqrt SWAP gate between qubit1 and qubit2 . More... | |
void | swapGate (Qureg qureg, int qubit1, int qubit2) |
Performs a SWAP gate between qubit1 and qubit2 . More... | |
void | tGate (Qureg qureg, int targetQubit) |
Apply the single-qubit T gate. More... | |
void | twoQubitUnitary (Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u) |
Apply a general two-qubit unitary (including a global phase factor). More... | |
void | unitary (Qureg qureg, int targetQubit, ComplexMatrix2 u) |
Apply a general single-qubit unitary (including a global phase factor). More... | |
Detailed Description
Unitary gates.
Function Documentation
◆ applyMultiControlledGateMatrixN()
void applyMultiControlledGateMatrixN | ( | Qureg | qureg, |
int * | ctrls, | ||
int | numCtrls, | ||
int * | targs, | ||
int | numTargs, | ||
ComplexMatrixN | m | ||
) |
Apply a general multi-controlled multi-qubit gate specified as an (possibly non-unitary) arbitrary complex matrix.
This is equivalent to multiControlledMultiQubitUnitary() but does not check nor enforce unitary of the given matrix m
. This differs from applyMultiControlledMatrixN(), because the latter only left-applies the matrix upon density matrices.
Any number of control and target qubits can be specified. This effects the many-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & \ddots \\ & & & m_{00} & m_{01} & \dots \\ & & & m_{10} & m_{11} & \dots \\ & & & \vdots & \vdots & \ddots \end{pmatrix} \]
on the control and target qubits.
Besides unitarity, the inputs and their preconditions are the same as for multiControlledMultiQubitUnitary().
- 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] m arbitrary matrix to apply as if it were a unitary gate
- Exceptions
-
invalidQuESTInputError() - if any qubit in
ctrls
andtargs
is invalid, i.e. outside [0,qureg.numQubitsRepresented
) - if
ctrls
ortargs
contain any repetitions - if any qubit in
ctrls
is also intargs
(and vice versa) - if
numTargs
< 1 - if
numCtrls
< 1 (use multiQubitUnitary() for no controls) - if matrix
m
is not of a compatible size withnumTargs
- if a node cannot fit the required number of target amplitudes in distributed mode
segmentation-fault - if
ctrls
contains fewer elements thannumCtrls
- if
targs
contains fewer elements thannumTargs
- if any qubit in
Referenced by TEST_CASE().
◆ compactUnitary()
Apply a single-qubit unitary parameterised by two given complex scalars.
Given valid complex numbers \(\alpha\) and \(\beta\), applies the unitary
\[ U = \begin{pmatrix} \alpha & -\beta^* \\ \beta & \alpha^* \end{pmatrix} \]
which is general up to a global phase factor.
Valid \(\alpha\), \(\beta\) satisfy \(|\alpha|^2 + |\beta|^2 = 1\).
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate on [in] alpha complex unitary parameter (row 1, column 1) [in] beta complex unitary parameter (row 2, column 1)
- Exceptions
-
invalidQuESTInputError() - if
targetQubit
is outside [0,qureg.numQubitsRepresented
) - if
alpha
,beta
don't satisfy |alpha
|^2 + |beta
|^2 = 1
- if
Referenced by TEST_CASE().
◆ controlledCompactUnitary()
void controlledCompactUnitary | ( | Qureg | qureg, |
int | controlQubit, | ||
int | targetQubit, | ||
Complex | alpha, | ||
Complex | beta | ||
) |
Apply a controlled unitary (single control, single target) parameterised by two given complex scalars.
Given valid complex numbers \(\alpha\) and \(\beta\), applies the two-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\ & & \alpha & -\beta^* \\ & & \beta & \alpha^* \end{pmatrix} \]
to the control and target qubits. Valid \(\alpha\), \(\beta\) satisfy \(|\alpha|^2 + |\beta|^2 = 1\). The target unitary is general up to a global phase factor.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubit apply the target unitary if this qubit has value 1 [in] targetQubit qubit on which to apply the target unitary [in] alpha complex unitary parameter (row 1, column 1) [in] beta complex unitary parameter (row 2, column 1)
- Exceptions
-
invalidQuESTInputError() - if either
controlQubit
ortargetQubit
are outside [0,qureg.numQubitsRepresented
) - if
controlQubit
andtargetQubit
are equal - if
alpha
,beta
don't satisfy |alpha
|^2 + |beta
|^2 = 1
- if either
Referenced by TEST_CASE().
◆ controlledMultiQubitUnitary()
void controlledMultiQubitUnitary | ( | Qureg | qureg, |
int | ctrl, | ||
int * | targs, | ||
int | numTargs, | ||
ComplexMatrixN | u | ||
) |
Apply a general controlled multi-qubit unitary (including a global phase factor).
One control and any number of target qubits can be specified. This effects the many-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & 1 \\ & & & 1 \\ & & & & u_{00} & u_{01} & \dots \\ & & & & u_{10} & u_{11} & \dots \\ & & & & \vdots & \vdots & \ddots \end{pmatrix} \]
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 unitary and 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. 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] ctrl the control qubit [in] targs a list of the target qubits, ordered least to most significant [in] numTargs the number of target qubits [in] u unitary matrix to apply
- Exceptions
-
invalidQuESTInputError() - if
ctrl
or any index intargs
is outside of [0,qureg.numQubitsRepresented
) - if
targs
are not unique - if
targs
containsctrl
- if matrix
u
is not unitary - if matrix
u
is not of a compatible size withnumTargs
- if a node cannot fit the required number of target amplitudes in distributed mode
- if
Referenced by TEST_CASE().
◆ controlledNot()
void controlledNot | ( | Qureg | qureg, |
int | controlQubit, | ||
int | targetQubit | ||
) |
Apply the controlled not (single control, single target) gate, also known as the c-X, c-sigma-X, c-Pauli-X and c-bit-flip gate.
This applies pauliX to the target qubit if the control qubit has value 1. This effects the two-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & & 1 \\ & & 1 \end{pmatrix} \]
on the control and target qubits.
- See also
- Parameters
-
[in,out] qureg the state-vector or density matrix to modify [in] controlQubit nots the target if this qubit is 1 [in] targetQubit qubit to not
- Exceptions
-
invalidQuESTInputError() - if either
controlQubit
ortargetQubit
are outside [0,qureg.numQubitsRepresented
) - if
controlQubit
andtargetQubit
are equal
- if either
Referenced by TEST_CASE().
◆ controlledPauliY()
void controlledPauliY | ( | Qureg | qureg, |
int | controlQubit, | ||
int | targetQubit | ||
) |
Apply the controlled pauliY (single control, single target) gate, also known as the c-Y and c-sigma-Y gate.
This applies pauliY to the target qubit if the control qubit has value 1. This effects the two-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & & -i \\ & & i \end{pmatrix} \]
on the control and target qubits.
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubit applies pauliY to the target if this qubit is 1 [in] targetQubit qubit to not
- Exceptions
-
invalidQuESTInputError() - if either
controlQubit
ortargetQubit
are outside [0,qureg.numQubitsRepresented
) - if
controlQubit
andtargetQubit
are equal
- if either
Referenced by TEST_CASE().
◆ controlledPhaseFlip()
void controlledPhaseFlip | ( | Qureg | qureg, |
int | idQubit1, | ||
int | idQubit2 | ||
) |
Apply the (two-qubit) controlled phase flip gate, also known as the controlled pauliZ gate.
For each state, if both input qubits have value one, multiply the amplitude of that state by -1. This applies the two-qubit unitary:
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & 1 \\ & & & -1 \end{pmatrix} \]
with circuit diagram:
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] idQubit1,idQubit2 qubits to operate upon
- Exceptions
-
invalidQuESTInputError() - if
idQubit1
oridQubit2
are outside [0,qureg.numQubitsRepresented
) - if
idQubit1
andidQubit2
are equal
- if
Referenced by TEST_CASE().
◆ controlledPhaseShift()
Introduce a phase factor \( \exp(i \theta) \) on state \( |11\rangle \) of qubits idQubit1
and idQubit2
.
For angle \(\theta\), this effects the unitary
\[ \begin{pmatrix} 1 & & & \\ & 1 & & \\ & & 1 & \\ & & & \exp(i \theta) \end{pmatrix} \]
on idQubit1
and idQubit2
.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] idQubit1 first qubit in the state to phase shift [in] idQubit2 second qubit in the state to phase shift [in] angle amount by which to shift the phase in radians
- Exceptions
-
invalidQuESTInputError() - if
idQubit1
oridQubit2
are outside [0,qureg.numQubitsRepresented
) - if
idQubit1
andidQubit2
are equal
- if
Referenced by TEST_CASE().
◆ controlledRotateAroundAxis()
void controlledRotateAroundAxis | ( | Qureg | qureg, |
int | controlQubit, | ||
int | targetQubit, | ||
qreal | angle, | ||
Vector | axis | ||
) |
Applies a controlled rotation by a given angle around a given vector on the Bloch-sphere.
The vector must not be zero (else an error is thrown), but needn't be unit magnitude.
For angle \(\theta\) and axis vector \(\vec{n}\), applies \(R_{\hat{n}} = \exp \left(- i \frac{\theta}{2} \hat{n} \cdot \vec{\sigma} \right) \) to states where the target qubit is 1 ( \(\vec{\sigma}\) is the vector of Pauli matrices).
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubit qubit with value 1 in the rotated states [in] targetQubit qubit to rotate [in] angle angle by which to rotate in radians [in] axis vector around which to rotate (can be non-unit; will be normalised)
- Exceptions
-
invalidQuESTInputError() - if either
controlQubit
ortargetQubit
are outside [0,qureg.numQubitsRepresented
) - if
controlQubit
andtargetQubit
are equal - if
axis
is the zero vector
- if either
Referenced by TEST_CASE().
◆ controlledRotateX()
Applies a controlled rotation by a given angle around the X-axis of the Bloch-sphere.
The target qubit is rotated in states where the control qubit has value 1.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubit qubit which has value 1 in the rotated states [in] targetQubit qubit to rotate [in] angle angle by which to rotate the target qubit in radians
- Exceptions
-
invalidQuESTInputError() - if either
controlQubit
ortargetQubit
are outside [0,qureg.numQubitsRepresented
) - if
controlQubit
andtargetQubit
are equal
- if either
Referenced by TEST_CASE().
◆ controlledRotateY()
Applies a controlled rotation by a given angle around the Y-axis of the Bloch-sphere.
The target qubit is rotated in states where the control qubit has value 1.
- rotateY()
- controlledRotateX()
- controlledRotateZ()
- controlledRotateAroundAxis()
- controlledPhaseShift()
- multiRotateZ()
- multiRotatePauli()
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubit qubit which has value 1 in the rotated states [in] targetQubit qubit to rotate [in] angle angle by which to rotate the target qubit in radians
- Exceptions
-
invalidQuESTInputError() - if either
controlQubit
ortargetQubit
are outside [0,qureg.numQubitsRepresented
) - if
controlQubit
andtargetQubit
are equal
- if either
Referenced by TEST_CASE().
◆ controlledRotateZ()
Applies a controlled rotation by a given angle around the Z-axis of the Bloch-sphere.
The target qubit is rotated in states where the control qubit has value 1.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubit qubit which has value 1 in the rotated states [in] targetQubit qubit to rotate [in] angle angle by which to rotate the target qubit in radians
- Exceptions
-
invalidQuESTInputError() - if either
controlQubit
ortargetQubit
are outside [0,qureg.numQubitsRepresented
) - if
controlQubit
andtargetQubit
are equal
- if either
Referenced by TEST_CASE().
◆ controlledTwoQubitUnitary()
void controlledTwoQubitUnitary | ( | Qureg | qureg, |
int | controlQubit, | ||
int | targetQubit1, | ||
int | targetQubit2, | ||
ComplexMatrix4 | u | ||
) |
Apply a general controlled two-qubit unitary (including a global phase factor).
The given unitary is applied to the target amplitudes where the control qubit has value 1. This effects the many-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\ & & 1 \\ & & & 1 \\ & & & & u_{00} & u_{01} & u_{02} & u_{03} \\ & & & & u_{10} & u_{11} & u_{12} & u_{13} \\ & & & & u_{20} & u_{21} & u_{22} & u_{23} \\ & & & & u_{30} & u_{31} & u_{32} & u_{33} \end{pmatrix} \]
on the control and target qubits.
targetQubit1
is treated as the least
significant qubit in u
, such that a row in u
is dotted with the vector \( |\text{targetQubit2} \;\; \text{targetQubit1}\rangle : \{ |00\rangle, |01\rangle, |10\rangle, |11\rangle \} \)
The passed 4x4 ComplexMatrix must be unitary, otherwise an error is thrown.
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] controlQubit the control qubit which must be in state 1 to effect the given unitary [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 unitary matrix to apply
- Exceptions
-
invalidQuESTInputError() - if
controlQubit
,targetQubit1
ortargetQubit2
are outside [0,qureg.numQubitsRepresented
) - if any of
controlQubit
,targetQubit1
andtargetQubit2
are equal - if matrix
u
is not unitary- if each node cannot fit 4 amplitudes in distributed mode.
- if
Referenced by TEST_CASE().
◆ controlledUnitary()
void controlledUnitary | ( | Qureg | qureg, |
int | controlQubit, | ||
int | targetQubit, | ||
ComplexMatrix2 | u | ||
) |
Apply a general controlled unitary (single control, single target), which can include a global phase factor.
The given unitary is applied to the target qubit if the control qubit has value 1, effecting the two-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\ & & u_{00} & u_{01}\\ & & u_{10} & u_{11} \end{pmatrix} \]
on the control and target qubits.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubit apply unitary if this qubit is 1 [in] targetQubit qubit to operate on [in] u single-qubit unitary matrix to apply
- Exceptions
-
invalidQuESTInputError() - if either
controlQubit
ortargetQubit
are outside [0,qureg.numQubitsRepresented
) - if
controlQubit
andtargetQubit
are equal - if
u
is not unitary
- if either
Referenced by TEST_CASE().
◆ diagonalUnitary()
void diagonalUnitary | ( | Qureg | qureg, |
int * | targets, | ||
int | numTargets, | ||
SubDiagonalOp | op | ||
) |
Apply a many-qubit unitary specified as a diagonal matrix upon a specific set of qubits of a quantum register.
Assume the given SubDiagonalOp op
represents unitary operator
\[ \hat{D} = \begin{pmatrix} d_1 & & & \\ & d_2 & & \\ & & d_3 & \\ & & & \ddots \end{pmatrix} \]
Valid unitary operators have elements which satisfy \(|d_i|=1 \; \forall \; i\).
This function effects
\[ |\psi\rangle \rightarrow \hat{D}_{\text{targets}} |\psi\rangle \]
upon state-vectors \(|\psi\rangle\), and
\[ \rho \rightarrow \hat{D}_{\text{targets}} \; \rho \; \hat{D}_{\text{targets}}^\dagger \]
upon density matrices \(\rho\).
To relax unitarity, use applyGateSubDiagonalOp()
To left-multiply the operator as a non-unitary, use applySubDiagonalOp()
To apply a full-Hilbert diagonal operator which must ergo itself be distributed, use applyDiagonalOp()
- Parameters
[in,out] qureg the Qureg instance to operate upon [in] targets the list of target qubit indices [in] numTargets the length of list targets
, which must match the dimension ofop
[in] op a SubDiagonalOp initialised to be unitary
- Exceptions
invalidQuESTInputError()
- if
numTargets
does not match the size ofop
- if
numTargets
is invalid (<0 or larger thanqureg
)- if
numTargets
contains an invalid qubit index, or a repetition- if
op
is non-unitary
Referenced by TEST_CASE().
◆ hadamard()
void hadamard | ( | Qureg | qureg, |
int | targetQubit | ||
) |
Apply the single-qubit Hadamard gate.
This takes \(|0\rangle\) to \(|+\rangle\) and \(|1\rangle\) to \(|-\rangle\), and is equivalent to a rotation of \(\pi\) around the x-axis then \(\pi/2\) about the y-axis on the Bloch-sphere. I.e.
\[ \frac{1}{\sqrt{2}} \begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix} \]
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate on
- Exceptions
-
invalidQuESTInputError() - if
targetQubit
is outside [0,qureg.numQubitsRepresented
)
- if
Referenced by TEST_CASE().
◆ multiControlledMultiQubitNot()
void multiControlledMultiQubitNot | ( | Qureg | qureg, |
int * | ctrls, | ||
int | numCtrls, | ||
int * | targs, | ||
int | numTargs | ||
) |
Apply a NOT (or Pauli X) gate with multiple control and target qubits.
This applies pauliX to qubits targs
on every basis state for which the control qubits ctrls
are all in the \(|1\rangle\) state. The ordering within each of ctrls
and targs
has no effect on the operation.
This function is equivalent, but significantly faster (approximately
numTargs
times) than applying controlled NOTs on each qubit intargs
in turn, since:\[ C_{a, \,b, \,\dots}( X_c \otimes X_d \otimes \dots ) \equiv C_{a, \,b, \,\dots}( X_c) \; \otimes \; C_{a, \,b, \,\dots}(X_d) \; \otimes \; \dots \]
The effected unitary, if
targs
andctrls
happened to be contiguous, has matrix:\[ \begin{pmatrix} 1 \\ & 1 \\\ & & \ddots \\ & & & & & & {{\scriptstyle\cdot}^{{\scriptstyle\cdot}^{{\scriptstyle\cdot}}}} \\ & & & & & 1 & \\ & & & & 1 & & \\ & & & {{\scriptstyle\cdot}^{{\scriptstyle\cdot}^{{\scriptstyle\cdot}}}} & & & \end{pmatrix} \]
and circuit diagram:
In distributed mode, this operation requires at most a single round of pair-wise communication between nodes, and hence is as efficient as pauliX().
- See also
- Parameters
[in,out] qureg a state-vector or density matrix to modify [in] ctrls a list of the control qubit indices [in] numCtrls the length of list ctrls
[in] targs a list of the qubits to be targeted by the X gates [in] numTargs the length of list targs
- Exceptions
invalidQuESTInputError()
- if any qubit in
ctrls
andtargs
is invalid, i.e. outside [0,qureg.numQubitsRepresented
)- if
ctrls
ortargs
contain any repetitions- if any qubit in
ctrls
is also intargs
(and vice versa)- if
numTargs
< 1- if
numCtrls
< 1 (use multiQubitNot() for no controls)segmentation-fault
- if
ctrls
contains fewer elements thannumCtrls
- if
targs
contains fewer elements thannumTargs
Referenced by TEST_CASE().
◆ multiControlledMultiQubitUnitary()
void multiControlledMultiQubitUnitary | ( | Qureg | qureg, |
int * | ctrls, | ||
int | numCtrls, | ||
int * | targs, | ||
int | numTargs, | ||
ComplexMatrixN | u | ||
) |
Apply a general multi-controlled multi-qubit unitary (including a global phase factor).
Any number of control and target qubits can be specified. This effects the many-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & \ddots \\ & & & u_{00} & u_{01} & \dots \\ & & & u_{10} & u_{11} & \dots \\ & & & \vdots & \vdots & \ddots \end{pmatrix} \]
on the control and target qubits.
The target qubits in targs
are treated as ordered least significant to most significant in u
.
The passed ComplexMatrixN must be unitary and be a compatible size with the specified number of target qubits, otherwise an error is thrown.
To left-multiply a non-unitary ComplexMatrixN, including control qubits, use applyMultiControlledMatrixN()
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.
- See also
- 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 unitary matrix to apply
- Exceptions
-
invalidQuESTInputError() - if any qubit in
ctrls
andtargs
is invalid, i.e. outside [0,qureg.numQubitsRepresented
) - if
ctrls
ortargs
contain any repetitions - if any qubit in
ctrls
is also intargs
(and vice versa) - if
numTargs
< 1 - if
numCtrls
< 1 (use multiQubitUnitary() for no controls) - if matrix
u
is not unitary - if matrix
u
is not of a compatible size withnumTargs
- if a node cannot fit the required number of target amplitudes in distributed mode
segmentation-fault - if
ctrls
contains fewer elements thannumCtrls
- if
targs
contains fewer elements thannumTargs
- if any qubit in
Referenced by TEST_CASE().
◆ multiControlledMultiRotatePauli()
void multiControlledMultiRotatePauli | ( | Qureg | qureg, |
int * | controlQubits, | ||
int | numControls, | ||
int * | targetQubits, | ||
enum pauliOpType * | targetPaulis, | ||
int | numTargets, | ||
qreal | angle | ||
) |
Apply a multi-controlled multi-target multi-Pauli rotation, also known as a controlled Pauli gadget.
This is the unitary
\[ |1\rangle\langle 1|^{\otimes\, \text{numControls}} \; \otimes \, \exp \left( - i \, \frac{\theta}{2} \; \bigotimes_{j}^{\text{numTargets}} \hat{\sigma}_j\right) \;\;+\;\; \sum\limits_{k=0}^{2^{\,\text{numControls}} - 2} |k\rangle\langle k| \otimes \text{I} \]
where \(\hat{\sigma}_j\) are the Pauli operators (pauliOpType) in targetPaulis
, which operate upon the corresponding qubits in targetQubits
.
All qubits not appearing in
targetQubits
andcontrolQubits
are assumed to receive the identity operator.For example:
int numCtrls = 1;int numTargs = 4;int ctrls[] = {4};int targs[] = {0,1,2,3};qureg, ctrls, numCtrls, targs, paulis, numTargs, 0.1);void multiControlledMultiRotatePauli(Qureg qureg, int *controlQubits, int numControls, int *targetQubits, enum pauliOpType *targetPaulis, int numTargets, qreal angle)Apply a multi-controlled multi-target multi-Pauli rotation, also known as a controlled Pauli gadget.Definition: QuEST.c:713effects
\[ |1\rangle\langle 1 | \otimes \exp\left( -i \, (0.1/2) \, X_0 \, Y_1 \, Z_2 \right) \, \text{I}_3 \;\; + \;\; |0\rangle\langle 0| \otimes \text{I}^{\otimes 4} \]
on
qureg
, where unspecified qubits (along with those targeted byPAULI_I
) are assumed to receive the identity operator (excluded from exponentiation).This means specifying
PAULI_I
does not induce a global phase factor \(\exp(-i \theta/2)\). Hence, if alltargetPaulis
are identity, then this function does nothing toqureg
. SpecifyingPAULI_I
on a qubit is superfluous but allowed for convenience.This function effects the controlled Pauli gadget by first (controlled) rotating the qubits which are targeted with either
X
orY
into alternate basis, performing multiControlledMultiRotateZ() on all target qubits, then restoring the original basis.
- See also
- Parameters
[in,out] qureg object representing the set of all qubits [in] controlQubits list of the indices of qubits to control upon [in] numControls length of length controlQubits
[in] targetQubits a list of the indices of the target qubits [in] targetPaulis a list of the Pauli operators around which to rotate the target qubits [in] numTargets length of list targetQubits
[in] angle the angle by which the multi-qubit state is rotated around the Z axis
- Exceptions
invalidQuESTInputError()
- if any qubit in
controlQubits
andtargetQubits
is invalid, i.e. outside [0,qureg.numQubitsRepresented
)- if
controlQubits
ortargetQubits
contain any repetitions- if any qubit in
controlQubits
is also intargetQubits
(and vice versa)- if
numTargets
< 1- if
numControls
< 1 (use multiRotateZ() for no controls)- if any element of
targetPaulis
is not one ofPAULI_I
,PAULI_X
,PAULI_Y
,PAULI_Z
segmentation-fault
- if
controlQubits
contains fewer elements thannumControls
- if
targetQubits
contains fewer elements thannumTargets
- if
targetPaulis
contains fewer elements thannumTargets
Referenced by TEST_CASE().
◆ multiControlledMultiRotateZ()
void multiControlledMultiRotateZ | ( | Qureg | qureg, |
int * | controlQubits, | ||
int | numControls, | ||
int * | targetQubits, | ||
int | numTargets, | ||
qreal | angle | ||
) |
Apply a multi-controlled multi-target Z rotation, also known as a controlled phase gadget.
This is the unitary
\[ |1\rangle\langle 1|^{\otimes\, \text{numControls}} \; \otimes \, \exp \left( - i \, \frac{\theta}{2} \; \bigotimes_{j}^{\text{numTargets}} Z_j\right) \;\;+\;\; \sum\limits_{k=0}^{2^{\,\text{numControls}} - 2} |k\rangle\langle k| \otimes \text{I} \]
where the Pauli Z gates operate upon the qubits in targetQubits
, and cause rotations of \(\theta =\) angle
.
All qubits not appearing in
targetQubits
andcontrolQubits
are assumed to receive the identity operator.This has the effect of premultiplying all amplitudes (for which the control qubits are
1
) with \(\exp(\pm i \theta/2)\), where the sign is determined by the parity of the target qubits for that amplitude.
- See also
- Parameters
[in,out] qureg object representing the set of all qubits [in] controlQubits list of the indices of qubits to control upon [in] numControls length of length controlQubits
[in] targetQubits a list of the indices of the target qubits [in] numTargets length of list targetQubits
[in] angle the angle by which the multi-qubit state is rotated around the Z axis
- Exceptions
invalidQuESTInputError()
- if any qubit in
controlQubits
andtargetQubits
is invalid, i.e. outside [0,qureg.numQubitsRepresented
)- if
controlQubits
ortargetQubits
contain any repetitions- if any qubit in
controlQubits
is also intargetQubits
(and vice versa)- if
numTargets
< 1- if
numControls
< 1 (use multiRotateZ() for no controls)segmentation-fault
- if
controlQubits
contains fewer elements thannumControls
- if
targetQubits
contains fewer elements thannumTargets
Referenced by TEST_CASE().
◆ multiControlledPhaseFlip()
void multiControlledPhaseFlip | ( | Qureg | qureg, |
int * | controlQubits, | ||
int | numControlQubits | ||
) |
Apply the multiple-qubit controlled phase flip gate, also known as the multiple-qubit controlled pauliZ gate.
For each state, if all control qubits have value one, multiply the amplitude of that state by -1. This applies the many-qubit unitary:
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & \ddots \\ & & & 1 \\ & & & & -1 \end{pmatrix} \]
on the control qubits.
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubits array of input qubits [in] numControlQubits number of input qubits
- Exceptions
-
invalidQuESTInputError() - if
numControlQubits
is outside [1,qureg.numQubitsRepresented
) - if any qubit in
controlQubits
is outside [0,qureg.numQubitsRepresented
) - if any qubit in
qubits
is repeated
- if
Referenced by TEST_CASE().
◆ multiControlledPhaseShift()
void multiControlledPhaseShift | ( | Qureg | qureg, |
int * | controlQubits, | ||
int | numControlQubits, | ||
qreal | angle | ||
) |
Introduce a phase factor \( \exp(i \theta) \) on state \( |1 \dots 1 \rangle \) of the passed qubits.
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubits array of qubits to phase shift [in] numControlQubits the length of array controlQubits
[in] angle amount by which to shift the phase in radians
- Exceptions
-
invalidQuESTInputError() - if
numControlQubits
is outside [1,qureg.numQubitsRepresented
]) - if any qubit index in
controlQubits
is outside [0,qureg.numQubitsRepresented
]) - if the qubits in
controlQubits
are not unique
- if
Referenced by TEST_CASE().
◆ multiControlledTwoQubitUnitary()
void multiControlledTwoQubitUnitary | ( | Qureg | qureg, |
int * | controlQubits, | ||
int | numControlQubits, | ||
int | targetQubit1, | ||
int | targetQubit2, | ||
ComplexMatrix4 | u | ||
) |
Apply a general multi-controlled two-qubit unitary (including a global phase factor).
Any number of control qubits can be specified, and if all have value 1, the given unitary is applied to the target qubit. This effects the many-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & \ddots \\ & & & u_{00} & u_{01} & u_{02} & u_{03} \\ & & & u_{10} & u_{11} & u_{12} & u_{13} \\ & & & u_{20} & u_{21} & u_{22} & u_{23} \\ & & & u_{30} & u_{31} & u_{32} & u_{33} \end{pmatrix} \]
on the control and target qubits.
targetQubit1
is treated as the least
significant qubit in u
, such that a row in u
is dotted with the vector \( |\text{targetQubit2} \;\; \text{targetQubit1}\rangle : \{ |00\rangle, |01\rangle, |10\rangle, |11\rangle \} \)
The passed 4x4 ComplexMatrix must be unitary, otherwise an error is thrown.
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] controlQubits the control qubits which all must be in state 1 to effect the given unitary [in] numControlQubits the number of control qubits [in] targetQubit1 first target qubit, treated as least significant in u
[in] targetQubit2 second target qubit, treated as most significant in u
[in] u unitary matrix to apply
- Exceptions
-
invalidQuESTInputError() - if
targetQubit1
ortargetQubit2
are outside [0,qureg.numQubitsRepresented
) - if
targetQubit1
equalstargetQubit2
- if any qubit in
controlQubits
is outside [0,qureg.numQubitsRepresented
) - if
controlQubits
are not unique - if either
targetQubit1
andtargetQubit2
are incontrolQubits
- if matrix
u
is not unitary - if each node cannot fit 4 amplitudes in distributed mode
- if
Referenced by TEST_CASE().
◆ multiControlledUnitary()
void multiControlledUnitary | ( | Qureg | qureg, |
int * | controlQubits, | ||
int | numControlQubits, | ||
int | targetQubit, | ||
ComplexMatrix2 | u | ||
) |
Apply a general multiple-control single-target unitary, which can include a global phase factor.
Any number of control qubits can be specified, and if all have value 1, the given unitary is applied to the target qubit. This effects the many-qubit unitary
\[ \begin{pmatrix} 1 \\ & 1 \\\ & & \ddots \\ & & & u_{00} & u_{01}\\ & & & u_{10} & u_{11} \end{pmatrix} \]
on the control and target qubits. The given 2x2 ComplexMatrix must be unitary, otherwise an error is thrown.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubits applies unitary if all qubits in this array equal 1 [in] numControlQubits number of control qubits [in] targetQubit qubit to operate on [in] u single-qubit unitary matrix to apply
- Exceptions
-
invalidQuESTInputError() - if
numControlQubits
is outside [1,qureg.numQubitsRepresented
]) - if any qubit index (
targetQubit
or one incontrolQubits
) is outside [0,qureg.numQubitsRepresented
]) - if any qubit in
controlQubits
is repeated - if
controlQubits
containstargetQubit
- if
u
is not unitary
- if
Referenced by TEST_CASE().
◆ multiQubitNot()
void multiQubitNot | ( | Qureg | qureg, |
int * | targs, | ||
int | numTargs | ||
) |
Apply a NOT (or Pauli X) gate with multiple target qubits, which has the same effect as (but is much faster than) applying each single-qubit NOT gate in turn.
The ordering within targs
has no effect on the operation.
This function is equivalent, but significantly faster (approximately
numTargs
times) than applying pauliX() on each qubit intargs
in turn.\[ X_a \otimes X_b \otimes \dots \]
The effected unitary, if
targs
happen to be contiguous, has matrix:\[ \begin{pmatrix} & & & {{\scriptstyle\cdot}^{{\scriptstyle\cdot}^{{\scriptstyle\cdot}}}} \\ & & 1 & \\ & 1 & & \\ {{\scriptstyle\cdot}^{{\scriptstyle\cdot}^{{\scriptstyle\cdot}}}} & & & \end{pmatrix} \]
and circuit diagram:
In distributed mode, this operation requires at most a single round of pair-wise communication between nodes, and hence is as efficient as pauliX().
- Parameters
[in,out] qureg a state-vector or density matrix to modify [in] targs a list of the qubits to be targeted by the X gates [in] numTargs the length of list targs
- Exceptions
invalidQuESTInputError()
- if any qubit in
targs
is invalid, i.e. outside [0,qureg.numQubitsRepresented
)- if
targs
contain any repetitions- if
numTargs
< 1- if
numTargs
>qureg.numQubitsRepresented
segmentation-fault
- if
targs
contains fewer elements thannumTargs
Referenced by TEST_CASE().
◆ multiQubitUnitary()
void multiQubitUnitary | ( | Qureg | qureg, |
int * | targs, | ||
int | numTargs, | ||
ComplexMatrixN | u | ||
) |
Apply a general multi-qubit unitary (including a global phase factor) with any number of target qubits.
The first target qubit in targs
is treated as least significant in u
. For example,
will invoke multiplication
\[ \begin{pmatrix} u_{00} & u_{01} & u_{02} & u_{03} & u_{04} & u_{05} & u_{06} & u_{07} \\ u_{10} & u_{11} & u_{12} & u_{13} & u_{14} & u_{15} & u_{16} & u_{17} \\ u_{20} & u_{21} & u_{22} & u_{23} & u_{24} & u_{25} & u_{26} & u_{27} \\ u_{30} & u_{31} & u_{32} & u_{33} & u_{34} & u_{35} & u_{36} & u_{37} \\ u_{40} & u_{41} & u_{42} & u_{43} & u_{44} & u_{45} & u_{46} & u_{47} \\ u_{50} & u_{51} & u_{52} & u_{53} & u_{54} & u_{55} & u_{56} & u_{57} \\ u_{60} & u_{61} & u_{62} & u_{63} & u_{64} & u_{65} & u_{66} & u_{67} \\ u_{70} & u_{71} & u_{72} & u_{73} & u_{74} & u_{75} & u_{76} & u_{77} \\ \end{pmatrix} \begin{pmatrix} |cba\rangle = |000\rangle \\ |cba\rangle = |001\rangle \\ |cba\rangle = |010\rangle \\ |cba\rangle = |011\rangle \\ |cba\rangle = |100\rangle \\ |cba\rangle = |101\rangle \\ |cba\rangle = |110\rangle \\ |cba\rangle = |111\rangle \end{pmatrix} \]
The passed ComplexMatrix must be unitary and be a compatible size with the specified number of target qubits, otherwise an error is thrown.
To effect a non-unitary ComplexMatrixN, use applyGateMatrixN().
To left-multiply a non-unitary ComplexMatrixN, use applyMatrixN().
To specify only the diagonal elements of the matrix, use diagonalUnitary().
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.
- See also
- 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 unitary matrix to apply
- Exceptions
-
invalidQuESTInputError() - if any index in
targs
is outside of [0,qureg.numQubitsRepresented
) - if
targs
are not unique - if matrix
u
is not unitary - if
u
is not of a compatible size withnumTargs
- if a node cannot fit the required number of target amplitudes in distributed mode
- if any index in
Referenced by TEST_CASE().
◆ multiRotatePauli()
void multiRotatePauli | ( | Qureg | qureg, |
int * | targetQubits, | ||
enum pauliOpType * | targetPaulis, | ||
int | numTargets, | ||
qreal | angle | ||
) |
Apply a multi-qubit multi-Pauli rotation, also known as a Pauli gadget, on a selected number of qubits.
This is the unitary
\[ \exp \left( - i \, \frac{\theta}{2} \; \bigotimes_{j}^{\text{numTargets}} \hat{\sigma}_j\right) \]
where \(\theta = \)angle
and \(\hat{\sigma}_j \in \{X, Y, Z\}\) is a Pauli operator pauliOpType operating upon the corresponding qubit targetQubits
.
For example:
effects
\[ \exp \left( - i \, (0.1/2) \; X_5 \, Y_8 \, Z_9 \right) \]
on qureg
, where unspecified qubits (along with those targeted by PAULI_I
) are assumed to receive the identity operator (excluded from exponentiation).
This means specifying
PAULI_I
does not induce a global phase factor \(\exp(-i \theta/2)\). Hence, if alltargetPaulis
are identity, then this function does nothing toqureg
. SpecifyingPAULI_I
on a qubit is superfluous but allowed for convenience.
This function effects the Pauli gadget by first rotating the qubits which are nominated to receive X
or Y
Paulis into alternate basis, performing multiRotateZ() on all target qubits, then restoring the original basis.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubits a list of the indices of the target qubits [in] targetPaulis a list of the Pauli operators (pauliOpType) to apply to the corresponding qubits in targetQubits
[in] numTargets number of target qubits, i.e. the length of targetQubits
andtargetPaulis
[in] angle the angle by which the multi-qubit state is rotated
- Exceptions
-
invalidQuESTInputError() - if
numTargets
is outside [1,qureg.numQubitsRepresented
) - if any qubit in
targetQubits
is outside [0,qureg.numQubitsRepresented
) - if any qubit in
targetQubits
is repeated - if any element of
targetPaulis
is not one ofPAULI_I
,PAULI_X
,PAULI_Y
,PAULI_Z
segmentation-fault - if
targetQubits
contains fewer elements thannumTargets
- if
targetPaulis
contains fewer elements thannumTargets
- if
Referenced by TEST_CASE().
◆ multiRotateZ()
Apply a multi-qubit Z rotation, also known as a phase gadget, on a selected number of qubits.
This is the unitary
\[ \exp \left( - i \, \frac{\theta}{2} \; \bigotimes_{j}^{\text{numQubits}} Z_j\right) \]
where the Pauli Z gates operate the qubits listed in qubits
, and cause rotations of \(\theta =\) angle
.
All qubits not appearing in
qubits
are assumed to receive the identity operator.
This has the effect of premultiplying every amplitude with \(\exp(\pm i \theta/2)\) where the sign is determined by the parity of the target qubits for that amplitude.
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] qubits a list of the indices of the target qubits [in] numQubits number of target qubits [in] angle the angle by which the multi-qubit state is rotated around the Z axis
- Exceptions
-
invalidQuESTInputError() - if
numQubits
is outside [1,qureg.numQubitsRepresented
]) - if any qubit in
qubits
is outside [0,qureg.numQubitsRepresented
]) - if any qubit in
qubits
is repeated
segmentation-fault - if
qubits
contains fewer elements thannumQubits
- if
Referenced by TEST_CASE().
◆ multiStateControlledUnitary()
void multiStateControlledUnitary | ( | Qureg | qureg, |
int * | controlQubits, | ||
int * | controlState, | ||
int | numControlQubits, | ||
int | targetQubit, | ||
ComplexMatrix2 | u | ||
) |
Apply a general single-qubit unitary with multiple control qubits, conditioned upon a specific bit sequence.
Any number of control qubits can be specified, along with their classical state (0
or 1
) to condition upon. Only amplitudes of computational basis states for which controlQubits
have corresponding bit values controlState
are modified by u
.
This function is equivalent (albeit faster) to applying pauliX() on each of the control qubits which are conditioned on outcome
0
, calling multiControlledUnitary(), then re-appplying pauliX() on the same qubits.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] controlQubits the indices of the control qubits [in] controlState the bit values (0 or 1) of each control qubit, upon which to condition [in] numControlQubits number of control qubits [in] targetQubit qubit to operate the unitary upon [in] u single-qubit unitary matrix to apply
- Exceptions
-
invalidQuESTInputError() - if
numControlQubits
is outside [1,qureg.numQubitsRepresented
]) - if any qubit index (
targetQubit
or one incontrolQubits
) is outside [0,qureg.numQubitsRepresented
]), - if any qubit in
controlQubits
is repeated - if
controlQubits
containstargetQubit
- if any element of
controlState
is not a bit (0
or1
) - if
u
is not unitary
- if
Referenced by TEST_CASE().
◆ pauliX()
void pauliX | ( | Qureg | qureg, |
int | targetQubit | ||
) |
Apply the single-qubit Pauli-X (also known as the X, sigma-X, NOT or bit-flip) gate.
This is a rotation of \(\pi\) around the x-axis on the Bloch sphere. I.e.
\[ \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix} \]
with circuit diagram:
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate on
- Exceptions
-
invalidQuESTInputError() - if
targetQubit
is outside [0,qureg.numQubitsRepresented
)
- if
Referenced by TEST_CASE().
◆ pauliY()
void pauliY | ( | Qureg | qureg, |
int | targetQubit | ||
) |
Apply the single-qubit Pauli-Y (also known as the Y or sigma-Y) gate.
This is a rotation of \(\pi\) around the Y-axis on the Bloch sphere. I.e.
\[ \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix} \]
with circuit diagram:
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate on
- Exceptions
-
invalidQuESTInputError() - if
targetQubit
is outside [0,qureg.numQubitsRepresented
)
- if
Referenced by TEST_CASE().
◆ pauliZ()
void pauliZ | ( | Qureg | qureg, |
int | targetQubit | ||
) |
Apply the single-qubit Pauli-Z (also known as the Z, sigma-Z or phase-flip) gate.
This is a rotation of \(\pi\) around the Z-axis (a phase shift) on the Bloch sphere. I.e.
\[ \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix} \]
with circuit diagram:
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate on
- Exceptions
-
invalidQuESTInputError() - if
targetQubit
is outside [0,qureg.numQubitsRepresented
)
- if
Referenced by TEST_CASE().
◆ phaseShift()
Shift the phase between \( |0\rangle \) and \( |1\rangle \) of a single qubit by a given angle.
This is equivalent to a Z-axis rotation of the Bloch-sphere up to a global phase factor. For angle \(\theta\), this effects single-qubit unitary
\[ \begin{pmatrix} 1 & 0 \\ 0 & \exp(i \theta) \end{pmatrix} \]
with circuit diagram
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to undergo a phase shift [in] angle amount by which to shift the phase in radians
- Exceptions
-
invalidQuESTInputError() targetQubit
is outside [0,qureg.numQubitsRepresented
).
Referenced by TEST_CASE().
◆ rotateAroundAxis()
Rotate a single qubit by a given angle around a given Vector on the Bloch-sphere.
The vector must not be zero (else an error is thrown), but needn't be unit magnitude, since it will be normalised by QuEST.
For angle \(\theta\) and axis vector \(\vec{n}\), applies \(R_{\hat{n}} = \exp \left(- i \frac{\theta}{2} \hat{n} \cdot \vec{\sigma} \right) \) where \(\vec{\sigma}\) is the vector of Pauli matrices.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] rotQubit qubit to rotate [in] angle angle by which to rotate in radians [in] axis vector around which to rotate (can be non-unit; will be normalised)
- Exceptions
-
invalidQuESTInputError() - if
rotQubit
is outside [0,qureg.numQubitsRepresented
) - if
axis
is the zero vector
- if
Referenced by TEST_CASE().
◆ rotateX()
Rotate a single qubit by a given angle around the X-axis of the Bloch-sphere.
For angle \(\theta\), applies
\[ \begin{pmatrix} \cos\theta/2 & -i \sin \theta/2\\ -i \sin \theta/2 & \cos \theta/2 \end{pmatrix} \]
with circuit diagram:
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] rotQubit qubit to rotate [in] angle angle by which to rotate in radians
- Exceptions
-
invalidQuESTInputError() - if
rotQubit
is outside [0,qureg.numQubitsRepresented
)
- if
Referenced by TEST_CASE().
◆ rotateY()
Rotate a single qubit by a given angle around the Y-axis of the Bloch-sphere.
For angle \(\theta\), applies
\[ \begin{pmatrix} \cos\theta/2 & - \sin \theta/2\\ \sin \theta/2 & \cos \theta/2 \end{pmatrix} \]
with circuit diagram:
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] rotQubit qubit to rotate [in] angle angle by which to rotate in radians
- Exceptions
-
invalidQuESTInputError if rotQubit
is outside [0,qureg.numQubitsRepresented
).
Referenced by TEST_CASE().
◆ rotateZ()
Rotate a single qubit by a given angle around the Z-axis of the Bloch-sphere (also known as a phase shift gate).
For angle \(\theta\), applies
\[ \begin{pmatrix} \exp(-i \theta/2) & 0 \\ 0 & \exp(i \theta/2) \end{pmatrix} \]
with circuit diagram:
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] rotQubit qubit to rotate [in] angle angle by which to rotate in radians
- Exceptions
-
invalidQuESTInputError() - if
rotQubit
is outside [0,qureg.numQubitsRepresented
)
- if
Referenced by TEST_CASE().
◆ sGate()
void sGate | ( | Qureg | qureg, |
int | targetQubit | ||
) |
Apply the single-qubit S gate.
This is a rotation of \(\pi/2\) around the Z-axis on the Bloch sphere, or the unitary:
\[ \begin{pmatrix} 1 & 0 \\ 0 & i \end{pmatrix} \]
with circuit diagram:
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate upon
- Exceptions
-
invalidQuESTInputError() - if
targetQubit
is outside [0,qureg.numQubitsRepresented
)
- if
Referenced by TEST_CASE().
◆ sqrtSwapGate()
void sqrtSwapGate | ( | Qureg | qureg, |
int | qb1, | ||
int | qb2 | ||
) |
Performs a sqrt SWAP gate between qubit1
and qubit2
.
This effects
\[ \begin{pmatrix} 1 \\ & \frac{1}{2}(1+i) & \frac{1}{2}(1-i) \\\ & \frac{1}{2}(1-i) & \frac{1}{2}(1+i) \\ & & & 1 \end{pmatrix} \]
on the designated qubits, though is performed internally by three CNOT gates.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] qb1 qubit to sqrt swap [in] qb2 other qubit to sqrt swap
- Exceptions
-
invalidQuESTInputError() - if either
qubit1
orqubit2
are outside [0,qureg.numQubitsRepresented
) - if
qubit1
andqubit2
are equal
- if either
Referenced by TEST_CASE().
◆ swapGate()
void swapGate | ( | Qureg | qureg, |
int | qubit1, | ||
int | qubit2 | ||
) |
Performs a SWAP gate between qubit1
and qubit2
.
This effects
\[ \begin{pmatrix} 1 \\ & & 1 \\\ & 1 \\ & & & 1 \end{pmatrix} \]
on the designated qubits, though is performed internally by three CNOT gates.
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] qubit1 qubit to swap [in] qubit2 other qubit to swap
- Exceptions
-
invalidQuESTInputError() - if either
qubit1
orqubit2
are outside [0,qureg.numQubitsRepresented
) - if
qubit1
andqubit2
are equal
- if either
Referenced by TEST_CASE().
◆ tGate()
void tGate | ( | Qureg | qureg, |
int | targetQubit | ||
) |
Apply the single-qubit T gate.
This is a rotation of \(\pi/4\) around the Z-axis on the Bloch sphere, or the unitary:
\[ \begin{pmatrix} 1 & 0 \\ 0 & \exp\left(i \frac{\pi}{4}\right) \end{pmatrix} \]
with circuit diagram:
- See also
- Parameters
-
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate upon
- Exceptions
-
invalidQuESTInputError() - if
targetQubit
is outside [0,qureg.numQubitsRepresented
)
- if
Referenced by TEST_CASE().
◆ twoQubitUnitary()
void twoQubitUnitary | ( | Qureg | qureg, |
int | targetQubit1, | ||
int | targetQubit2, | ||
ComplexMatrix4 | u | ||
) |
Apply a general two-qubit unitary (including a global phase factor).
targetQubit1
is treated as the least
significant qubit in u
, such that a row in u
is dotted with the vector \( |\text{targetQubit2} \;\; \text{targetQubit1}\rangle : \{ |00\rangle, |01\rangle, |10\rangle, |11\rangle \} \)
For example,
will invoke multiplication
\[ \begin{pmatrix} u_{00} & u_{01} & u_{02} & u_{03} \\ u_{10} & u_{11} & u_{12} & u_{13} \\ u_{20} & u_{21} & u_{22} & u_{23} \\ u_{30} & u_{31} & u_{32} & u_{33} \end{pmatrix} \begin{pmatrix} |ba\rangle = |00\rangle \\ |ba\rangle = |01\rangle \\ |ba\rangle = |10\rangle \\ |ba\rangle = |11\rangle \end{pmatrix} \]
The passed ComplexMatrix4 must be unitary, otherwise an error is thrown.
Use applyMatrix4() to left-multiply a non-unitary ComplexMatrix4.
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.
- See also
- 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 unitary matrix to apply
- Exceptions
invalidQuESTInputError()
- if
targetQubit1
ortargetQubit2
are outside [0,qureg.numQubitsRepresented
)- if
targetQubit1
equalstargetQubit2
- if matrix
u
is not unitary- if each node cannot fit 4 amplitudes in distributed mode
Referenced by TEST_CASE().
◆ unitary()
void unitary | ( | Qureg | qureg, |
int | targetQubit, | ||
ComplexMatrix2 | u | ||
) |
Apply a general single-qubit unitary (including a global phase factor).
The passed 2x2 ComplexMatrix must be unitary, otherwise an error is thrown.
If qureg
is a state-vector, then the resulting state is \( u \, |\text{qureg}\rangle \).
If qureg
is a density-matrix \( \rho \), then the resulting state is \( u \, \rho \, u^\dagger \).
Use applyMatrix2() to left-multiply a non-unitary ComplexMatrix2
- See also
- Parameters
[in,out] qureg object representing the set of all qubits [in] targetQubit qubit to operate on [in] u unitary matrix to apply
- Exceptions
invalidQuESTInputError()
- if
targetQubit
is outside [0,qureg.numQubitsRepresented
)- if matrix
u
is not unitary
Referenced by TEST_CASE().