From 7da1f9c28b1f98940ca5ca1973cce55997b9426e Mon Sep 17 00:00:00 2001 From: Fe-r-oz Date: Sat, 7 Sep 2024 12:23:30 +0500 Subject: [PATCH] =?UTF-8?q?Bug=20fix=20to=20StackOverflowError=20for=20md?= =?UTF-8?q?=20=E2=8A=97=20SX=20where=20typeof(md)=20is=20MixedDestabilizer?= =?UTF-8?q?{...}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/linalg.jl | 70 ++++++++++++++++++++++++++++++++++++++++++++-- test/test_stabs.jl | 6 ++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/linalg.jl b/src/linalg.jl index 16b4eaf52..26a4a07e1 100644 --- a/src/linalg.jl +++ b/src/linalg.jl @@ -161,8 +161,10 @@ julia> tensor(s, s) See also [`tensor_pow`](@ref).""" function tensor end -function tensor(ops::AbstractStabilizer...) # TODO optimize this by doing conversion to common type to enable preallocation - foldl(⊗, ops[2:end], init=ops[1]) +function tensor(ops::AbstractStabilizer...) + ct = promote_type(map(typeof, ops)...) + conv_ops = map(x -> convert(ct, x), ops) + return foldl(⊗, conv_ops) end """Repeated tensor product of an operators or a tableau. @@ -264,3 +266,67 @@ function tensor(ops::CliffordOperator...) # TODO implement \otimes for Destabili end CliffordOperator(tab) end + +""" +Tensor product between [`MixedDestabilizer`](@ref) and [`Stabilizer`](@ref). + +```jldoctest +julia> md = MixedDestabilizer(T"Z//X", 1) +𝒟ℯ𝓈𝓉𝒶𝒷 ++ Z +𝒮𝓉𝒶𝒷 ++ X + +julia> md ⊗ S"X" +𝒟ℯ𝓈𝓉𝒶𝒷 ++ Z_ ++ _Z +𝒮𝓉𝒶𝒷 ++ X_ ++ _X + +julia> S"X" ⊗ md +𝒟ℯ𝓈𝓉𝒶𝒷 ++ Z_ ++ _Z +𝒮𝓉𝒶𝒷 ++ X_ ++ _X + +julia> S"X" ⊗ md ⊗ S"X" ⊗ md +𝒟ℯ𝓈𝓉𝒶𝒷 ++ Z___ ++ _Z__ ++ __Z_ ++ ___Z +𝒮𝓉𝒶𝒷━━ ++ X___ ++ _X__ ++ __X_ ++ ___X +``` +""" +function tensor(md::MixedDestabilizer, s::Stabilizer) + ntot_md = nqubits(md) + ntot_s = nqubits(s) + ntot = ntot_md + ntot_s + rtot_md = LinearAlgebra.rank(md) + rtot_s = length(s) + rtot = rtot_md + rtot_s + tab = zero(Tableau, 2*ntot, ntot) + last_dvrow = 0 + last_svrow = ntot + last_col = 0 + md1 = MixedDestabilizer(s) + last_lxrow = rtot + last_lzrow = ntot+rtot + for op in [md, md1] + _, last_svrow, _ = puttableau!(tab, stabilizerview(op), last_svrow, last_col) + _, last_dvrow, _ = puttableau!(tab, destabilizerview(op), last_dvrow, last_col) + _, last_lxrow, _ = puttableau!(tab, logicalxview(op), last_lxrow, last_col) + _, last_lzrow, last_col = puttableau!(tab, logicalzview(op), last_lzrow, last_col) + end + return MixedDestabilizer(tab, rtot) +end + +tensor(s::Stabilizer, md::MixedDestabilizer) = tensor(md, s) diff --git a/test/test_stabs.jl b/test/test_stabs.jl index 63a5c562e..d415621ea 100644 --- a/test/test_stabs.jl +++ b/test/test_stabs.jl @@ -55,6 +55,12 @@ stabs = [s[1:i] for s in [random_stabilizer(n) for n in [32,16,16,64,63,65,129,128,127]] for i in rand(1:10)]; mdstabs = MixedDestabilizer.(stabs); @test canonicalize!(⊗(stabs...)) == canonicalize!(stabilizerview(⊗(mdstabs...))) + md = MixedDestabilizer(random_destabilizer(n)) + s = random_stabilizer(n) + mds = md⊗s + @test mixed_destab_looks_good(mds) + estab = stabilizerview(md)⊗s + @test canonicalize!(copy(stabilizerview(mds))) == canonicalize!(estab) end end