QGate Module
This module contains the QGate class, which represents a quantum gate. It provides methods to easily create a gate from different representations (matrix, sequence, tuple) and to stock its information in an intuitive way. The class also contains methods to stock the decomposition of the gate, its initial representation and its error. Finally, the class provides a method to calculate the matrix representation of the gate from its sequence.
- Classes:
QGate: Class representing a quantum gate.
- class qdecomp.utils.qgate.QGate(name: str | None = None, target: tuple[int, ...] = (0,))[source]
Bases:
objectClass representing a quantum gate. It provides the user the ability to easily create and manipulate quantum gates. The gates can be defined either by their matrix, their sequence or a tuple. A Gate object contains the information about the qubit on which it acts, its control bit, if any, and its error if a sequence is used to approximate it. The class also provides a method to calculate the matrix representation of the gate from its sequence.
- Class methods to instantiate a QGate object:
from_matrix: Create a QGate object from a matrix.
from_sequence: Create a QGate object from a sequence.
from_tuple: Create a QGate object from a tuple.
- Parameters:
name (str | None) – Name of the gate.
num_qubits (int) – Number of qubits on which the gate applies.
sequence (str | None) – Sequence associated with the gate decomposition.
target (tuple[int]) – Qubits on which the gate acts.
init_matrix (np.ndarray | None) – Matrix used to initialize the gate.
sequence_matrix (np.ndarray | None) – Approximated matrix representation of the gate.
epsilon (float) – Tolerance for the gate.
- Methods to change the QGate representation:
to_tuple: Convert the gate to a tuple representation.
convert: Convert the gate by using a user-defined function.
set_decomposition: Set the decomposition of the gate. The decomposition might be an approximation of the initial gate stored in the init_matrix attribute.
calculate_seq_matrix: Calculate the matrix representation of the gate from its sequence.
Example
>>> import numpy as np >>> from qdecomp.utils import QGate # Create a gate from a sequence >>> g1 = QGate.from_sequence(sequence="CNOT", target=(1, 3)) >>> print(g1) Sequence: CNOT Target: (1, 3) # Create a gate from a matrix >>> g2 = QGate.from_matrix(matrix=np.diag([1, -1]), name="My_Z_Gate") >>> print(g2) Gate: My_Z_Gate Target: (0,) Init. matrix: [[ 1 0] [ 0 -1]] # Create a gate from a tuple >>> g3 = QGate.from_tuple(("H", (0, ), 0)) >>> print(g3) Sequence: H Target: (0,) # Get the matrix of a from_sequence() gate >>> gate = QGate.from_sequence(sequence="X Z Y", name="my_gate") >>> print("Name:", gate.name) Name: my_gate >>> print("Sequence:", gate.sequence) Sequence: X Z Y >>> print("Target:", gate.target) Target: (0,) >>> print("Matrix:\n", gate.sequence_matrix, "\n") Matrix: [[ 0.+1.j 0.+0.j] [-0.+0.j -0.+1.j]] # Set the approximation sequence of a gate >>> approx_gate = QGate.from_matrix(matrix=np.diag([1-0.001j, 1.j+0.001]), name="approx_my_gate") >>> approx_gate.set_decomposition("S", epsilon=0.01) >>> print("Name:", approx_gate.name) Name: approx_my_gate >>> print("Sequence:", approx_gate.sequence) Sequence: S >>> print("Initial matrix:\n", approx_gate.init_matrix) Initial matrix: [[1. -0.001j 0. +0.j ] [0. +0.j 0.001+1.j ]] >>> print("Matrix from sequence:\n", approx_gate.sequence_matrix) Matrix from sequence: [[1.+0.j 0.+0.j] [0.+0.j 0.+1.j]]
- __init__(name: str | None = None, target: tuple[int, ...] = (0,)) None[source]
Initialize the QGate object.
- Parameters:
name (str | None) – Name of the gate
target (tuple[int, ...]) – Qubits on which the gate applies.
- Raises:
ValueError – If the target qubits are not a tuple.
ValueError – If the target qubits are not integers.
ValueError – If the target qubits are not in ascending order.
- classmethod from_matrix(matrix: ndarray, name: str | None = None, target: tuple[int, ...] = (0,), epsilon: float | None = None) QGate[source]
Create a QGate object from a matrix.
- Parameters:
matrix (np.ndarray) – Matrix representation of the gate.
name (str | None) – Name of the gate.
target (tuple[int, ...]) – Qubits on which the gate applies.
epsilon (float | None) – Tolerance for the gate.
- Returns:
The QGate object.
- Return type:
- Raises:
ValueError – If the matrix is not unitary.
ValueError – If the number of rows of the matrix is not 2^num_of_qubits.
Example
>>> import numpy as np >>> from qdecomp.utils import QGate >>> gate = QGate.from_matrix(np.diag([1, 1j]), name="my_S_gate", target=(1, )) >>> print(gate) Gate: my_S_gate Target: (1,) Init. matrix: [[1.+0.j 0.+0.j] [0.+0.j 0.+1.j]]
- classmethod from_sequence(sequence: str, name: str | None = None, target: tuple[int, ...] = (0,)) QGate[source]
Create a QGate object from a sequence.
- Parameters:
sequence (str) – Sequence associated with the gate decomposition.
target (tuple[int, ...]) – Qubits on which the gate applies.
- Returns:
The QGate object.
- Return type:
Example
>>> from qdecomp.utils import QGate >>> h_gate = QGate.from_sequence("H", name="my_H_gate", target=(2, )) >>> print(h_gate) Gate: my_H_gate Sequence: H Target: (2,) >>> cx_gate = QGate.from_sequence("CNOT", name="my_CNOT_gate", target=(1, 3)) >>> print(cx_gate) Gate: my_CNOT_gate Sequence: CNOT Target: (1, 3)
- classmethod from_tuple(gate_tuple: tuple, name: str | None = None) QGate[source]
Create a QGate object from a tuple.
- Two tuple formats are allowed:
(sequence, target, epsilon)
(matrix, target, epsilon)
In the first case, the epsilon is discarded.
- Parameters:
gate_tuple (tuple) – Tuple representation of the gate.
- Returns:
The QGate object.
- Return type:
- Raises:
TypeError – If the first elements of the tuple is not a string or a np.ndarray.
ValueError – If the tuple does not contain three elements.
Example
>>> from qdecomp.utils import QGate # Create a QGate object from a sequence >>> init_gate = QGate.from_sequence("H", name="my_H_gate", target=(2, )) >>> print(init_gate) Gate: my_H_gate Sequence: H Target: (2,) # Get the tuple representation of the QGate object >>> tup = init_gate.to_tuple() >>> print(tup, "\n") ('H', (2,), 0) # Reconstruct the QGate object from the tuple >>> tup_gate = QGate.from_tuple(tup) >>> print(tup_gate) Sequence: H Target: (2,)
- property name: str | None
Get the name of the gate.
- Returns:
The name of the gate.
- Return type:
str | None
- property sequence: str | None
Get the sequence associated with the gate decomposition.
- Returns:
The sequence associated with the gate decomposition.
- Return type:
str | None
- property target: tuple[int]
Get the target qubit(s).
- Returns:
The target qubit(s).
- Return type:
tuple[int]
- property init_matrix: ndarray
Return the matrix used to initialize the gate.
- Returns:
Matrix representation of the initialization gate.
- Return type:
np.ndarray
- property sequence_matrix: ndarray
Get the matrix representation of the gate given by its sequence. If the gate is initialized with a matrix (obtained with the init_matrix property), and then its sequence is specified, the sequence matrix represents the matrix obtained by multiplying the gates in the sequence.
- Returns:
Approximated matrix representation of the gate.
- Return type:
np.ndarray
- property matrix: ndarray
Get a matrix representation of the gate. If the sequence is known, the matrix associated to the sequence is returned, as the sequence_matrix property does. If the sequence is not known, the matrix used to initialize the gate (accessed via the init_matrix property) is returned.
- Returns:
Matrix representation of the gate.
- Return type:
np.ndarray
- property num_qubits: int
Get the number of qubits on which the gate applies.
- Returns:
The number of qubits on which the gate applies.
- Return type:
int
- property epsilon: float | None
Get the tolerance for the gate.
- Returns:
The tolerance for the gate.
- Return type:
float | None
- to_tuple() tuple[source]
Convert the gate to a tuple representation.
- Returns:
The tuple representation of the gate.
- Return type:
tuple
- Raises:
ValueError – If the sequence is not initialized.
- set_decomposition(sequence: str, epsilon: float | None = None) None[source]
Set the decomposition of the gate. This decomposition doesn’t need to be exact. The error epsilon specifies the error made by approximating the initial gate by the sequence and the exact matrix representation is stored in the approx_matrix attribute.
- Parameters:
sequence (str) – The decomposition of the gate.
epsilon (float | None) – The tolerance for the gate. If None, the value of the epsilon attribute is used.
- Raises:
ValueError – If the sequence is already initialized.
ValueError – If the epsilon is not already initialized for the gate and not provided as an argument.