Skip to content

Commit 1389086

Browse files
mrossinekjenglick
andauthored
How-to guide for noisy circuit simulation using OBP (#85)
* docs: add a guide on how to simulate circuits using OBP * test: ensure PauliLindbladErrorInstruction._define is covered * docs: update the noisy expectation value computation This updates the how-to guide on simulating using OBP based on feedback I received offline. The most significant change is the update to the noisy expectation value computation section, which now resembles a workflow involving the `NoiseLearner` (and its returned result) more closely. * fix: ruff formatting * Apply suggestions from code review Co-authored-by: Jen Glick <41485571+jenglick@users.noreply.github.com> * docs: decrease fake noise model effect Prior to this commit, the random noise model that was being generated essentially killed the entire signal, resulting in a near-zero expectation value. This commit reduces the noise model coefficient scale to ensure that some signal remains, resulting in an expectation value ~85% of the noiseless one. --------- Co-authored-by: Jen Glick <41485571+jenglick@users.noreply.github.com>
1 parent 2b7b67b commit 1389086

File tree

3 files changed

+599
-1
lines changed

3 files changed

+599
-1
lines changed

docs/how_tos/simulating_circuits_with_obp.ipynb

Lines changed: 539 additions & 0 deletions
Large diffs are not rendered by default.

qiskit_addon_obp/utils/noise.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
from __future__ import annotations
1616

17-
from qiskit.circuit import Instruction
17+
import numpy as np
18+
from qiskit.circuit import Instruction, QuantumCircuit, QuantumRegister
19+
from qiskit.quantum_info import PauliList, SparsePauliOp, SuperOp
1820
from qiskit_ibm_runtime.utils.noise_learner_result import PauliLindbladError
1921

2022

@@ -42,3 +44,32 @@ def __init__(self, ple: PauliLindbladError):
4244
def ple(self) -> PauliLindbladError:
4345
"""Returns the internal Pauli-Lindblad error object."""
4446
return self._ple
47+
48+
def _define(self) -> None:
49+
# Implementation of Instruction._define which populates the definition attribute with a
50+
# QuantumCircuit-based representation of this instruction.
51+
52+
# This implementation is adapted from qiskit_aer.noise.PauliLindbladError
53+
chan_z = np.zeros((1, self.num_qubits), dtype=bool)
54+
chan_x = np.zeros_like(chan_z)
55+
chan_p = np.ones(1, dtype=float)
56+
for term_z, term_x, term_r in zip(
57+
self.ple.generators.z,
58+
self.ple.generators.x,
59+
self.ple.rates,
60+
):
61+
term_p = 0.5 - 0.5 * np.exp(-2 * term_r)
62+
chan_z = np.concatenate([chan_z, np.logical_xor(chan_z, term_z)], axis=0)
63+
chan_x = np.concatenate([chan_x, chan_x ^ term_x])
64+
chan_p = np.concatenate([(1 - term_p) * chan_p, term_p * chan_p])
65+
66+
error_op = SparsePauliOp(PauliList.from_symplectic(chan_z, chan_x), chan_p).simplify()
67+
chan = SuperOp(np.zeros(2 * [4**self.num_qubits]))
68+
for pauli, coeff in zip(error_op.paulis, error_op.coeffs.real):
69+
chan += coeff * SuperOp(pauli)
70+
71+
q = QuantumRegister(self.num_qubits, "q")
72+
qc = QuantumCircuit(q, name=self.name)
73+
qc.append(chan.to_instruction(), q)
74+
75+
self.definition = qc

test/utils/test_noise.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# This code is a Qiskit project.
2+
#
3+
# (C) Copyright IBM 2025.
4+
#
5+
# This code is licensed under the Apache License, Version 2.0. You may
6+
# obtain a copy of this license in the LICENSE.txt file in the root directory
7+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8+
#
9+
# Any modifications or derivative works of this code must retain this
10+
# copyright notice, and modified files need to carry a notice indicating
11+
# that they have been altered from the originals.
12+
13+
"""Tests the PauliLindbladError noise utilities."""
14+
15+
import unittest
16+
17+
from qiskit import QuantumCircuit
18+
from qiskit.quantum_info import PauliList
19+
from qiskit_addon_obp.utils.noise import PauliLindbladErrorInstruction
20+
from qiskit_ibm_runtime.utils.noise_learner_result import PauliLindbladError
21+
22+
23+
class TestPauliLindbladError(unittest.TestCase):
24+
def test_ple_definition(self):
25+
err = PauliLindbladError(PauliList(["XX", "XY", "ZX"]), [0.1, 0.2, 0.3])
26+
inst = PauliLindbladErrorInstruction(err)
27+
self.assertTrue(isinstance(inst.definition, QuantumCircuit))
28+
self.assertEqual(inst.definition.data[0].operation.name, "kraus")

0 commit comments

Comments
 (0)