NoisyCircuits.utils package
NoisyCircuits.utils.BuildQubitGateModel module
This module allows users to generate the noise operators for single qubit and two qubit gates from the noise model dictionary obtained from the the calibration data from IBM Hardware using the class BuildModel.
The module allows users to filter out noise instructions that have a certain user-defined probability of occurrance (called threshold). The output from the module are the noise operators for single and two qubit gates, the connectivity chart for the specified device and the error operators on the measurement operation.
The connectivity chart is created from the two qubit gate instruction set where the directionality and the connection between qubits in the hardware is considered. An example usage is as follows:
Example
>>> from NoisyCircuits.utils.BuildQubitGateModel import BuildModel
>>> model = BuildModel(noise_model=noise_model, num_qubits=num_qubits, num_cores=2, threshold=1e-6, basis_gates=[["sx"], ["cx"]], verbose=True)
>>> single_qubit_noise, two_qubit_noise, connectivity, measurement_noise = model.build_qubit_gate_model()
Additionally, it needs to be noted that the QuantumCircuit module automatically builds the noise model without the user requiring to call this in the script.
- class NoisyCircuits.utils.BuildQubitGateModel.BuildModel(noise_model: dict, num_qubits: int, num_cores: int = 2, threshold: float = 1e-12, basis_gates: list[list[str]] | None = None, verbose: bool = True)[source]
Bases:
objectModule that generates the noise operators for each gate on each qubit from the noise model.
- Parameters:
noise_model (dict) – The noise model to use. Provided as a JSON-ised dictionary.
num_qubits (int) – The number of qubits in the model.
num_cores (int, optional) – The number of cores to use for parallel processing. Defaults to 2.
threshold (float, optional) – The threshold for noise. Defaults to 1e-12.
basis_gates (list[list[str]]) – List of basis gates for single qubit and two qubit operators.
verbose (bool) – Flag to indicate whether logging is required or not. Defaults to True.
- Raises:
TypeError – If noise_model is not a dictionary or num_qubits is not an integer.
ValueError – If num_qubits is not a positive integer or threshold is not between 0 and 1.
TypeError – If num_cores is not an integer.
ValueError – If num_cores is not a positive integer, or greater than the number of available CPU cores.
TypeError – If threshold is not a float or int.
ValueError – If basis_gates is None or not a list of lists of strings.
- build_qubit_gate_model() tuple[dict, dict, dict, dict][source]
Builds the qubit gate model by extracting single-qubit and two-qubit gate errors from the noise model.
- Raises:
ValueError – If the noise model does not contain information regarding the specified basis gates.
- Returns:
A tuple containing the single-qubit gate error instructions, two-qubit gate error instructions, measurement error instructions and the connectivity map.
- Return type:
tuple[dict, dict, dict, dict]
NoisyCircuits.utils.CreateNoiseModel module
This module allows users to create a noise model from user provided calibration data in a CSV file format. The calibration data should include specific columns for qubit properties and gate errors. The class reads the calibration data, processes it, and constructs a noise model that can be used for quantum circuit simulations.
Alternatively, users can obtain the noise model from the calibration data of IBM Quantum Hardware using IBM Rest API. This class retrieves the calibration data of the specified backend and processes it to create the noise model in dictionary format.
See the documentation of the specific classes for more details on the expected format of the calibration data and the usage of the classes to create or obtain the noise model.
- class NoisyCircuits.utils.CreateNoiseModel.CreateNoiseModel(calibration_data_file: str, basis_gates: list[list[str]])[source]
Bases:
objectA class to create a noise model from user provided calibration data. The calibration data should be provided in a CSV file format with specific columns for qubit properties and gate errors. The class reads the calibration data, processes it, and constructs a noise model that can be used for quantum circuit simulations.
Additionally, the user must specify the basis gates for the quantum hardware in order to create the noise model. The basis gates must be provided in a list of lists format where the first list contains the single qubit basis gates and the second list contains the two qubit basis gates. For example, if the single qubit basis gates are “x”, “sx” and “rz” and the two qubit basis gate is “cz”, then the basis gates should be provided as [[“x”, “sx”, “rz”], [“cz”]].
The definition of the header in the CSV file (in table view) should be as follows:
Qubit
T1 (us)
T2 (us)
Prob meas 0 prep 1
Prob meas 1 prep 0
Single Qubit Gate Length (ns)
Single Qubit Basis Gate Error
Gate Length (ns)
Two Qubit Basis Gate Error
An example of the content of the CSV file (in table view) where the basis gates are [[“x”, “sx”], [“cz”]] is as follows:
Qubit
T1 (us)
T2 (us)
Prob meas 0 prep 1
Prob meas 1 prep 0
Single Qubit Gate Length (ns)
x Error
sx Error
Gate Length (ns)
cz Error
0
50.534
19.955
0.0789
0.1316
24
0.002118
0.002118
1:68
1:0.0207
1
153.049
144.814
0.0696
0.1243
24
0.00052
0.00052
2:68;0:68
2:0.00479;0:0.0207
For a better example of the content of the CSV file, please refer to the example CSV file provided in the NoisyCircuits repository within the noise_models directory.
- Parameters:
calibration_data_file (str) – The path to the CSV file containing the calibration data.
- Raises:
TypeError – Raised when the input arguements are not of the expected type. - calibration_data_file should be a string representing the path to the CSV file. - basis_gates should be a list of lists of strings representing the basis gates for the quantum hardware.
FileNotFoundError – If the specified CSV file is not found.
ValueError – If the CSV file does not contain the required columns or if the data is not in the expected format.
Example
>>> from NoisyCircuits.utils.CreateNoiseModel import CreateNoiseModel >>> calibration_file_path = "path/to/calibration_data.csv" >>> basis_gates = [["x", "sx", "rz"], ["cz"]] >>> noise_model = CreateNoiseModel(calibration_data_file=calibration_file_path, basis_gates=basis_gates).create_noise_model()
- class NoisyCircuits.utils.CreateNoiseModel.GetNoiseModel(backend_name: str, token: str, service_crn: str)[source]
Bases:
objectThis class allows the user to obtain the noise model from the calibration data of IBM Quantum Hardware using IBM Rest API. This class retreives the calibration data of the specified backend and processes it to create the noise model in dictionary format.
A valid IBM Quantum API token and CRN is required to access the calibration data of the backend.
- Parameters:
backend_name (str) – The name of the IBM Quantum backend.
token (str) – The IBM Quantum API token.
service_crn (str) – The CRN of the IBM Quantum service instance.
- Raises:
TypeError – If backend_name, token or service_crn is not a string.
ValueError – If there is an issue connecting to the IBM Quantum API or if the backend is not found in the user’s account.
Example
>>> from NoisyCircuits.utils.CreateNoiseModel import GetNoiseModel >>> backend_name = "ibm_perth" >>> token = "your_ibm_quantum_api_token" >>> service_crn = "your_ibm_quantum_service_crn" >>> noise_model_generator = GetNoiseModel(backend_name=backend_name, token=token, service_crn=service_crn) >>> noise_model = noise_model_generator.get_noise_model(save_csv=True, destination="path/to/save/csv", file_name="calibration_data.csv")
- get_noise_model(save_csv: bool = False, destination: str | None = None, file_name: str | None = None) dict[source]
Method to obtain the noise model in dictionary format from the calibration data of the specified backend.
- Parameters:
save_csv (bool, optional) – Flag to enable saving the converted calibration data as a CSV file. Defaults to False.
destination (str, optional) – The directory where the CSV file should be saved if required by the used. Defaults to None, in which case the file will be saved in the current working directory. Relevant only if save_csv is set to True.
file_name (str, optional) – The name of the CSV file to save the converted calibration data. Defaults to None, in which case the file will be saved with a computer generated name. Relevant only if save_csv is set to True.
- Returns:
The noise model of the specified backend in dictionary format.
- Return type:
dict
- Raises:
TypeError – If any of the input arguments are not of the expected type, an error is raised with a detailed message indicating the expected type for each argument.
NotADirectoryError – If the specified destination for saving the CSV file is not a valid directory, an error is raised with a detailed message indicating the issue with the provided destination path.
NoisyCircuits.utils.Decomposition module
This module provides the skeleton for users/developers to add custom decompositions for the different gates. This module only contains abstract classes and methods, providing error handling to the specific backend decomposition classes.
This module includes the following classes:
Decomposition - Abstract class that acts as a template to the specific QPU decompositions.
ShapeMismatchError - Execption handling for errors in dimensionality mismatch to the size of the unitary matrix to the applied qubits.
NonSquareMatrixError - Execption handling for errors where the unitary matrix is not of size (N,N)
NonUnitaryMatrixError - Execption handling for errors where the input matrix is not a unitary matrix.
- class NoisyCircuits.utils.Decomposition.Decomposition(num_qubits: int)[source]
Bases:
ABCAbstract base class for quantum circuit decomposition which defines the interface for various quantum gate operations for different QPUs with varying basis gates.
- Parameters:
num_qubits (int) – The number of qubits in the quantum circuit.
- abstract CRX(theta: int | float, control: int, target: int)[source]
Applies the CRX (Controlled RX) gate between two qubits. Effectively applies the unitary:
\[\begin{split}CRX(\theta, q_0, q_1) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \cos(\theta/2) & -i\sin(\theta/2) \\ 0 & 0 & -i\sin(\theta/2) & \cos(\theta/2) \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The rotation angle.
control (int) – The control qubit.
target (int) – The target qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If control/target is not an integer.
ValueError – If the control/target is out of range.
- abstract CRY(theta: int | float, control: int, target: int)[source]
Applies the CRY (Controlled RY) gate between two qubits. Effectively applies the unitary:
\[\begin{split}CRY(\theta, q_0, q_1) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \cos(\theta/2) & \sin(\theta/2) \\ 0 & 0 & \sin(\theta/2) & \cos(\theta/2) \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The rotation angle.
control (int) – The control qubit.
target (int) – The target qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If control/target is not an integer.
ValueError – If the control/target is out of range.
- abstract CRZ(theta: int | float, control: int, target: int)[source]
Applies the CRZ (Controlled RZ) gate between two qubits. Effectively applies the unitary:
\[\begin{split}CRZ(\theta, q_0, q_1) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & \exp(-i\theta/2) & 0 \\ 0 & 0 & 0 & \exp(i\theta/2) \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The rotation angle.
control (int) – The control qubit.
target (int) – The target qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If control/target is not an integer.
ValueError – If the control/target is out of range.
- abstract CX(control: int, target: int)[source]
Applies the CX (CNOT) gate between two qubits. Effectively applies the unitary:
\[\begin{split}CX(q_0, q_1) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \end{pmatrix}\end{split}\]- Parameters:
control (int) – The control qubit.
target (int) – The target qubit.
- Raises:
TypeError – If control/target is not an integer.
ValueError – If the control/target is out of range.
- abstract CY(control: int, target: int)[source]
Applies the CY gate between two qubits. Effectively applies the unitary:
\[\begin{split}CY(q_0, q_1) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & -i \\ 0 & 0 & i & 0 \end{pmatrix}\end{split}\]- Parameters:
control (int) – The control qubit.
target (int) – The target qubit.
- Raises:
TypeError – If control/target is not an integer.
ValueError – If the control/target is out of range.
- abstract CZ(control: int, target: int)[source]
Applies the CZ gate between two qubits. Effectively applies the unitary:
\[\begin{split}CZ(q_0, q_1) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & -1 \end{pmatrix}\end{split}\]- Parameters:
control (int) – The control qubit.
target (int) – The target qubit.
- Raises:
TypeError – If control/target is not an integer.
ValueError – If the control/target is out of range.
- abstract ECR(control: int, target: int)[source]
Applies the ECR (Echoed Cross Resonance) gate between two qubits. Effectively applies the unitary:
\[\begin{split}ECR(q_0, q_1) = \frac{1}{\sqrt{2}}\begin{pmatrix} 0 & 0 & 1 & i \\ 0 & 0 & i & 1 \\ 1 & -i & 0 & 0 \\ -i & 1 & 0 & 0 \end{pmatrix}\end{split}\]- Parameters:
control (int) – The control qubit.
target (int) – The target qubit.
- Raises:
TypeError – If control/target is not an integer.
ValueError – If control/target is out of range.
- abstract H(qubit: int)[source]
Applies the H gate which is a Hadamard gate. Effectively applies the unitary:
\[\begin{split}H = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix}\end{split}\]- Parameters:
qubit (int) – The target qubit.
- Raises:
TypeError – If qubit is not an integer.
ValueError – If the qubit is out of range.
- abstract RX(theta: int | float, qubit: int)[source]
Applies the RX gate which is a rotation around the X-axis by an angle of \(\theta\). Effectively applies the unitary:
\[\begin{split}RX(\theta) = \begin{pmatrix} \cos(\theta/2) & -i\sin(\theta/2) \\ -i\sin(\theta/2) & \cos(\theta/2) \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The rotation angle.
qubit (int) – The target qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If qubit is not an integer.
ValueError – If the qubit is out of range.
- abstract RXX(theta: int | float, qubit1: int, qubit2: int)[source]
Applies the RXX Coupling Gate (Ising XX) \(XX(\theta)\) which effectively applies the unitary:
\[\begin{split}XX(\theta) = \begin{pmatrix} \cos(\theta/2) & 0 & 0 & -i\sin(\theta/2) \\ 0 & \cos(\theta/2) & -i\sin(\theta/2) & 0 \\ 0 & -i\sin(\theta/2) & \cos(\theta/2) & 0 \\ -i\sin(\theta/2) & 0 & 0 & \cos(\theta/2) \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The angle of rotation.
qubit1 (int) – The first qubit.
qubit2 (int) – The second qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If qubit1/qubit2 is not an integer.
ValueError – If qubit1/qubit2 is out of range.
- abstract RY(theta: int | float, qubit: int)[source]
Applies the RY gate which is a rotation around the Y-axis by an angle of \(\theta\). Effectively applies the unitary:
\[\begin{split}RY(\theta) = \begin{pmatrix} \cos(\theta/2) & -\sin(\theta/2) \\ \sin(\theta/2) & \cos(\theta/2) \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The rotation angle.
qubit (int) – The target qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If qubit is not an integer.
ValueError – If the qubit is out of range.
- abstract RYY(theta: int | float, qubit1: int, qubit2: int)[source]
Applies the RYY Coupling Gate (Ising YY) \(YY(\theta)\) which effectively applies the unitary:
\[\begin{split}YY(\theta) = \begin{pmatrix} \cos(\theta/2) & 0 & 0 & i\sin(\theta/2) \\ 0 & \cos(\theta/2) & -i\sin(\theta/2) & 0 \\ 0 & -i\sin(\theta/2) & \cos(\theta/2) & 0 \\ i\sin(\theta/2) & 0 & 0 & \cos(\theta/2) \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The angle of rotation.
qubit1 (int) – The first qubit.
qubit2 (int) – The second qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If qubit1/qubit2 is not an integer.
ValueError – If qubit1/qubit2 is out of range.
- abstract RZ(theta: int | float, qubit: int)[source]
Applies the RZ gate which is a rotation around the Z-axis by an angle of \(\theta\). Effectively applies the unitary:
\[\begin{split}RZ(\theta) = \begin{pmatrix} e^{-i\theta/2} & 0 \\ 0 & e^{i\theta/2} \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The rotation angle.
qubit (int) – The target qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If qubit is not an integer.
ValueError – If qubit is out of range.
- abstract RZZ(theta: int | float, qubit1: int, qubit2: int)[source]
Applies the RZZ Coupling Gate (Ising ZZ) \(ZZ(\theta)\) which effectively applies the unitary:
\[\begin{split}ZZ(\theta) = \begin{pmatrix} \exp(-i\theta/2) & 0 & 0 & 0 \\ 0 & \exp(i\theta/2) & 0 & 0 \\ 0 & 0 & \exp(i\theta/2) & 0 \\ 0 & 0 & 0 & \exp(-i\theta/2) \end{pmatrix}\end{split}\]- Parameters:
theta (int | float) – The angle of rotation.
qubit1 (int) – The first qubit.
qubit2 (int) – The second qubit.
- Raises:
TypeError – If theta is not an integer or float.
TypeError – If qubit1/qubit2 is not an integer.
ValueError – If qubit1/qubit2 is out of range.
- abstract SWAP(qubit1: int, qubit2: int)[source]
Applies the SWAP gate between two qubits. Effectively applies the unitary:
\[\begin{split}SWAP(q_0, q_1) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}\end{split}\]- Parameters:
qubit1 (int) – The first qubit.
qubit2 (int) – The second qubit.
- Raises:
TypeError – If qubit1/qubit2 is not an integer.
ValueError – If qubit1/qubit2 is out of range.
- abstract SX(qubit: int)[source]
Applies the SX gate which is a square root of the X gate. Effectively applies the unitary:
\[\begin{split}SX = \frac{1}{2}\begin{pmatrix} 1+i & 1-i \\ 1-i & 1+i \end{pmatrix}\end{split}\]- Parameters:
qubit (int) – The target qubit.
- Raises:
TypeError – If qubit is not an integer.
ValueError – If qubit is out of range.
- abstract X(qubit: int)[source]
Applies the X gate which is a Pauli-X gate. Effectively applies the unitary:
\[\begin{split}X = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}\end{split}\]- Parameters:
qubit (int) – The target qubit.
- Raises:
TypeError – If qubit is not an integer.
ValueError – If qubit is out of range.
- abstract Y(qubit: int)[source]
Applies the Y gate which is a Pauli-Y gate. Effectively applies the unitary:
\[\begin{split}Y = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix}\end{split}\]- Parameters:
qubit (int) – The target qubit.
- Raises:
TypeError – If qubit is not an integer.
ValueError – If the qubit is out of range.
- abstract Z(qubit: int)[source]
Applies the Z gate which is a Pauli-Z gate. Effectively applies the unitary:
\[\begin{split}Z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}\end{split}\]- Parameters:
qubit (int) – The target qubit.
- Raises:
TypeError – If qubit is not an integer.
ValueError – If the qubit is out of range.
- abstract apply_swap_decomposition(qubit1: int, qubit2: int)[source]
Applies the SWAP decomposition to the circuit for every SWAP call.
- Parameters:
qubit1 (int) – The first qubit.
qubit2 (int) – The second qubit.
- Raises:
TypeError – If qubit1/qubit2 is not an integer.
ValueError – If qubit1/qubit2 is out of range.
- abstract apply_unitary(unitary_matrix: ndarray, qubits: list[int])[source]
Applies a unitary operation to the specified qubits.
- Parameters:
unitary_matrix (np.ndarray) – The unitary matrix to apply.
qubits (list[int]) – The list of qubits to which the unitary matrix will be applied.
- Raises:
TypeError – If unitary_matrix is not a numpy ndarray.
TypeError – If any qubit in the qubits list is not an integer or if qubits is not a list.
ValueError – If any qubit in the qubits list is out of range.
NonSquareMatrixError – If the unitary matrix is not square.
ShapeMismatchError – If the shape of the unitary matrix does not match the state of the qubits for the provided number of qubits.
NonUnitaryMatrixError – If the matrix is not unitary.
- exception NoisyCircuits.utils.Decomposition.NonSquareMatrixError[source]
Bases:
ExceptionException raised for errors in the shape of input arrays.