Unitaries

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().

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]ctrlsa list of the control qubits
[in]numCtrlsthe number of control qubits
[in]targsa list of the target qubits, ordered least to most significant
[in]numTargsthe number of target qubits
[in]marbitrary matrix to apply as if it were a unitary gate
Exceptions
invalidQuESTInputError()
  • if any qubit in ctrls and targs is invalid, i.e. outside [0, qureg.numQubitsRepresented)
  • if ctrls or targs contain any repetitions
  • if any qubit in ctrls is also in targs (and vice versa)
  • if numTargs < 1
  • if numCtrls < 1 (use multiQubitUnitary() for no controls)
  • if matrix m is not of a compatible size with numTargs
  • if a node cannot fit the required number of target amplitudes in distributed mode
segmentation-fault
  • if ctrls contains fewer elements than numCtrls
  • if targs contains fewer elements than numTargs
Author
Tyson Jones

Referenced by TEST_CASE().

◆ compactUnitary()

void compactUnitary ( Qureg  qureg,
int  targetQubit,
Complex  alpha,
Complex  beta 
)

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\).

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]targetQubitqubit to operate on
[in]alphacomplex unitary parameter (row 1, column 1)
[in]betacomplex 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
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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]quregobject representing the set of all qubits
[in]controlQubitapply the target unitary if this qubit has value 1
[in]targetQubitqubit on which to apply the target unitary
[in]alphacomplex unitary parameter (row 1, column 1)
[in]betacomplex unitary parameter (row 2, column 1)
Exceptions
invalidQuESTInputError()
  • if either controlQubit or targetQubit are outside [0, qureg.numQubitsRepresented)
  • if controlQubit and targetQubit are equal
  • if alpha, beta don't satisfy |alpha|^2 + |beta|^2 = 1
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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.

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]ctrlthe control qubit
[in]targsa list of the target qubits, ordered least to most significant
[in]numTargsthe number of target qubits
[in]uunitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if ctrl or any index in targs is outside of [0, qureg.numQubitsRepresented)
  • if targs are not unique
  • if targs contains ctrl
  • if matrix u is not unitary
  • if matrix u is not of a compatible size with numTargs
  • if a node cannot fit the required number of target amplitudes in distributed mode
Author
Tyson Jones

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]quregthe state-vector or density matrix to modify
[in]controlQubitnots the target if this qubit is 1
[in]targetQubitqubit to not
Exceptions
invalidQuESTInputError()
  • if either controlQubit or targetQubit are outside [0, qureg.numQubitsRepresented)
  • if controlQubit and targetQubit are equal
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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]quregobject representing the set of all qubits
[in]controlQubitapplies pauliY to the target if this qubit is 1
[in]targetQubitqubit to not
Exceptions
invalidQuESTInputError()
  • if either controlQubit or targetQubit are outside [0, qureg.numQubitsRepresented)
  • if controlQubit and targetQubit are equal
Author
Tyson Jones
Ania Brown (debug)

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:

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]idQubit1,idQubit2qubits to operate upon
Exceptions
invalidQuESTInputError()
  • if idQubit1 or idQubit2 are outside [0, qureg.numQubitsRepresented)
  • if idQubit1 and idQubit2 are equal
Author
Tyson Jones

Referenced by TEST_CASE().

◆ controlledPhaseShift()

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.

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]quregobject representing the set of all qubits
[in]idQubit1first qubit in the state to phase shift
[in]idQubit2second qubit in the state to phase shift
[in]angleamount by which to shift the phase in radians
Exceptions
invalidQuESTInputError()
  • if idQubit1 or idQubit2 are outside [0, qureg.numQubitsRepresented)
  • if idQubit1 and idQubit2 are equal
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]controlQubitqubit with value 1 in the rotated states
[in]targetQubitqubit to rotate
[in]angleangle by which to rotate in radians
[in]axisvector around which to rotate (can be non-unit; will be normalised)
Exceptions
invalidQuESTInputError()
  • if either controlQubit or targetQubit are outside [0, qureg.numQubitsRepresented)
  • if controlQubit and targetQubit are equal
  • if axis is the zero vector
Author
Tyson Jones

Referenced by TEST_CASE().

◆ controlledRotateX()

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.

The target qubit is rotated in states where the control qubit has value 1.

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]controlQubitqubit which has value 1 in the rotated states
[in]targetQubitqubit to rotate
[in]angleangle by which to rotate the target qubit in radians
Exceptions
invalidQuESTInputError()
  • if either controlQubit or targetQubit are outside [0, qureg.numQubitsRepresented)
  • if controlQubit and targetQubit are equal
Author
Tyson Jones

Referenced by TEST_CASE().

◆ controlledRotateY()

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.

The target qubit is rotated in states where the control qubit has value 1.

