diff --git a/Project.toml b/Project.toml index 9f80fd3..a1c7ff8 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Quantikz" uuid = "b0d11df0-eea3-4d79-b4a5-421488cbf74b" authors = ["Stefan Krastanov "] -version = "1.0.3" +version = "1.0.4" [deps] EndpointRanges = "340492b5-2a47-5f55-813d-aca7ddf97656" diff --git a/src/Quantikz.jl b/src/Quantikz.jl index da6af00..666f5df 100644 --- a/src/Quantikz.jl +++ b/src/Quantikz.jl @@ -115,7 +115,7 @@ MultiControlU(str::AbstractString,control::Integer,target::Integer) = MultiContr MultiControlU(control::Integer,target::Integer) = MultiControlU("\\;\\;",[control],[],[target]) affectedqubits(g::MultiControlU) = [g.control...,g.ocontrol...,g.target...] -function update_table!(qtable,step,g::MultiControlU) # TODO displaycircuit([CNOT([1,4],[3],[2,5])]) has bad ocircle covered by line and a disconnected target +function update_table!(qtable,step,g::MultiControlU) table = qtable.table control = g.control ocontrol = g.ocontrol @@ -130,15 +130,7 @@ function update_table!(qtable,step,g::MultiControlU) # TODO displaycircuit([CNOT else startpoint = min(M,controls[1][2]) end - offset = iseven(M-m) && (m+M)/2 ∉ target ? ",label style={yshift=0.2cm}" : "" - table[m,step] = "\\gate[$(M-m+1)$(offset)]{$(g.str)}" - for i in m+1:M - if i ∉ target - table[i,step] = "\\linethrough" - else - table[i,step] = "" - end - end + draw_rectangle!(table,m,M,step,target,g.str) for (str, i) in controls if i > M && startpoint < M if startpoint < m @@ -155,6 +147,24 @@ function update_table!(qtable,step,g::MultiControlU) # TODO displaycircuit([CNOT qtable end +function draw_rectangle!(table,m,M,step,targets,str) + deleted = Int[] + for i in m+1:M + if i ∉ targets + if strip(table[i,step-1])=="" + push!(deleted, i) + else + table[i,step] = "\\linethrough" + end + else + table[i,step] = "" + end + end + offset = iseven(M-m) && ((m+M)/2 ∉ vcat(targets,deleted)) ? ",label style={yshift=0.2cm}" : "" + nwires = isempty(deleted) ? "" : ",nwires={$(join(deleted,","))}" + table[m,step] = "\\gate[$(M-m+1)$(offset)$(nwires)]{$(str)}" +end + struct U <: QuantikzOp str::AbstractString target::Integer @@ -210,15 +220,7 @@ function update_table!(qtable,step,meas::Measurement) else step = step+1 m,M = extrema(meas.targets) - offset = iseven(M-m) && (m+M)/2 ∉ meas.targets ? ",label style={yshift=0.2cm}" : "" - table[m,step] = "\\gate[$(M-m+1)$(offset)]{$(meas.str)}" - for i in m+1:M - if i ∉ meas.targets - table[i,step] = "\\linethrough" - else - table[i,step] = "" - end - end + draw_rectangle!(table,m,M,step,meas.targets,meas.str) qubitsview(qtable)[meas.targets,step+1] .= "\\qw" ancillaryview(qtable)[1,step-1] = "\\lstick{}" ancillaryview(qtable)[1,step] = "\\ctrl{$(M-qtable.qubits-1)}" @@ -250,15 +252,7 @@ affectedbits(g::ClassicalDecision) = g.bits function update_table!(qtable,step,g::ClassicalDecision) table = qtable.table m,M = extrema(g.targets) # TODO this piece of code is repeated frequently, abstract it away - offset = iseven(M-m) && (m+M)/2 ∉ g.targets ? ",label style={yshift=0.2cm}" : "" - table[m,step] = "\\gate[$(M-m+1)$(offset)]{$(g.str)}" - for i in m+1:M - if i ∉ g.targets - table[i,step] = "\\linethrough" - else - table[i,step] = "" - end - end + draw_rectangle!(table,m,M,step,g.targets,g.str) startpoint = minimum(g.bits) bitsview(qtable)[startpoint,step] = "\\cwbend{$(-(qtable.qubits-M)-qtable.ancillaries-startpoint)}" for b in sort(g.bits)[2:end] diff --git a/test/runtests.jl b/test/runtests.jl index 3586a0c..9e348d6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -70,6 +70,23 @@ end @test circuit2string([Measurement(2),Measurement(1,1)]) == circuit2string([Measurement(2),Measurement(1,1)], mode=:expanded) == "\\begin{quantikz}[transparent, row sep={0.8cm,between origins}]\n\\qw & \\qw & \\meterD{} & \\\\\n\\qw & \\meterD{} & & \\\\\n\\cw & \\cw & \\cwbend{-2} & \\cw\n\\end{quantikz}" end +@testset "Avoiding placement of already deleted wires on top of rectangles" begin +c =[Measurement(2), + U(3), U(3), + MultiControlU("A", [1, 3]), + U(3), + U("A", [1,4]), + U(3), + U([1,3]), + U(3), + Measurement([1,3]), + U(3), + ClassicalDecision([1,3],1)] +@test circuit2string(c) == "\\begin{quantikz}[transparent, row sep={0.8cm,between origins}]\n\\qw & \\qw & \\qw & \\gate[3,nwires={2}]{A} & \\qw & \\gate[4,nwires={2}]{A} & \\qw & \\gate[3,nwires={2}]{\\;\\;} & \\qw & \\qw & \\gate[3,nwires={2}]{\\;\\;} & \\qw & \\qw & \\gate[3,nwires={2}]{\\;\\;} & \\qw\\\\\n\\qw & \\meterD{} & & & & & & & & & & & & & \\\\\n\\qw & \\gate{\\;\\;} & \\gate{\\;\\;} & & \\gate{\\;\\;} & \\linethrough & \\gate{\\;\\;} & & \\gate{\\;\\;} & \\qw & & \\qw & \\gate{\\;\\;} & & \\qw\\\\\n\\qw & \\qw & \\qw & \\qw & \\qw & & \\qw & \\qw & \\qw & \\qw & \\qw & \\qw & \\qw & \\qw & \\qw\\\\\n & & & & & & & & & \\lstick{} & \\ctrl{-2} & \\meterD{} & & & \\\\\n\\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cwbend{-3} & \\cw\n\\end{quantikz}" +@test circuit2string(c,mode=:expanded) == "\\begin{quantikz}[transparent, row sep={0.8cm,between origins}]\n\\qw & \\qw & \\qw & \\qw & \\gate[3,nwires={2}]{A} & \\qw & \\gate[4,nwires={2}]{A} & \\qw & \\gate[3,nwires={2}]{\\;\\;} & \\qw & \\qw & \\gate[3,nwires={2}]{\\;\\;} & \\qw & \\qw & \\gate[3,nwires={2}]{\\;\\;} & \\qw\\\\\n\\qw & \\meterD{} & & & & & & & & & & & & & & \\\\\n\\qw & \\qw & \\gate{\\;\\;} & \\gate{\\;\\;} & & \\gate{\\;\\;} & \\linethrough & \\gate{\\;\\;} & & \\gate{\\;\\;} & \\qw & & \\qw & \\gate{\\;\\;} & & \\qw\\\\\n\\qw & \\qw & \\qw & \\qw & \\qw & \\qw & & \\qw & \\qw & \\qw & \\qw & \\qw & \\qw & \\qw & \\qw & \\qw\\\\\n & & & & & & & & & & \\lstick{} & \\ctrl{-2} & \\meterD{} & & & \\\\\n\\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cw & \\cwbend{-3} & \\cw\n\\end{quantikz}" +end + + end function filetests()