Gates Module

This section documents the quforge.gates module which contains functions and classes for quantum gates.

class quforge.gates.CCNOT(index=[0, 1, 2], dim=2, wires=3, inverse=False, device='cpu')[source]

Bases: Module

CCNOT (Toffoli) Gate for qudits.

The CCNOT gate (or Toffoli gate) is a controlled-controlled NOT gate that flips the target qudit if both control qudits are in the specified states. For qudits, this gate is generalized to perform a modular arithmetic operation on the target: if the control qudits are in states (|c_1rangle) and (|c_2rangle), and the target qudit is in state (|trangle), then

\[|c_1\, c_2\, t\rangle \to |c_1\, c_2\, ((c_1 \times c_2) + t) \mod d_t\rangle,\]

where (d_t) is the dimension of the target qudit.

Arguments:
index (list of int): The indices of the control and target qudits, where the first two entries are the

control qudits and the third is the target qudit. Default is [0, 1, 2].

dim (int or list of int): The dimension of the qudits. If an integer is provided, all qudits are assumed to have that

dimension; if a list is provided, each element specifies the dimension of the corresponding qudit.

wires (int): The total number of qudits. Default is 3. inverse (bool): Whether to apply the inverse of the CCNOT gate. Default is False. device (str): The device on which computations are performed. Default is ‘cpu’.

Attributes:

index (list of int): The indices of the control and target qudits. dim (list of int): The dimension of each qudit. U (torch.Tensor): The matrix representation of the CCNOT gate. inverse (bool): Whether the gate is inverted.

