From 3cdf46b5359ded01406fc1cca2e99b24a740c765 Mon Sep 17 00:00:00 2001 From: ismoldayev <76691869+ismoldayev@users.noreply.github.com> Date: Thu, 18 Apr 2024 13:12:16 -0400 Subject: [PATCH] configure two gate noise in various code evaluation setups (#253) --------- Co-authored-by: Stefan Krastanov --- CHANGELOG.md | 1 + .../QuantumCliffordQuantikzExt.jl | 2 +- src/ecc/decoder_pipeline.jl | 38 ++++++++++++++++--- src/noise.jl | 8 ++-- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 666b0afec..75c4fd6a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ## v0.9.4 - dev +- Gate errors are now conveniently supported by the various ECC benchmark setups in the `ECC` module. - Remove printing of spurious debug info from the PyBP decoder. ## v0.9.3 - 2024-04-10 diff --git a/ext/QuantumCliffordQuantikzExt/QuantumCliffordQuantikzExt.jl b/ext/QuantumCliffordQuantikzExt/QuantumCliffordQuantikzExt.jl index 8f78f858b..f5d9ca858 100644 --- a/ext/QuantumCliffordQuantikzExt/QuantumCliffordQuantikzExt.jl +++ b/ext/QuantumCliffordQuantikzExt/QuantumCliffordQuantikzExt.jl @@ -71,7 +71,7 @@ function Quantikz.QuantikzOp(op::Reset) # TODO This is complicated because quant Quantikz.Initialize("$str",affectedqubits(op)) # TODO make Quantikz work with tuples and remove the collect end end -Quantikz.QuantikzOp(op::NoiseOp) = Quantikz.Noise(op.indices) +Quantikz.QuantikzOp(op::NoiseOp) = Quantikz.Noise(collect(op.indices)) Quantikz.QuantikzOp(op::NoiseOpAll) = Quantikz.NoiseAll() Quantikz.QuantikzOp(op::ClassicalXORConcreteWorkaround) = Quantikz.ClassicalDecision(sort([op.store, op.bits...])) diff --git a/src/ecc/decoder_pipeline.jl b/src/ecc/decoder_pipeline.jl index 1c9828b67..d1fbe897f 100644 --- a/src/ecc/decoder_pipeline.jl +++ b/src/ecc/decoder_pipeline.jl @@ -79,18 +79,46 @@ struct ShorSyndromeECCSetup <: AbstractECCSetup end end +function add_two_qubit_gate_noise(g, gate_error) + return () +end + +"""Applies gate_error to a given two-qubit gate g.""" +function add_two_qubit_gate_noise(g::AbstractTwoQubitOperator, gate_error) + qubits = affectedqubits(g) + return (PauliError(qubits, gate_error), ) +end + function physical_ECC_circuit(H, setup::NaiveSyndromeECCSetup) syndrome_circ, n_anc, syndrome_bits = naive_syndrome_circuit(H) - noisy_syndrome_circ = syndrome_circ # add_two_qubit_gate_noise(syndrome_circ, gate_error) - mem_error_circ = [PauliError(i, setup.mem_noise) for i in 1:nqubits(H)]; + noisy_syndrome_circ = [] + + for op in syndrome_circ + push!(noisy_syndrome_circ, op) + for noise_op in add_two_qubit_gate_noise(op, setup.two_qubit_gate_noise) + push!(noisy_syndrome_circ, noise_op) + end + end + + mem_error_circ = [PauliError(i, setup.mem_noise) for i in 1:nqubits(H)] circ = [mem_error_circ..., noisy_syndrome_circ...] - circ, syndrome_bits, n_anc + return circ, syndrome_bits, n_anc end + function physical_ECC_circuit(H, setup::ShorSyndromeECCSetup) prep_anc, syndrome_circ, n_anc, syndrome_bits = shor_syndrome_circuit(H) - noisy_syndrome_circ = syndrome_circ # add_two_qubit_gate_noise(syndrome_circ, gate_error) - mem_error_circ = [PauliError(i, setup.mem_noise) for i in 1:nqubits(H)]; + + noisy_syndrome_circ = [] + for op in syndrome_circ + push!(noisy_syndrome_circ, op) + for noise_op in add_two_qubit_gate_noise(op, setup.two_qubit_gate_noise) + push!(noisy_syndrome_circ, noise_op) + end + end + + mem_error_circ = [PauliError(i, setup.mem_noise) for i in 1:nqubits(H)] + circ = [prep_anc..., mem_error_circ..., noisy_syndrome_circ...] circ, syndrome_bits, n_anc end diff --git a/src/noise.jl b/src/noise.jl index fabc748c9..c4e7b095a 100644 --- a/src/noise.jl +++ b/src/noise.jl @@ -52,11 +52,13 @@ function applynoise!(s::AbstractStabilizer,noise::UnbiasedUncorrelatedNoise,i::I end """An operator that applies the given `noise` model to the qubits at the selected `indices`.""" -struct NoiseOp <: AbstractNoiseOp - noise::AbstractNoise - indices::AbstractVector{Int} +struct NoiseOp{N, Q} <: AbstractNoiseOp where {N, Q} + noise::N #<:AbstractNoise + indices::NTuple{Q, Int} end +NoiseOp(noise, indices::AbstractVector{Int}) = NoiseOp(noise, tuple(indices...)) + """A convenient constructor for various types of Pauli errors, that can be used as circuit gates in simulations. Returns more specific types when necessary."""