Parameters
[in,out]quregobject representing the set of all qubits
[in]controlQubitqubit which has value 1 in the rotated states
[in]targetQubitqubit to rotate
[in]angleangle by which to rotate the target qubit in radians
Exceptions
invalidQuESTInputError()
  • if either controlQubit or targetQubit are outside [0, qureg.numQubitsRepresented)
  • if controlQubit and targetQubit are equal
Author
Tyson Jones

Referenced by TEST_CASE().

◆ controlledRotateZ()

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.

The target qubit is rotated in states where the control qubit has value 1.

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]controlQubitqubit which has value 1 in the rotated states
[in]targetQubitqubit to rotate
[in]angleangle by which to rotate the target qubit in radians
Exceptions
invalidQuESTInputError()
  • if either controlQubit or targetQubit are outside [0, qureg.numQubitsRepresented)
  • if controlQubit and targetQubit are equal
Author
Tyson Jones

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.

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]controlQubitthe control qubit which must be in state 1 to effect the given unitary
[in]targetQubit1first qubit to operate on, treated as least significant in u
[in]targetQubit2second qubit to operate on, treated as most significant in u
[in]uunitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if controlQubit, targetQubit1 or targetQubit2 are outside [0, qureg.numQubitsRepresented)
  • if any of controlQubit, targetQubit1 and targetQubit2 are equal
  • if matrix u is not unitary
    • if each node cannot fit 4 amplitudes in distributed mode.
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]controlQubitapply unitary if this qubit is 1
[in]targetQubitqubit to operate on
[in]usingle-qubit unitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if either controlQubit or targetQubit are outside [0, qureg.numQubitsRepresented)
  • if controlQubit and targetQubit are equal
  • if u is not unitary
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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()

See also
Parameters
[in,out]quregthe Qureg instance to operate upon
[in]targetsthe list of target qubit indices
[in]numTargetsthe length of list targets, which must match the dimension of op
[in]opa SubDiagonalOp initialised to be unitary
Exceptions
invalidQuESTInputError()
  • if numTargets does not match the size of op
  • if numTargets is invalid (<0 or larger than qureg)
  • if numTargets contains an invalid qubit index, or a repetition
  • if op is non-unitary
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]targetQubitqubit to operate on
Exceptions
invalidQuESTInputError()
  • if targetQubit is outside [0, qureg.numQubitsRepresented)
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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 in targs 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 and ctrls 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]qurega state-vector or density matrix to modify
[in]ctrlsa list of the control qubit indices
[in]numCtrlsthe length of list ctrls
[in]targsa list of the qubits to be targeted by the X gates
[in]numTargsthe length of list targs
Exceptions
invalidQuESTInputError()
  • if any qubit in ctrls and targs is invalid, i.e. outside [0, qureg.numQubitsRepresented)
  • if ctrls or targs contain any repetitions
  • if any qubit in ctrls is also in targs (and vice versa)
  • if numTargs < 1
  • if numCtrls < 1 (use multiQubitNot() for no controls)
segmentation-fault
  • if ctrls contains fewer elements than numCtrls
  • if targs contains fewer elements than numTargs
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]ctrlsa list of the control qubits
[in]numCtrlsthe number of control qubits
[in]targsa list of the target qubits, ordered least to most significant
[in]numTargsthe number of target qubits
[in]uunitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if any qubit in ctrls and targs is invalid, i.e. outside [0, qureg.numQubitsRepresented)
  • if ctrls or targs contain any repetitions
  • if any qubit in ctrls is also in targs (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 with numTargs
  • if a node cannot fit the required number of target amplitudes in distributed mode
segmentation-fault
  • if ctrls contains fewer elements than numCtrls
  • if targs contains fewer elements than numTargs
Author
Tyson Jones

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 and controlQubits 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);
pauliOpType
Codes for specifying Pauli operators.
Definition: QuEST.h:113
@ PAULI_Z
Definition: QuEST.h:113
@ PAULI_Y
Definition: QuEST.h:113
@ PAULI_I
Definition: QuEST.h:113
@ PAULI_X
Definition: QuEST.h:113
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:713

effects

\[ |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 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 all targetPaulis are identity, then this function does nothing to qureg. Specifying PAULI_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 or Y into alternate basis, performing multiControlledMultiRotateZ() on all target qubits, then restoring the original basis.

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]controlQubitslist of the indices of qubits to control upon
[in]numControlslength of length controlQubits
[in]targetQubitsa list of the indices of the target qubits
[in]targetPaulisa list of the Pauli operators around which to rotate the target qubits
[in]numTargetslength of list targetQubits
[in]anglethe angle by which the multi-qubit state is rotated around the Z axis
Exceptions
invalidQuESTInputError()
  • if any qubit in controlQubits and targetQubits is invalid, i.e. outside [0, qureg.numQubitsRepresented)
  • if controlQubits or targetQubits contain any repetitions
  • if any qubit in controlQubits is also in targetQubits (and vice versa)
  • if numTargets < 1
  • if numControls < 1 (use multiRotateZ() for no controls)
  • if any element of targetPaulis is not one of PAULI_I, PAULI_X, PAULI_Y, PAULI_Z
