Skip to content

Commit

Permalink
gate times test
Browse files Browse the repository at this point in the history
  • Loading branch information
obliviateandsurrender committed Jul 13, 2024
1 parent d2cfc4a commit 8d9e9ff
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 12 deletions.
43 changes: 32 additions & 11 deletions pennylane_qiskit/noise_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,17 +156,35 @@ def _process_kraus_ops(
def _extract_gate_time(gate_data: dict, gate_name: str, gate_wires: int) -> float:
"""Helper method to extract gate time for a quantum error"""
tg = 1.0
if fgates := dict(filter(lambda item: item[0][0] == gate_name, gate_data)):
for g_d, g_t in fgates.items():
g_d[1] = (g_d[1],) if isinstance(int, g_d[1]) else g_d[1]
if gate_wires in g_d:
if fgates := dict(filter(lambda item: item[0][0] == gate_name, gate_data.items())):
for (_, w_r), g_t in fgates.items():
if w_r in gate_wires if isinstance(w_r, int) else set(gate_wires).issubset(w_r):
tg = g_t
break
return tg


Check notice on line 166 in pennylane_qiskit/noise_models.py

View check run for this annotation

codefactor.io / CodeFactor

pennylane_qiskit/noise_models.py#L109-L166

Complex Method
def _process_thermal_relaxation(choi_matrix, **kwargs):
"""Computes parameters for thermal relaxation error from a Choi matrix of Kraus matrices"""
def _process_thermal_relaxation(choi_matrix, **kwargs) -> Tuple[bool, str, np.ndarray] or None:
r"""Computes the parameters for thermal relaxation error from a Choi matrix of Kraus matrices.
Args:
choi_matrix (ndarray): Choi matrix of the channel to be processed.
For plugin developers: This assumes :math:`T_1 < T_2 \leq 2 T_1`, where the error is expressed
as a general non-unitary Kraus error channel.
.. math::
\begin{bmatrix}
1 - p_e p_{r} & 0 & 0 & \exp{-T_g/T_2} \\
0 & p_e p_{r} & 0 & 0 \\
0 & 0 & (1 - p_e) p_{r} & 0 \\
\exp{-T_g/T_2} & 0 & 0 & 1 - (1 - p_e) p_{r}
\end{bmatrix}
Parameters :math:`p_e` is the excited-state population and :math:`p_r = 1 - \exp{-T_g/T_1}`
with :math:`T_g` as gate time and :math:`T_1\ (T_2)` as the relaxation (dephasing) constants.
"""
nt_values = choi_matrix[tuple(zip(*sorted(kraus_indice_map["ThermalRelaxation"])))]
decimals, atol, rtol = tuple(map(kwargs.get, default_option_map))

Expand Down Expand Up @@ -249,14 +267,17 @@ def _process_depolarization(error_dict: dict, multi_pauli: bool = False) -> dict


def _process_reset(error_dict: dict, **kwargs) -> dict:
"""Checks parity of a qunatum error with ``Reset`` instruction to a PennyLane Channel.
r"""Checks parity of a qunatum error with ``Reset`` instruction to a PennyLane Channel.
Args:
error_dict (dict): error dictionary for the quantum error
**kwargs: optional keyword arguments
Returns:
dict: An updated error dictionary based on parity with existing PennyLane channel.
For plugin developers: second branch of the condition assumes reset error expressed
from a thermal relaxation error with :math:`T_2 \leq T_1`.
"""
error_probs = error_dict["probs"]

Expand Down Expand Up @@ -351,7 +372,7 @@ def _build_qerror_op(error, **kwargs) -> qml.operation.Operation:
Args:
error (QuantumError): Quantum error object
kwargs: Optional keyword arguments used during conversion
kwargs: Optional keyword arguments used during conversion.
Returns:
qml.operation.Channel: converted PennyLane quantum channel which is
Expand Down Expand Up @@ -411,15 +432,15 @@ def _build_noise_model_map(noise_model, **kwargs) -> Tuple[dict, dict]:
Keyword Arguments:
thermal_relaxation (bool): prefer conversion of ``QiskitErrors`` to thermal relaxation errors
over damping errors. Default is ``False``.
readout_error (bool): include readout error in the converted noise model. Default is ``True``.
gate_times (Dict[Tuple(str, Tuple[int]), float]): a dictionary to provide gate times for building
thermal relaxation error. Each key will be a tuple of instruction name and qubit indices and
the corresponding value will be the time in seconds. If it is not provided or a gate/qubit
is missing, then a default value of `1.0 s`` will be used for the specific constructions.
multi_pauli (bool): assume depolarization channel to be multi-qubit. This is currently not
supported with ``qml.DepolarizationChannel``, which is a single qubit channel.
readout_error (bool): include readout error in the converted noise model. Default is ``True``.
optimize (bool): controls if a contraction order optimization is used for ``einsum`` while
transforming Kraus operators to a Choi matrix, wherever required. Default is ``False``.
multi_pauli (bool): assume depolarization channel to be multi-qubit. This is currently not
supported with ``qml.DepolarizationChannel``, which is a single qubit channel.
options (dict[str, Union[int, float]]): optional parameters related to tolerance and rounding:
- decimals (int): number of decimal places to round the Kraus matrices. Default is ``10``.
Expand Down
27 changes: 26 additions & 1 deletion tests/test_noise_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ def test_build_model_map(self, depol1, depol2, exc_pop):
error_2 = noise.depolarizing_error(depol2, 2)
error_3 = noise.phase_amplitude_damping_error(0.14, 0.24, excited_state_population=exc_pop)

# Add errors to noise model
noise_model = noise.NoiseModel()
noise_model.add_all_qubit_quantum_error(error_1, ["rz", "sx", "x"])
noise_model.add_all_qubit_quantum_error(error_2, ["cx"])
Expand All @@ -201,3 +200,29 @@ def test_build_model_map(self, depol1, depol2, exc_pop):
{AnyWires: ["CNOT"]},
{AnyWires: ["RY", "RX"]},
]

@pytest.mark.parametrize(
"gate_times",
[
{("sx", (0, 1)): 2.0, ("rx", (0,)): 2.5, ("rx", (1,)): 3.0},
{("sx", (0,)): 2.0, ("sx", (1,)): 2.5, ("rx", (0, 1)): 3.0},
],
)
def test_thermal_gate_times(self, gate_times):
"""Tests that a quantum error can be correctly converted into a PennyLane QubitChannel."""

pl_channels, pl_vals = [], []
noise_model = noise.NoiseModel()
for gate_wires, time in gate_times.items():
gate, wires = gate_wires
for wire in wires:
noise_model.add_quantum_error(
noise.thermal_relaxation_error(0.14, 0.24, time, 0.02), gate, (wire,)
)
pl_channels.append(qml.ThermalRelaxationError(0.02, 0.14, 0.24, time, wires=AnyWires))
pl_vals.append({(wire,): [gate.upper()] for wire in wires})

model_map, _ = _build_noise_model_map(noise_model, gate_times=gate_times)

assert list(model_map.keys()) == pl_channels
assert list(model_map.values()) == pl_vals

0 comments on commit 8d9e9ff

Please sign in to comment.