Examples:
>>> import quforge.quforge as qf
>>> gate = qf.CCNOT(index=[0, 1, 2], dim=2, wires=3)
>>> state = qf.State('1-1-0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # For multidimensional qudits, e.g. if the first two qudits are 3-dimensional and the target is 2-dimensional:
>>> gate = qf.CCNOT(index=[0, 1, 2], dim=[3,3,2], wires=3)
>>> state = qf.State('1-2-0', dim=[3,3,2])
>>> result = gate(state)
>>> print(result)
forward(x)[source]

Apply the CCNOT gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor of the qudits.

Returns:

The resulting state after applying the CCNOT gate.

Return type:

torch.Tensor

matrix()[source]

Retrieve the full matrix representation of the CCNOT gate.

Returns:

The unitary matrix representing the CCNOT gate.

Return type:

torch.Tensor

training: bool
class quforge.gates.CNOT(index=[0, 1], wires=2, dim=2, device='cpu', sparse=False, inverse=False)[source]

Bases: Module

Controlled-NOT (CNOT) Gate for qudits.

The CNOT gate is a controlled gate where the target qudit is shifted based on the state of the control qudit. For qubits (2-level systems), the standard CNOT is recovered. For higher-dimensional qudits, if the control qudit is in state (|crangle) and the target qudit is in state (|trangle), the target is updated to (|(t + c) mod d_trangle), where (d_t) is the dimension of the target qudit.

Arguments:
index (list of int): The indices of the control and target qudits, where index[0] is the control

and index[1] is the target. Default is [0, 1].

wires (int): The total number of qudits in the circuit. Default is 2. dim (int or list of int): The dimension(s) of the qudits. If an integer, all qudits have that dimension.

If a list, each element corresponds to the dimension of a qudit.

device (str): The device on which computations are performed. Default is ‘cpu’. sparse (bool): Whether to use a sparse matrix representation. Default is False. inverse (bool): Whether to apply the inverse of the CNOT gate. Default is False.

Attributes:

index (list of int): The indices of the control and target qudits. dim (int or list of int): The dimension(s) of the qudits. U (torch.Tensor): The matrix representation of the CNOT gate. inverse (bool): Whether the matrix is inverted.

Examples:
>>> # Uniform qudit case (e.g. qubits)
>>> gate = qf.CNOT(index=[0,1], wires=2, dim=2)
>>> state = qf.State('0-0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits: first qudit (control) is a qubit (dim=2) and second (target) is a qutrit (dim=3)
>>> gate = CNOT(index=[0,1], wires=2, dim=[2,3])
>>> state = State('1-2', dim=[2,3])
>>> result = gate(state)
>>> print(result)
forward(x)[source]

Apply the CNOT gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor of the qudits.

Returns:

The resulting state after applying the CNOT gate.

Return type:

torch.Tensor

matrix()[source]

Retrieve the unitary matrix representing the CNOT gate.

Returns:

The unitary matrix representing the CNOT gate.

Return type:

torch.Tensor

training: bool
class quforge.gates.CRX(index=[0, 1], dim=2, wires=2, j=0, k=1, device='cpu', sparse=False)[source]

Bases: Module

Controlled-RX Gate for qudits.

The CRX gate applies an RX (rotation-X) operation on the target qudit, conditioned on the state of the control qudit. For qudits, if the control qudit (at index index[0]) is in a given state, the RX rotation (by an angle (theta)) is applied on the target qudit (at index index[1]), where the rotation affects only the subspace spanned by the levels (j) and (k).

Arguments:

index (list of int): The indices of the control and target qudits. Default is [0, 1]. dim (int or list of int): The dimension(s) of the qudits. If an integer, all qudits are assumed to have that dimension. wires (int): The total number of qudits in the circuit. Default is 2. j (int): The first target level for the RX rotation. Default is 0. k (int): The second target level for the RX rotation. Default is 1. device (str): The device to perform computations on. Default is ‘cpu’. sparse (bool): Whether to use a sparse matrix representation. Default is False.

Attributes:

index (list of int): The indices of the control and target qudits. dim (list of int): The list of dimensions of the qudits. j, k (int): The levels (0-indexed) on the target qudit that define the RX rotation subspace. angle (torch.nn.Parameter): A learnable rotation angle parameter. wires (int): Total number of qudits. sparse (bool): Whether a sparse matrix representation is used.

Examples:
>>> # Uniform qudit case (e.g., qubits)
>>> gate = CRX(index=[0, 1], dim=2, wires=2, j=0, k=1)
>>> state = State('0-0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits: for instance, first qudit is a qutrit (dim=3) and second is a qubit (dim=2).
>>> # Here, we want to apply the controlled RX rotation on the target qudit's subspace between levels 0 and 1.
>>> gate = CRX(index=[0, 1], dim=[3,2], wires=2, j=0, k=1, device='cpu')
>>> state = State('1-0', dim=[3,2])
>>> result = gate(state)
>>> print(result)
forward(x, param=False)[source]

Apply the CRX gate to the qudit state.

Parameters:
  • x (torch.Tensor) – The input state tensor (a column vector) whose dimension equals the product of the individual qudit dimensions.

  • param (torch.Tensor or bool) – If False, use the internal angle; otherwise, use the provided angle.

Returns:

The resulting state after applying the CRX gate.

Return type:

torch.Tensor

matrix(param=False)[source]

Construct and return the full matrix representation of the CRY gate.

Parameters:

param (torch.Tensor or bool) – If False, use the internal angle parameter (self.angle); otherwise, use the provided tensor as the rotation angle.

Returns:

The dense unitary matrix representing the CRY gate.

Return type:

torch.Tensor

training: bool
class quforge.gates.CRY(index=[0, 1], dim=2, wires=2, j=0, k=1, device='cpu', sparse=False)[source]

Bases: Module

Controlled-RY Gate for qudits.

The CRY gate applies an RY (rotation-Y) operation on the target qudit, conditioned on the state of the control qudit. For qudits, if the control qudit (at index index[0]) is in a given state, then an RY rotation (by angle (theta)) is applied on the target qudit (at index index[1]). The rotation acts nontrivially only on the two-dimensional subspace spanned by levels (j) and (k) of the target.

Arguments:

index (list of int): The indices of the control and target qudits. Default is [0, 1]. dim (int or list of int): The dimension(s) of the qudits. If an integer, all qudits are assumed to have that

dimension; if a list, each element specifies the dimension of the corresponding qudit.

wires (int): The total number of qudits in the circuit. Default is 2. j (int): The first target level for the RY rotation (0-indexed). Default is 0. k (int): The second target level for the RY rotation (0-indexed). Default is 1. device (str): The device for computations. Default is ‘cpu’. sparse (bool): Whether to use a sparse matrix representation. Default is False.

Attributes:

index (list of int): The indices of the control and target qudits. dim (list of int): The dimensions of the qudits. angle (torch.nn.Parameter): The learnable rotation angle. wires (int): The total number of qudits. sparse (bool): Whether a sparse matrix is used.

Examples:
>>> # Single dimensional qudit case (e.g. qubits)
>>> gate = qf.CRY(index=[0,1], dim=2, wires=2, j=0, k=1)
>>> state = qf.State('0-0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits: first qudit is a qutrit (dim=3) and second is a qubit (dim=2)
>>> gate = qf.CRY(index=[0,1], dim=[3,2], wires=2, j=0, k=1, device='cpu')
>>> state = qf.State('1-0', dim=[3,2])
>>> result = gate(state)
>>> print(result)
forward(x, param=False)[source]

Apply the CRY gate to the qudit state.

Parameters:
  • x (torch.Tensor) – The input state (a column vector) whose dimension equals the product of the individual qudit dimensions.

  • param (torch.Tensor or bool) – If False, use the internal angle; otherwise, use the provided angle.

Returns:

The state after applying the CRY gate.

Return type:

torch.Tensor

matrix(param=False)[source]

Construct and return the full matrix representation of the CRY gate.

Parameters:

param (torch.Tensor or bool) – If False, use the internal angle parameter (self.angle); otherwise, use the provided tensor as the rotation angle.

Returns:

The dense unitary matrix representing the CRY gate.

Return type:

torch.Tensor

training: bool
class quforge.gates.CRZ(index=[0, 1], dim=2, wires=2, j=1, device='cpu', sparse=False)[source]

Bases: Module

Controlled-RZ Gate for qudits.

The CRZ gate applies an RZ (rotation-Z) operation on the target qudit, conditioned on the state of the control qudit. For qubits, this recovers the standard controlled-RZ. For qudits, if the control qudit (at index index[0]) is in a given state, then the target qudit (at index index[1]) is phase-shifted. The phase shift is applied only to the target qudit’s basis elements according to a function of the control value.

Arguments:

index (list of int): The indices of the control and target qudits, where index[0] is the control. dim (int or list of int): The dimension(s) of the qudits. If an integer, all qudits have that dimension. wires (int): The total number of qudits in the circuit. Default is 2. (If dim is a list, wires is taken as len(dim).) j (int): The target level on the target qudit where a different phase is applied. Default is 1. device (str): The device on which computations are performed. Default is ‘cpu’. sparse (bool): Whether to use a sparse matrix representation. Default is False.

Attributes:

index (list of int): The indices of the control and target qudits. dim (int or list of int): The dimension(s) of the qudits. angle (torch.nn.Parameter): The learnable rotation angle. wires (int): The total number of qudits. sparse (bool): Whether a sparse matrix is used.

Examples:
>>> # Single dimensional qudit case (qubits)
>>> gate = qf.CRZ(index=[0, 1], dim=2, wires=2, j=1)
>>> state = qf.State('0-0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits: e.g. first qudit has dim 3 and second dim 2.
>>> gate = qf.CRZ(index=[0, 1], dim=[3,2], wires=2, j=1, device='cpu')
>>> state = qf.State('0-0', dim=[3,2])
>>> result = gate(state)
>>> print(result)
forward(x)[source]

Apply the CRZ gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor (column vector) whose dimension equals the product of the individual qudit dimensions.

Returns:

The resulting state after applying the CRZ gate.

Return type:

torch.Tensor

matrix(param=False)[source]

Construct and return the full matrix representation of the CRZ gate.

Parameters:

param (torch.Tensor or bool) – If False, use the internal angle parameter (self.angle); otherwise, use the provided tensor as the rotation angle.

Returns:

The dense unitary matrix representing the CRZ gate.

Return type:

torch.Tensor

training: bool
class quforge.gates.CU(dim=2, wires=2, device='cpu', index=[0, 1], matrix=None, control_dim=None)[source]

Bases: Module

Controlled-Unitary (CU) Gate for qudits with configurable control branches.

This gate applies a different unitary on a target subsystem depending on the state of a control qudit. The qudits affected by this gate are specified by a single list index, where the first element is the control qudit and the remaining elements are the target qudits. For a control qudit with dimension (d_c), the ideal operation is:

\[\mathrm{CU} = \sum_{k=0}^{d_c-1} |k\rangle\langle k| \otimes U_k.\]

With the new flag control_dim, the user specifies which control state(s) trigger a nontrivial unitary on the target subsystem. For control states not in control_dim the gate acts as the identity.

There are two modes:

  1. Random (Learnable) Mode (`matrix=None`): For each control state in control_dim, a learnable parameter (of shape ((d_{target}, d_{target}))) is defined. Its skew-Hermitian part is exponentiated to yield a unitary. Control states not in control_dim use the identity block.

    For example, with qubits and:

  2. Custom Matrix Mode (when `matrix` is provided): The user must supply the active unitary blocks for the control states in control_dim. These can be provided as either a list of matrices, a 3D tensor (with first dimension equal to len(control_dim)), or a 2D tensor that packs the blocks. Blocks for control states not in control_dim are taken as identity.

Arguments:
dim (int or list of int): The dimension of each qudit. If an integer, all qudits are assumed to have that

dimension; if a list, each element specifies the dimension of the corresponding qudit.

wires (int): The total number of qudits in the system (used only when dim is an integer). device (str): The device on which computations are performed. index (list of int): A list specifying which qudits the gate acts on. The first element is the control qudit,

and the remaining elements are the target qudits.

matrix (torch.Tensor or list or None): If provided, a custom unitary is used for the active branches.

See discussion above.

control_dim (int or list of int or None): Specifies the control state(s) for which the gate applies the active

unitary. For control states not in this list, the identity is used. If not provided, a default is chosen: for qubits, the default is [1]; for higher dimensions, the default is [d_control - 1].

Examples:
>>> # Error: index must contain at least one control and one target.
>>> U = CU(dim=2, wires=3, index=[0])  # Raises an error.
>>>
>>> # For a 3-qudit system with control qudit 0 and target qudit 1,
>>> # using random parameters and default control_dim (for qubits, [1]):
>>> U = CU(dim=2, wires=3, index=[0,1])
>>>
>>> # For a 3-qudit system with control qudit 0 and target qudit 1,
>>> # but with identity applied on control state |1> (i.e. active unitary on state |0>):
>>> U = CU(dim=2, wires=3, index=[0,1], control_dim=[0])
>>>
>>> # For a 3-qudit system with control qudit 1 and target qudit 0,
>>> # with custom unitary blocks provided as a list (for control states in control_dim).
>>> custom_blocks = [torch.eye(2, dtype=torch.complex64), 0.5*torch.eye(2, dtype=torch.complex64)]
>>> U = CU(dim=2, wires=3, index=[1,0], control_dim=[0,1], matrix=custom_blocks)
forward(x)[source]

Define the computation performed at every call.

Should be overridden by all subclasses.

Note

Although the recipe for forward pass needs to be defined within this function, one should call the Module instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.

matrix()[source]

Retrieve the full unitary matrix representation of the CU gate.

training: bool
class quforge.gates.CZ(index=[0, 1], dim=2, wires=2, device='cpu')[source]

Bases: Module

Controlled-Z (CZ) Gate for qudits.

The CZ gate applies a Z operation on the target qudit if the control qudit is in a specific state. For qubits, it recovers the standard controlled-Z behavior. For qudits, the gate is defined such that if the control qudit (at index index[0]) is in state (|crangle) and the target qudit (at index index[1]) is in state (|trangle), then the target qudit is acted upon by a Z rotation:

\[|c,t\rangle \to \left(|c\rangle\langle c| \otimes Z_t(c)\right)|c,t\rangle,\]

where the target qudit receives a phase shift determined by (c). In our implementation, for each possible control state (c), we construct the operator

\[u_c = \bigotimes_{i=0}^{wires-1} U_i,\]
with
  • (U_i =) the projector (|c\rangle\langle c|) on the control qudit (if (i = index[0])),

  • (U_i =) the Z gate (Z(s=c)) on the target qudit (if (i = index[1])), and

  • (U_i = I) for all other qudits.

The full CZ operator is then obtained by summing (u_c) over all control states.

Arguments:
index (list of int): The indices of the control and target qudits, where index[0] is the control

and index[1] is the target. Default is [0, 1].

dim (int or list of int): The dimension of the qudits. If an integer, all qudits are assumed to have that

dimension; if a list, each element specifies the dimension of the corresponding qudit.

wires (int): The total number of qudits in the circuit. Default is 2. (If dim is a list, wires is set to len(dim).) device (str): The device to perform the computations on. Default is ‘cpu’.

Attributes:

index (list of int): The indices of the control and target qudits. dim (int or list of int): The dimension(s) of the qudits. U (torch.Tensor): The matrix representation of the CZ gate.

Examples:
>>> # Single dimensional qudit case (e.g., qubits):
>>> gate = qf.CZ(index=[0, 1], dim=2, wires=2)
>>> state = qf.State('0-0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits:
>>> # For instance, first qudit is a qutrit (dim=3) and second is a qubit (dim=2)
>>> gate = qf.CZ(index=[0, 1], dim=[3,2])
>>> state = qf.State('1-0', dim=[3,2])
>>> result = gate(state)
>>> print(result)
forward(x)[source]

Apply the CZ gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor of the qudits.

Returns:

The resulting state after applying the CZ gate.

Return type:

torch.Tensor

matrix()[source]

Retrieve the unitary matrix representing the CZ gate.

Returns:

The unitary matrix representing the CZ gate.

Return type:

torch.Tensor

training: bool
class quforge.gates.H(dim=2, index=[0], wires=1, inverse=False, device='cpu')[source]

Bases: Module

Hadamard Gate for qudits.

The Hadamard gate creates a superposition of states in a qudit system.

Matrix Representation:

For a qudit of dimension D, the Hadamard gate is defined as

\[\begin{split}H = \frac{1}{\sqrt{D}} \begin{pmatrix} 1 & 1 & \cdots & 1 \\\\ 1 & \omega & \cdots & \omega^{D-1} \\\\ 1 & \omega^2 & \cdots & \omega^{2(D-1)} \\\\ \vdots & \vdots & \ddots & \vdots \\\\ 1 & \omega^{D-1} & \cdots & \omega^{(D-1)(D-1)} \end{pmatrix}\end{split}\]

where

\[\omega = \exp\left(\frac{2\pi i}{D}\right).\]
Arguments:
dim (int or list of int):

The dimension of the qudit(s). If an integer is provided, all qudits are assumed to have that dimension. If a list is provided, each element corresponds to the dimension of the corresponding qudit.

index (list of int):

The indices of the qudits to which the gate is applied.

wires (int): The total number of qudits in the circuit. Default is 1. inverse (bool):

Whether to apply the inverse of the Hadamard gate. Default is False.

device (str):

The device on which computations are performed. Default is ‘cpu’.

Attributes:

index (list of int): The indices of the qudits on which the gate is applied. device (str): The device on which computations are performed. dim (int or list of int): The qudit dimension(s). M_dict (dict): A dictionary mapping each target qudit index to its Hadamard matrix.

Examples:
>>> # Uniform qudit dimensions (e.g., 3 qubits):
>>> gate = qf.H(dim=2, index=[0])
>>> psi = qf.State('0-1-0', dim=2)  # three-qubit state
>>> result = gate(psi)
>>> print(result)
>>> # Multidimensional qudits (e.g., first qubit is a qubit and second is a qutrit):
>>> gate = qf.H(dim=[2,3], index=[1], device='cpu')
>>> psi = qf.State('1-2', dim=[2,3])
>>> result = gate(psi)
>>> print(result)
forward(x)[source]

Apply the Hadamard gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor. It is assumed that x is a column vector whose dimension is the product of the individual qudit dimensions.

Returns:

The resulting state after applying the Hadamard gate.

Return type:

torch.Tensor

matrix()[source]

Construct and return the overall unitary matrix corresponding to the Hadamard gate.

Returns:

The complete unitary operator representing the Hadamard gate applied

on the specified qudits, with dimensions matching the product of individual qudit dimensions.

Return type:

torch.Tensor

training: bool
class quforge.gates.MCX(index=[0, 1], dim=2, wires=2, inverse=False, device='cpu')[source]

Bases: Module

Multi-Controlled CX Gate for qudits.

The MCX gate applies a controlled-X operation where multiple control qudits are used to control a target qudit. For qubits (2-level systems) this recovers the standard controlled-X gate. For qudits, if the control qudits are in states (|c_1rangle, |c_2rangle, dots, |c_{n-1}rangle) and the target qudit is in state (|trangle), then the target is updated as

\[|c_1, c_2, \dots, c_{n-1}, t\rangle \to |c_1, c_2, \dots, c_{n-1}, (c_1 \cdot c_2 \cdots c_{n-1} + t) \mod d_t\rangle,\]

where (d_t) is the dimension of the target qudit.

Arguments:
index (list of int): The indices of the control and target qudits. The last element is the target qudit,

and the preceding indices are the control qudits. Default is [0, 1].

dim (int or list of int): The dimension of the qudits. If an integer, all qudits are assumed to have that

dimension; if a list, each element specifies the dimension of the corresponding qudit.

wires (int): The total number of qudits. Default is 2. inverse (bool): Whether to apply the inverse of the MCX gate. Default is False. device (str): The device on which computations are performed. Default is ‘cpu’.

Attributes:

index (list of int): The indices of the control and target qudits. dim (list of int): The dimension of each qudit. U (torch.Tensor): The matrix representation of the MCX gate. inverse (bool): Whether the gate is inverted.

Examples:
>>> import quforge.quforge as qf
>>> # Single dimensional qudit case (e.g. qubits)
>>> gate = qf.MCX(index=[0, 1], dim=2, wires=2)
>>> state = qf.State('0-0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits: for example, first qudit is 3-dimensional and second is 2-dimensional.
>>> gate = qf.MCX(index=[0, 1], dim=[3, 2], wires=2, device='cpu')
>>> state = qf.State('1-0', dim=[3, 2])
>>> result = gate(state)
>>> print(result)
forward(x)[source]

Apply the MCX gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor of the qudits.

Returns:

The resulting state after applying the MCX gate.

Return type:

torch.Tensor

matrix()[source]

Retrieve the full matrix representation of the MCX gate.

Returns:

The unitary matrix representing the MCX gate.

Return type:

torch.Tensor

training: bool
class quforge.gates.RX(j=0, k=1, index=[0], dim=2, wires=1, device='cpu', angle=None, sparse=False)[source]

Bases: Module

Rotation-X (RX) Gate for qudits.

The RX gate represents a rotation about the X-axis of the Bloch sphere in a qudit system. For a qubit (2-level system), the matrix representation is given by

\[\begin{split}RX(\theta) = \begin{pmatrix} \cos(\theta/2) & -i\sin(\theta/2) \\ -i\sin(\theta/2) & \cos(\theta/2) \end{pmatrix}\end{split}\]

For higher-dimensional qudits, the RX gate affects only the specified two levels (indexed by (j) and (k)), leaving all other levels unchanged.

Arguments:
j (int or list of int):

The first level to rotate between. If an integer is provided, it is applied to all target qudits.

k (int or list of int):

The second level to rotate between. If an integer is provided, it is applied to all target qudits.

index (list of int):

The indices of the qudits to which the RX gate is applied.

dim (int or list of int):

The dimension of the qudit. If an integer is provided, all qudits are assumed to have that dimension. If a list is provided, each element specifies the dimension of the corresponding qudit.

wires (int):

The total number of qudits in the circuit. (Used when dim is an integer.)

device (str):

The device on which computations are performed. Default is ‘cpu’.

angle (float or torch.Tensor or None):

The rotation angle. If None, create a random parameter, if float or torch.Tensor, use it directly.

sparse (bool):

Whether to use a sparse matrix representation. Default is False.

Attributes:

j, k: The target levels for rotation (stored per qudit in a mapping if needed). index (list of int): The indices of the qudits to which the gate is applied. angle (torch.nn.Parameter or torch.Tensor): The rotation angle(s) for each qudit. sparse (bool): Whether the matrix representation is sparse. dim (int or list of int): The dimension(s) of the qudit(s).

Examples:
>>> # Single dimensional qudit (qubit) case:
>>> gate = qf.RX(index=[0])
>>> state = qf.State('0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits: for example, first qudit is a qubit and second is a qutrit.
>>> # Here, we want to rotate between levels 1 and 0 for the first qudit and between levels 1 and 2 for the second.
>>> gate = qf.RX(index=[0,1], dim=[2,3], j=[1,1], k=[0,2], device='cpu')
>>> state = qf.State('1-2', dim=[2,3])
>>> result = gate(state)
>>> print(result)
forward(x, param=None)[source]

Apply the RX gate to the qudit state.

Parameters:
  • x (torch.Tensor) – The input state tensor (a column vector) whose dimension is the product of the individual qudit dimensions.

  • param (torch.Tensor or bool) – If None, use the internal angle parameter. If provided, use it as the rotation angle.

Returns:

The resulting state after applying the RX gate.

Return type:

torch.Tensor

matrix(param=None)[source]

Construct and return the overall unitary operator representing the RX gate applied to the specified qudits in the circuit.

The rotation angle used for each target qudit is taken from the internal parameter self.angle unless an alternative angle is provided via the param argument.

Parameters:

param (list or bool) – If None, the method uses the internal angle parameter for each qudit. If a list is provided, its elements override the corresponding entries in self.angle for the rotation angles.

Returns:

The complete unitary operator (as a torch.Tensor) representing the RX gate

applied to the qudit state.

Return type:

torch.Tensor

training: bool
class quforge.gates.RY(j=0, k=1, index=[0], dim=2, wires=1, device='cpu', angle=None, sparse=False)[source]

Bases: Module

Rotation-Y (RY) Gate for qudits.

The RY gate represents a rotation around the Y-axis of the Bloch sphere in a qudit system. For a qubit (2-level system), the matrix representation is given by

\[\begin{split}RY(\theta) = \begin{pmatrix} \cos(\theta/2) & -\sin(\theta/2) \\ \sin(\theta/2) & \cos(\theta/2) \end{pmatrix}\end{split}\]

For higher-dimensional qudits, the RY gate acts only on the specified two levels (indexed by (j) and (k)), leaving all other levels unchanged.

Arguments:
j (int or list of int):

The first level to rotate between. If an integer is provided, it is applied to all target qudits.

k (int or list of int):

The second level to rotate between. If an integer is provided, it is applied to all target qudits.

index (list of int):

The indices of the qudits to which the RY gate is applied.

dim (int or list of int):

The dimension of the qudit. If an integer is provided, all qudits are assumed to have that dimension. If a list is provided, each element specifies the dimension of the corresponding qudit.

wires (int):

The total number of qudits in the circuit (used when dim is an integer).

device (str):

The device on which computations are performed. Default is ‘cpu’.

angle (float or torch.Tensor or None):

The rotation angle. If None, create a random parameter, if float or torch.Tensor, use it directly.

sparse (bool):

Whether to use a sparse matrix representation. Default is False.

Attributes:

j, k: The target levels for rotation (stored per target qudit in mappings). index (list of int): The indices of the qudits to which the gate is applied. angle (torch.nn.Parameter): The rotation angle(s) for each qudit. sparse (bool): Whether the matrix representation is sparse. dim (int or list of int): The dimension(s) of the qudit(s).

Examples:
>>> # Single dimension qudit (qubit) case:
>>> gate = RY(index=[0])
>>> state = qf.State('0', dim=2)
>>> result = qf.gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits:
>>> # For example, first qudit is a qubit and second is a qutrit.
>>> # Here, we want to rotate between levels 0 and 1 on the first qudit,
>>> # and between levels 1 and 2 on the second qudit.
>>> gate = qf.RY(index=[0,1], dim=[2,3], j=[0,1], k=[1,2], device='cpu')
>>> state = qf.State('0-2', dim=[2,3])
>>> result = gate(state)
>>> print(result)
forward(x, param=None)[source]

Apply the RY gate to the qudit state.

Parameters:
  • x (torch.Tensor) – The input state tensor (a column vector) whose dimension is the product of the individual qudit dimensions.

  • param (torch.Tensor or bool) – If None, use the internal angle parameter; if provided, use it as the rotation angle.

Returns:

The resulting state after applying the RY gate.

Return type:

torch.Tensor

matrix(param=None)[source]

Construct and return the overall unitary operator representing the RY gate applied to the specified qudits in the circuit.

The rotation angle used for each target qudit is taken from the internal parameter self.angle unless an alternative angle is provided via the param argument.

Parameters:

param (list or bool) – If None, the method uses the internal angle parameter for each qudit. If a list is provided, its elements override the corresponding entries in self.angle for the rotation angles.

Returns:

The complete unitary operator (as a torch.Tensor) representing the RY gate

applied to the qudit state.

Return type:

torch.Tensor

training: bool
class quforge.gates.RZ(j=1, index=[0], dim=2, wires=1, device='cpu', angle=None, sparse=False)[source]

Bases: Module

Rotation-Z (RZ) Gate for qudits.

The RZ gate represents a rotation around the Z-axis of the Bloch sphere in a qudit system. For a qubit (2-level system), the matrix representation is given by

\[\begin{split}RZ(\theta) = \begin{pmatrix} e^{-i\theta/2} & 0 \\ 0 & e^{i\theta/2} \end{pmatrix}\end{split}\]

For higher-dimensional qudits, the gate affects only the specified level (j) (i.e. multiplies the (j)th basis vector by a phase (e^{itheta})) while leaving the other levels unchanged.

Arguments:
j (int or list of int):

The level to which the phase rotation is applied. If an integer is provided, it is applied to all target qudits.

index (list of int):

The indices of the qudits to which the RZ gate is applied.

dim (int or list of int):

The dimension of the qudit. If an integer is provided, all qudits are assumed to have that dimension. If a list is provided, each element specifies the dimension of the corresponding qudit.

wires (int):

The total number of qudits in the circuit (used when dim is an integer).

device (str):

The device on which computations are performed. Default is ‘cpu’.

angle (float or torch.Tensor or None):

The rotation angle. If None, create a random parameter, if float or torch.Tensor, use it directly.

sparse (bool):

Whether to use a sparse matrix representation. Default is False.

Attributes:

j: The target level for the phase rotation (stored per target qudit in a mapping). index (list of int): The indices of the qudits to which the gate is applied. angle (torch.nn.Parameter): The rotation angle(s) for each qudit. sparse (bool): Whether the matrix representation is sparse. dim (int or list of int): The dimension(s) of the qudit(s).

Examples:
>>> # Single dimensional qudit (qubit) case:
>>> gate = qf.RZ(index=[0])
>>> state = qf.State('0', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits:
>>> # For example, if the first qudit is a qubit and the second is a qutrit,
>>> # and we wish to apply the phase rotation only to level 1 of each,
>>> # then:
>>> gate = qf.RZ(index=[0,1], dim=[2,3], j=[1,1], device='cpu')
>>> state = qf.State('0-2', dim=[2,3])
>>> result = gate(state)
>>> print(result)
forward(x, param=None)[source]

Apply the RZ gate to the qudit state.

Parameters:
  • x (torch.Tensor) – The input state tensor (a column vector) whose dimension is the product of the individual qudit dimensions.

  • param (torch.Tensor or bool) – If None, use the internal angle parameter; if provided, use it as the rotation angle.

Returns:

The resulting state after applying the RZ gate.

Return type:

torch.Tensor

matrix(param=None)[source]

Construct and return the overall unitary operator representing the RZ gate applied to the specified qudits in the circuit.

The rotation angle used for each target qudit is taken from the internal parameter self.angle unless an alternative angle is provided via the param argument.

Parameters:

param (list or bool) – If None, the method uses the internal angle parameter for each qudit. If a list is provided, its elements override the corresponding entries in self.angle for the rotation angles.

Returns:

The complete unitary operator (as a torch.Tensor) representing the RZ gate

applied to the qudit state.

Return type:

torch.Tensor

training: bool
class quforge.gates.SWAP(index=[0, 1], dim=2, wires=2, device='cpu')[source]

Bases: Module

SWAP Gate for qudits.

The SWAP gate exchanges the states of two qudits, generalizing the SWAP gate for qubits to higher-dimensional systems. When using multidimensional qudits, the total Hilbert space dimension is given by the product of the individual qudit dimensions.

Details:

For a qubit system (2-level qudits), the SWAP gate is represented as:

\[\begin{split}SWAP = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}\end{split}\]

For qudits, the gate exchanges the states of the two qudits specified by their indices.

Arguments:

index (list of int): The indices of the two qudits to be swapped. Default is [0, 1]. dim (int or list of int): The dimension of the qudits. If an integer is provided, all qudits have that dimension.

If a list is provided, each element specifies the dimension of the corresponding qudit.

wires (int): The total number of qudits in the circuit. Default is 2. (If dim is a list, wires is taken as len(dim).) device (str): The device on which the computations are performed. Default is ‘cpu’.

Attributes:

index (list of int): The indices of the qudits to be swapped. dim (int or list of int): The dimension(s) of the qudits. U (torch.Tensor): The matrix representation of the SWAP gate.

Examples:
>>> # Single dimensional qudit case (e.g. qubits)
>>> gate = qf.SWAP(index=[0,1], dim=2, wires=2)
>>> state = qf.State('0-1', dim=2)
>>> result = gate(state)
>>> print(result)
>>>
>>> # Multidimensional qudits: first qudit is a qubit (dim=2) and second is a qutrit (dim=3)
>>> gate = qf.SWAP(index=[0,1], dim=[2,3])
>>> state = qf.State('0-2', dim=[2,3])
>>> result = gate(state)
>>> print(result)
forward(x)[source]

Apply the SWAP gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor of the qudits.

Returns:

The resulting state after applying the SWAP gate.

Return type:

torch.Tensor

matrix()[source]

Retrieve the unitary matrix representing the SWAP gate.

Returns:

The unitary matrix representing the SWAP gate.

Return type:

torch.Tensor

training: bool
class quforge.gates.U(matrix=None, dim=2, wires=1, device='cpu', index=None)[source]

Bases: Module

Random or Custom Unitary Gate for qudits.

This gate can either apply a user-provided unitary matrix or, if no matrix is provided, generate a random unitary operator on the Hilbert space of a set of qudits. The gate can be applied on the entire system or on a specified subset of qudits via the index flag.

Arguments:
matrix (torch.Tensor or None): The custom unitary matrix to be applied as the gate.

If None (default), a random unitary is generated (via a random parameter that is exponentiated to produce a unitary).

dim (int or list of int): The dimension(s) of the qudits. If an integer is provided, all qudits

are assumed to have that dimension; if a list is provided, each element specifies the dimension of a corresponding qudit.

wires (int): The total number of qudits in the circuit (used only when dim is an integer). device (str): The device on which computations are performed (e.g. ‘cpu’ or ‘cuda’). index (int, list of int, or None): The index/indices of the qudit(s) on which to apply the gate.

If None, the gate acts on the entire system. For a single index, an integer can be provided. For a subset, provide a list of indices.

Examples:
>>> # Full-system custom gate (acting on 3 qudits, each with dimension 2)
>>> custom_matrix = torch.tensor(np.eye(2**3), dtype=torch.complex64)
>>> gate = U(matrix=custom_matrix, dim=2, wires=3, device='cpu')
>>> state = ...  # some state of dimension 2**3
>>> result = gate(state)
>>>
>>> # Full-system random gate (acting on 3 qudits, each with dimension 2)
>>> gate = U(matrix=None, dim=2, wires=3, device='cpu')
>>>
>>> # Custom gate acting only on qudits 0 and 2 of a 3-qudit system
>>> custom_matrix = torch.tensor(np.eye(2*2), dtype=torch.complex64)  # 4x4 matrix
>>> gate = U(matrix=custom_matrix, dim=2, wires=3, index=[0,2], device='cpu')
>>>
>>> # Random gate acting only on qudits 1 and 2 of a 3-qudit system
>>> gate = U(matrix=None, dim=2, wires=3, index=[1,2], device='cpu')
forward(x)[source]

Apply the unitary gate to the state x.

Parameters:

x (torch.Tensor) – The input state vector (as a column vector) with dimension equal to the product of the individual qudit dimensions.

Returns:

The transformed state vector.

Return type:

torch.Tensor

matrix()[source]

Construct and return the full unitary matrix representation of the gate.

Returns:

The full unitary matrix.

Return type:

torch.Tensor

training: bool
class quforge.gates.X(s=1, dim=2, wires=1, index=[0], device='cpu', inverse=False)[source]

Bases: Module

Generalized Pauli-X (X) Gate for qudits.

The X gate represents a cyclic shift of the computational basis states in a qudit system, generalizing the Pauli-X gate from qubits to higher dimensions.

Matrix Representation:

For a qubit (2-level qudit), the Pauli-X gate is represented as:

\[\begin{split}X = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}\end{split}\]

For a higher-dimensional qudit, the X gate shifts the basis states by a cyclic parameter ( s ) as follows. Given a qudit of dimension ( D ), its matrix elements are defined by

\[X_{j,i} = \langle j |X| i \rangle = \langle j | (i+s) \rangle,\]

where the addition is modulo ( D ).

Arguments:
s (int):

The cyclic shift parameter for the qudit. Default is 1.

dim (int or list of int):

The dimension of the qudit. If an integer, all qudits are assumed to have that dimension. If a list is provided, each element corresponds to the dimension of the respective qudit.

wires (int): The total number of qudits in the circuit. Default is 1. index (list of int):

The indices of the qudits to which the gate is applied.

device (str):

The device on which the computations are performed. Default is ‘cpu’.

inverse (bool):

Whether to apply the inverse of the X gate. Default is False.

Attributes:
index (list of int):

The indices of the qudits to which the gate is applied.

dim (int or list of int):

The dimension(s) of the qudit(s).

M or M_dict (torch.Tensor or dict):

The matrix representation of the X gate (for uniform dimensions) or a dictionary mapping each target qudit index to its corresponding X gate (for multidimensional qudits).

inverse (bool):

Whether the matrix representation is inverted.

Examples:
>>> # Uniform qudit dimensions (e.g., 3 qubits):
>>> gate = qf.X(s=1, dim=2, index=[0])
>>> psi = qf.State('0-1-0', dim=2)  # three-qubit state
>>> result = gate(psi)
>>> print(result)
>>> # Multidimensional qudits (e.g., first qudit is a qubit and second is a qutrit):
>>> gate = qf.X(s=1, dim=[2,3], index=[1], device='cpu')
>>> psi = qf.State('0-2', dim=[2,3])
>>> result = gate(psi)
>>> print(result)
forward(x)[source]

Apply the X gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor of the qudit. It is assumed to be a column vector whose dimension is the product of the individual qudit dimensions.

Returns:

The resulting state after applying the X gate.

Return type:

torch.Tensor

matrix()[source]

Construct and return the overall unitary matrix corresponding to the X gate.

Returns:

The complete unitary operator representing the X gate applied

on the specified qudits, with dimensions matching the product of individual qudit dimensions.

Return type:

torch.Tensor

training: bool
class quforge.gates.Y(s=1, dim=2, wires=1, index=[0], device='cpu')[source]

Bases: Module

Generalized Pauli-Y (Y) Gate for qudits.

The Y gate represents a combination of the X and Z gates, generalizing the Pauli-Y gate from qubits to higher dimensions. It is defined as

\[Y = \frac{1}{i}\, Z \cdot X,\]

where the generalized Pauli-X and Pauli-Z gates are applied to the target qudits.

Arguments:
s (int):

The cyclic shift parameter for the X gate. Default is 1.

dim (int or list of int):

The dimension of the qudit. If an integer, all qudits are assumed to have that dimension. If a list is provided, each element corresponds to the dimension of the respective qudit.

wires (int): The total number of qudits in the circuit. Default is 1. index (list of int):

The indices of the qudits to which the gate is applied.

device (str):

The device on which the computations are performed. Default is ‘cpu’.

Attributes:
index (list of int):

The indices of the qudits on which the gate is applied.

dim (int or list of int):

The qudit dimension(s).

M (torch.Tensor) or M_dict (dict):

For uniform dimensions, M stores the matrix representation of the Y gate. For multidimensional qudits, M_dict maps each target qudit index to its corresponding Y gate matrix.

Examples:
>>> # Uniform qudit dimensions (e.g., 3 qubits):
>>> gate = qf.Y(dim=2, index=[0])
>>> psi = qf.State('0-1-0', dim=2)  # three-qubit state
>>> result = gate(psi)
>>> print(result)
>>> # Multidimensional qudits (e.g., first qudit is a qubit and second is a qutrit):
>>> gate = qf.Y(dim=[2,3], index=[1], device='cpu')
>>> psi = qf.State('0-2', dim=[2,3])
>>> result = gate(psi)
>>> print(result)
forward(x)[source]

Apply the Y gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor of the qudit. It is assumed to be a column vector whose dimension is the product of the individual qudit dimensions.

Returns:

The resulting state after applying the Y gate.

Return type:

torch.Tensor

matrix()[source]

Construct and return the overall unitary matrix corresponding to the Y gate.

Returns:

The complete unitary operator representing the Y gate applied

on the specified qudits, with dimensions matching the product of individual qudit dimensions.

Return type:

torch.Tensor

training: bool
class quforge.gates.Z(dim=2, wires=1, s=1, index=[0], device='cpu', inverse=False)[source]

Bases: Module

Generalized Pauli-Z (Z) Gate for qudits.

The Z gate applies a phase shift to the computational basis states in a qudit system, generalizing the Pauli-Z gate from qubits to higher dimensions.

Matrix Representation:

For a qubit (2-level qudit), the Pauli-Z gate is represented as:

\[\begin{split}Z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}\end{split}\]

For a higher-dimensional qudit, the Z gate applies a phase shift based on a complex exponential. For a qudit of dimension ( D ) with phase parameter ( s ), the matrix is:

\[Z_s = \text{diag}(1, \omega^s, \omega^{2s}, \ldots, \omega^{(D-1)s})\]

where ( omega = exp(2pi i / D) ).

Arguments:
dim (int or list of int):

The dimension of the qudit. If an integer, all qudits are assumed to have that dimension. If a list is provided, each element corresponds to the dimension of the respective qudit.

wires (int): The total number of qudits in the circuit. Default is 1. s (int):

The phase shift parameter for the qudit. Default is 1.

index (list of int):

The indices of the qudits to which the gate is applied.

device (str):

The device on which computations are performed. Default is ‘cpu’.

inverse (bool):

Whether to apply the inverse of the Z gate. Default is False.

Attributes:
index (list of int):

The indices of the qudits to which the gate is applied.

dim (int or list of int):

The dimension(s) of the qudit(s).

M or M_dict (torch.Tensor or dict):

For uniform dimensions, M holds the matrix representation of the Z gate. For multidimensional qudits, M_dict is a dictionary mapping each target qudit index to its corresponding Z gate matrix.

inverse (bool):

Whether the matrix representation is inverted.

Examples:
>>> # Uniform qudit dimensions (e.g., 3 qubits):
>>> gate = qf.Z(dim=2, s=1, index=[0])
>>> psi = qf.State('0-1-0', dim=2)  # three-qubit state
>>> result = gate(psi)
>>> print(result)
>>> # Multidimensional qudits (e.g., first qudit is a qubit and second is a qutrit):
>>> gate = qf.Z(dim=[2,3], s=1, index=[1], device='cpu')
>>> psi = qf.State('0-2', dim=[2,3])
>>> result = gate(psi)
>>> print(result)
forward(x)[source]

Apply the Z gate to the qudit state.

Parameters:

x (torch.Tensor) – The input state tensor of the qudit. It is assumed to be a column vector whose dimension is the product of the individual qudit dimensions.

Returns:

The resulting state after applying the Z gate.

Return type:

torch.Tensor

matrix()[source]

Construct and return the overall unitary matrix corresponding to the Z gate.

Returns:

The complete unitary operator representing the Z gate applied

on the specified qudits, with dimensions matching the product of individual qudit dimensions.

Return type:

torch.Tensor

training: bool