segmentation-fault
  • if controlQubits contains fewer elements than numControls
  • if targetQubits contains fewer elements than numTargets
  • if targetPaulis contains fewer elements than numTargets
Author
Tyson Jones

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 and controlQubits 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]quregobject representing the set of all qubits
[in]controlQubitslist of the indices of qubits to control upon
[in]numControlslength of length controlQubits
[in]targetQubitsa list of the indices of the target qubits
[in]numTargetslength of list targetQubits
[in]anglethe angle by which the multi-qubit state is rotated around the Z axis
Exceptions
invalidQuESTInputError()
  • if any qubit in controlQubits and targetQubits is invalid, i.e. outside [0, qureg.numQubitsRepresented)
  • if controlQubits or targetQubits contain any repetitions
  • if any qubit in controlQubits is also in targetQubits (and vice versa)
  • if numTargets < 1
  • if numControls < 1 (use multiRotateZ() for no controls)
segmentation-fault
  • if controlQubits contains fewer elements than numControls
  • if targetQubits contains fewer elements than numTargets
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]controlQubitsarray of input qubits
[in]numControlQubitsnumber 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
Author
Tyson Jones

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.

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]controlQubitsarray of qubits to phase shift
[in]numControlQubitsthe length of array controlQubits
[in]angleamount 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
Author
Tyson Jones

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.

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]controlQubitsthe control qubits which all must be in state 1 to effect the given unitary
[in]numControlQubitsthe number of control qubits
[in]targetQubit1first target qubit, treated as least significant in u
[in]targetQubit2second target qubit, treated as most significant in u
[in]uunitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if targetQubit1 or targetQubit2 are outside [0, qureg.numQubitsRepresented)
  • if targetQubit1 equals targetQubit2
  • if any qubit in controlQubits is outside [0, qureg.numQubitsRepresented)
  • if controlQubits are not unique
  • if either targetQubit1 and targetQubit2 are in controlQubits
  • if matrix u is not unitary
  • if each node cannot fit 4 amplitudes in distributed mode
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]controlQubitsapplies unitary if all qubits in this array equal 1
[in]numControlQubitsnumber of control qubits
[in]targetQubitqubit to operate on
[in]usingle-qubit unitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if numControlQubits is outside [1, qureg.numQubitsRepresented])
  • if any qubit index (targetQubit or one in controlQubits) is outside [0, qureg.numQubitsRepresented])
  • if any qubit in controlQubits is repeated
  • if controlQubits contains targetQubit
  • if u is not unitary
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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 in targs 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().

See also
Parameters
[in,out]qurega state-vector or density matrix to modify
[in]targsa list of the qubits to be targeted by the X gates
[in]numTargsthe 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 than numTargs
Author
Tyson Jones

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,

multiQubitUnitary(qureg, (int []) {a, b, c}, 3, u);
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 qubit...
Definition: QuEST.c:304

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]quregobject representing the set of all qubits
[in]targsa list of the target qubits, ordered least significant to most in u
[in]numTargsthe number of target qubits
[in]uunitary 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 with numTargs
  • if a node cannot fit the required number of target amplitudes in distributed mode
Author
Tyson Jones

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:

multiRotatePauli(qureg, (int[]) {4,5,8,9}, (int[]) {0,1,2,3}, 4, .1)
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 qubit...
Definition: QuEST.c:693

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 all targetPaulis are identity, then this function does nothing to qureg. Specifying PAULI_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]quregobject representing the set of all qubits
[in]targetQubitsa list of the indices of the target qubits
[in]targetPaulisa list of the Pauli operators (pauliOpType) to apply to the corresponding qubits in targetQubits
[in]numTargetsnumber of target qubits, i.e. the length of targetQubits and targetPaulis
[in]anglethe 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 of PAULI_I, PAULI_X, PAULI_Y, PAULI_Z
segmentation-fault
  • if targetQubits contains fewer elements than numTargets
  • if targetPaulis contains fewer elements than numTargets
Author
Tyson Jones

Referenced by TEST_CASE().

