Correlated Noise Benchmarking - Noro-Official/OQS GitHub Wiki

Logical Error Rates under Correlated Noise

Quantum error correction assumes errors occur independently—but in physical systems, noise is often correlated across qubits, in time or space.

This page shows how to simulate correlated noise in OpenQStack and benchmark its impact on logical error rates, especially in small codes like the 3-qubit bit-flip code or larger surface codes.


What Is Correlated Noise?

Correlated noise affects multiple qubits simultaneously or exhibits temporal dependence.

Examples include:

  • Crosstalk: gate on Qubit 1 causes errors on Qubit 2
  • Shared control lines: environmental fluctuation affects all qubits
  • Spatial correlations: neighboring qubits flip together
  • Temporal drift: correlated phase errors across time steps

Standard error channels (e.g., depolarizing, bit-flip) assume i.i.d. noise, but real systems often violate this.


Step 1: Define a Correlated Noise Channel

Here's an example of a 2-qubit correlated X error channel:

from openqstack.qec import ErrorChannel, tensor
import numpy as np

class CorrelatedX(ErrorChannel):
    def __init__(self, p, n_qubits=3, targets=(0, 1)):
        super().__init__(n_qubits)
        self.p = p
        self.targets = targets

    def kraus_operators(self):
        I = np.eye(2)
        X = np.array([0, 1], [1, 0](/Noro-Official/OQS/wiki/0,-1],-[1,-0))
        K0 = np.sqrt(1 - self.p) * tensor(*[I]*self.n_qubits)
        
        ops = [I] * self.n_qubits
        for i in self.targets:
            ops[i] = X
        K1 = np.sqrt(self.p) * tensor(*ops)

        return [(K0, 1 - self.p), (K1, self.p)]

Step 2: Inject Correlated Noise

Replace the random bit-flip with your custom channel:

channel = CorrelatedX(p=0.1, n_qubits=3, targets=(0, 2))
noisy_state = channel(encoded_state)

Step 3: Measure Logical Error Rate

Use a benchmark loop like this:

def benchmark_correlated_noise(code, channel, psi, n_trials=1000):
    success = 0
    for _ in range(n_trials):
        encoded = code.encode(psi)
        noisy = channel(encoded)
        syndrome = code.measure_syndrome(noisy)
        recovered = code.recover(noisy, syndrome)
        decoded = code.decode(recovered)
        if np.allclose(np.abs(decoded), np.abs(psi), atol=1e-6):
            success += 1
    return success / n_trials

Step 4: Compare with Uncorrelated Noise

Try benchmarking under different noise types:

from openqstack.qec import BitFlipChannel

uncorrelated = BitFlipChannel(p=0.1, n_qubits=3, target_qubit=0)
correlated = CorrelatedX(p=0.1, n_qubits=3, targets=(0, 2))

psi = [1, 0]
rate_uncorr = benchmark_correlated_noise(code, uncorrelated, psi)
rate_corr = benchmark_correlated_noise(code, correlated, psi)

print(f"Uncorrelated Success: {rate_uncorr:.3f}")
print(f"Correlated Success:   {rate_corr:.3f}")

Step 5: Plot Logical Error Rate vs. Correlation Strength

import matplotlib.pyplot as plt

ps = np.linspace(0.0, 0.5, 20)
rates = []

for p in ps:
    channel = CorrelatedX(p=p, n_qubits=3, targets=(0, 1))
    r = benchmark_correlated_noise(BitFlipCode(), channel, [1, 0])
    rates.append(1 - r)  # logical error rate

plt.plot(ps, rates)
plt.xlabel("Correlation strength (p)")
plt.ylabel("Logical error rate")
plt.title("Effect of Correlated Noise on QEC")
plt.grid(True)
plt.show()

Why This Matters

Most QEC benchmarks assume uncorrelated, stochastic errors.
But real-world quantum systems exhibit:

  • Temperature-dependent cross-qubit noise
  • Spectator qubit influence
  • Pulse-based control artifacts

Surface codes and decoders must be re-evaluated under these conditions.


Future Directions

OpenQStack will support:

  • Time-correlated noise: temporal memory effects
  • Correlated Kraus channels: entangled or non-separable noise
  • Error map visualizations: syndrome maps with causality
  • Decoder benchmarking under realistic spatial-temporal noise

Related