◆ multiRotateZ()

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.

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.

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]qubitsa list of the indices of the target qubits
[in]numQubitsnumber of target qubits
[in]anglethe 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 than numQubits
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]controlQubitsthe indices of the control qubits
[in]controlStatethe bit values (0 or 1) of each control qubit, upon which to condition
[in]numControlQubitsnumber of control qubits
[in]targetQubitqubit to operate the unitary upon
[in]usingle-qubit unitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if numControlQubits is outside [1, qureg.numQubitsRepresented])
  • if any qubit index (targetQubit or one in controlQubits) is outside [0, qureg.numQubitsRepresented]),
  • if any qubit in controlQubits is repeated
  • if controlQubits contains targetQubit
  • if any element of controlState is not a bit (0 or 1)
  • if u is not unitary
Author
Tyson Jones

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:

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]targetQubitqubit to operate on
Exceptions
invalidQuESTInputError()
  • if targetQubit is outside [0, qureg.numQubitsRepresented)
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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:

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]targetQubitqubit to operate on
Exceptions
invalidQuESTInputError()
  • if targetQubit is outside [0, qureg.numQubitsRepresented)
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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:

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]targetQubitqubit to operate on
Exceptions
invalidQuESTInputError()
  • if targetQubit is outside [0, qureg.numQubitsRepresented)
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

Referenced by TEST_CASE().

◆ phaseShift()

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.

‍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

See also
Parameters
[in,out]quregobject representing the set of all qubits
[in]targetQubitqubit to undergo a phase shift
[in]angleamount by which to shift the phase in radians
Exceptions
invalidQuESTInputError()
  • targetQubit is outside [0, qureg.numQubitsRepresented).
Author
Tyson Jones

Referenced by TEST_CASE().

◆ rotateAroundAxis()

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.


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]quregobject representing the set of all qubits
[in]rotQubitqubit to rotate
[in]angleangle by which to rotate in radians
[in]axisvector 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
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

Referenced by TEST_CASE().

◆ rotateX()

void rotateX ( Qureg  qureg,
int  rotQubit,
qreal  angle 
)

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]quregobject representing the set of all qubits
[in]rotQubitqubit to rotate
[in]angleangle by which to rotate in radians
Exceptions
invalidQuESTInputError()
  • if rotQubit is outside [0, qureg.numQubitsRepresented)
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

Referenced by TEST_CASE().

◆ rotateY()

void rotateY ( Qureg  qureg,
int  rotQubit,
qreal  angle 
)

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]quregobject representing the set of all qubits
[in]rotQubitqubit to rotate
[in]angleangle by which to rotate in radians
Exceptions
invalidQuESTInputErrorif rotQubit is outside [0, qureg.numQubitsRepresented).
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc, debug)

Referenced by TEST_CASE().

◆ rotateZ()

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).


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]quregobject representing the set of all qubits
[in]rotQubitqubit to rotate
[in]angleangle by which to rotate in radians
Exceptions
invalidQuESTInputError()
  • if rotQubit is outside [0, qureg.numQubitsRepresented)
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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]quregobject representing the set of all qubits
[in]targetQubitqubit to operate upon
Exceptions
invalidQuESTInputError()
  • if targetQubit is outside [0, qureg.numQubitsRepresented)
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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]quregobject representing the set of all qubits
[in]qb1qubit to sqrt swap
[in]qb2other qubit to sqrt swap
Exceptions
invalidQuESTInputError()
  • if either qubit1 or qubit2 are outside [0, qureg.numQubitsRepresented)
  • if qubit1 and qubit2 are equal
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]qubit1qubit to swap
[in]qubit2other qubit to swap
Exceptions
invalidQuESTInputError()
  • if either qubit1 or qubit2 are outside [0, qureg.numQubitsRepresented)
  • if qubit1 and qubit2 are equal
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]targetQubitqubit to operate upon
Exceptions
invalidQuESTInputError()
  • if targetQubit is outside [0, qureg.numQubitsRepresented)
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

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,

twoQubitUnitary(qureg, a, b, u);
void twoQubitUnitary(Qureg qureg, int targetQubit1, int targetQubit2, ComplexMatrix4 u)
Apply a general two-qubit unitary (including a global phase factor).
Definition: QuEST.c:264

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]quregobject representing the set of all qubits
[in]targetQubit1first qubit to operate on, treated as least significant in u
[in]targetQubit2second qubit to operate on, treated as most significant in u
[in]uunitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if targetQubit1 or targetQubit2 are outside [0, qureg.numQubitsRepresented)
  • if targetQubit1 equals targetQubit2
  • if matrix u is not unitary
  • if each node cannot fit 4 amplitudes in distributed mode
Author
Tyson Jones

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]quregobject representing the set of all qubits
[in]targetQubitqubit to operate on
[in]uunitary matrix to apply
Exceptions
invalidQuESTInputError()
  • if targetQubit is outside [0, qureg.numQubitsRepresented)
  • if matrix u is not unitary
Author
Ania Brown (state-vector)
Tyson Jones (density matrix, doc)

Referenced by TEST_CASE().