From 937e6725f655cba284fe133bd6f81f80bfec4893 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Sun, 16 Jun 2024 23:05:24 +0900 Subject: [PATCH 1/5] Upgrade Luxor to Version 5 --- lib/YaoPlots/Project.toml | 4 +- lib/YaoPlots/README.md | 2 +- lib/YaoPlots/src/3d.jl | 100 ++++++++++++++++++++++++++++++++ lib/YaoPlots/src/YaoPlots.jl | 4 +- lib/YaoPlots/src/bloch.jl | 35 +++++------ lib/YaoPlots/src/vizcircuit.jl | 6 +- lib/YaoPlots/test/vizcircuit.jl | 2 +- 7 files changed, 126 insertions(+), 27 deletions(-) create mode 100644 lib/YaoPlots/src/3d.jl diff --git a/lib/YaoPlots/Project.toml b/lib/YaoPlots/Project.toml index 7e53dc1e..179e79c7 100644 --- a/lib/YaoPlots/Project.toml +++ b/lib/YaoPlots/Project.toml @@ -5,14 +5,12 @@ version = "0.9.2" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc" -Thebes = "8b424ff8-82f5-59a4-86a6-de3761897198" YaoArrayRegister = "e600142f-9330-5003-8abb-0ebd767abc51" YaoBlocks = "418bc28f-b43b-5e0b-a6e7-61bbc1a2c1df" [compat] LinearAlgebra = "1" -Luxor = "3" -Thebes = "1" +Luxor = "4" YaoArrayRegister = "0.9" YaoBlocks = "0.13" julia = "1" diff --git a/lib/YaoPlots/README.md b/lib/YaoPlots/README.md index ec5d9cd7..42f63e5a 100644 --- a/lib/YaoPlots/README.md +++ b/lib/YaoPlots/README.md @@ -23,7 +23,7 @@ using YaoPlots, Yao reg = zero_state(1) |> Rx(π/8) |> Rx(π/8) rho = density_matrix(ghz_state(2), 1) -bloch_sphere("|ψ⟩"=>reg, "ρ"=>rho; show_projection_lines=true) +bloch_sphere("|ψ>"=>reg, "ρ"=>rho; show_projection_lines=true) ``` Similarly, you will see diff --git a/lib/YaoPlots/src/3d.jl b/lib/YaoPlots/src/3d.jl new file mode 100644 index 00000000..597e357c --- /dev/null +++ b/lib/YaoPlots/src/3d.jl @@ -0,0 +1,100 @@ +# The following code is copied from Thebes.jl, which is a package for 3D plotting in Julia. +# Since Thebes.jl is not updated for a while, we need to update the code to make it work with the latest version of Luxor.jl. + +module Thebes +using Luxor +struct Point3D + x::Float64 + y::Float64 + z::Float64 +end + +mutable struct Projection + U::Point3D # + V::Point3D # + W::Point3D # + ue::Float64 # + ve::Float64 # + we::Float64 # + eyepoint::Point3D + centerpoint::Point3D + uppoint::Point3D + perspective::Float64 # +end + +function newprojection(ipos::Point3D, center::Point3D, up::Point3D, perspective=0.0) + if iszero(ipos.x) + ipos = Point3D(10e-9, ipos.y, ipos.z) + end + if iszero(ipos.y) + ipos = Point3D(ipos.x, 10e-9, ipos.z) + end + if iszero(ipos.z) + ipos = Point3D(ipos.x, ipos.y, 10e-9) + end + + # w is the line of sight + W = Point3D(center.x - ipos.x, center.y - ipos.y, center.z - ipos.z) + r = (W.x * W.x) + (W.y * W.y) + (W.z * W.z) + if r < eps() + @info("eye position and center are the same") + + W = Point3D(0.0, 0.0, 0.0) + else + # distancealise w to unit length + rinv = 1 / sqrt(r) + W = Point3D(W.x * rinv, W.y * rinv, W.z * rinv) + end + we = W.x * ipos.x + W.y * ipos.y + W.z * ipos.z # project e on to w + U = Point3D(W.y * (up.z - ipos.z) - W.z * (up.y - ipos.y), # u is at right angles to t - e + W.z * (up.x - ipos.x) - W.x * (up.z - ipos.z), # and w ., its' the pictures x axis + W.x * (up.y - ipos.y) - W.y * (up.x - ipos.x)) + r = (U.x * U.x) + (U.y * U.y) + (U.z * U.z) + + if r < eps() + @info("struggling to make a valid projection with these parameters") + U = Point3D(0.0, 0.0, 0.0) + else + rinv = 1 / sqrt(r) # distancealise u + U = Point3D(U.x * rinv, U.y * rinv, U.z * rinv) + end + + ue = U.x * ipos.x + U.y * ipos.y + U.z * ipos.z # project e onto u + + V = Point3D(U.y * W.z - U.z * W.y, # v is at right angles to u and w + U.z * W.x - U.x * W.z, # it's the world's y axis + U.x * W.y - U.y * W.x) + + ve = V.x * ipos.x + V.y * ipos.y + V.z * ipos.z # project e onto v + + Projection(U, V, W, ue, ve, we, ipos, center, up, perspective) +end + +function project(proj::Projection, P::Point3D) + # use default value for perspectiveness if not specified + r = proj.W.x * P.x + proj.W.y * P.y + proj.W.z * P.z - proj.we + if r < eps() + # "point $P is behind eye" + result = nothing + else + if proj.perspective == 0.0 + depth = 1 + else + depth = proj.perspective * (1 / r) + end + uq = depth * (proj.U.x * P.x + proj.U.y * P.y + proj.U.z * P.z - proj.ue) + vq = depth * (proj.V.x * P.x + proj.V.y * P.y + proj.V.z * P.z - proj.ve) + result = Point(uq, -vq) # because Y is down the page in Luxor (?!) + end + return result +end + +function eyepoint(pt::Point3D) + return newprojection(pt, Point3D(0, 0, 0), Point3D(0, 0, 1)) +end + +function Luxor.distance(p1::Point3D, p2::Point3D) + sqrt((p2.x - p1.x)^2 + (p2.y - p1.y)^2 + (p2.z - p1.z)^2) +end + +end \ No newline at end of file diff --git a/lib/YaoPlots/src/YaoPlots.jl b/lib/YaoPlots/src/YaoPlots.jl index baa89090..4efb0113 100644 --- a/lib/YaoPlots/src/YaoPlots.jl +++ b/lib/YaoPlots/src/YaoPlots.jl @@ -4,9 +4,7 @@ using YaoBlocks using YaoBlocks.DocStringExtensions using YaoArrayRegister import Luxor -import Thebes using Luxor: @layer, Point -using Thebes: Point3D, project using LinearAlgebra: tr export CircuitStyles, vizcircuit, darktheme!, lighttheme! @@ -19,6 +17,8 @@ plot(blk::AbstractBlock; kwargs...) = vizcircuit(blk; kwargs...) include("helperblock.jl") include("vizcircuit.jl") +include("3d.jl") +using .Thebes: Point3D, project include("bloch.jl") end diff --git a/lib/YaoPlots/src/bloch.jl b/lib/YaoPlots/src/bloch.jl index a681bf7e..ec75fddf 100644 --- a/lib/YaoPlots/src/bloch.jl +++ b/lib/YaoPlots/src/bloch.jl @@ -37,7 +37,7 @@ module BlochStyles # generic config const lw = Ref(1.0) const textsize = Ref(16.0) - const fontfamily = Ref("monospace") + const fontfamily = Ref("JuliaMono") const background_color = Ref("transparent") const color = Ref("#000000") @@ -132,8 +132,6 @@ function bloch_sphere(states...; Luxor.fontsize(textsize) fontfamily !== nothing && Luxor.fontface(fontfamily) Luxor.setline(lw) - Thebes.eyepoint(eye_point...) - draw_bloch_sphere(states...; eye_point, extra_kwargs...) # Save the drawing to a file @@ -153,8 +151,10 @@ function draw_bloch_sphere(states::Pair{<:AbstractString}...; colors = fill(BlochStyles.color[], length(states)), extra_kwargs... ) + proj = Thebes.eyepoint(Point3D(eye_point...)) + # get coordinate of a state - getcoo(x) = Point3D(ball_size .* state_to_cartesian(x)) + getcoo(x) = Point3D((ball_size .* state_to_cartesian(x))...) # ball Luxor.circle(Point(0, 0), ball_size, :stroke) @@ -162,12 +162,12 @@ function draw_bloch_sphere(states::Pair{<:AbstractString}...; # equator nstep = 100 equator_points = map(LinRange(0, 2π*(1-1/nstep), nstep)) do ϕ - project(Point3D(ball_size .* polar_to_cartesian(1.0, π/2, ϕ))) + project(proj, Point3D((ball_size .* polar_to_cartesian(1.0, π/2, ϕ))...)) end Luxor.line.(equator_points[1:2:end], equator_points[2:2:end], :stroke) # show axes - axes3D(ball_size*3 ÷ 2; extra_kwargs...) + axes3D(ball_size*3 ÷ 2; proj, extra_kwargs...) # show 01 states if show01 @@ -178,7 +178,7 @@ function draw_bloch_sphere(states::Pair{<:AbstractString}...; if Thebes.distance(Point3D(0, 0, 0), Point3D(eye_point...)) < Thebes.distance(p, Point3D(eye_point...)) Luxor.setopacity(0.3) end - show_point(txt, project(p); dot_size, text_offset=Point(10, 0), show_line=false) + show_point(txt, project(proj, p); dot_size, text_offset=Point(10, 0), show_line=false) end end end @@ -191,32 +191,32 @@ function draw_bloch_sphere(states::Pair{<:AbstractString}...; if Thebes.distance(Point3D(0, 0, 0), Point3D(eye_point...)) < Thebes.distance(p, Point3D(eye_point...)) Luxor.setopacity(0.3) end - show_point(txt, project(p); dot_size, text_offset=Point(10, 0), show_line=show_line) + show_point(txt, project(proj, p); dot_size, text_offset=Point(10, 0), show_line=show_line) end if show_projection_lines # show θ ratio = 0.2 - sz = project(Point3D(0, 0, ball_size*ratio)) + sz = project(proj, Point3D(0, 0, ball_size*ratio)) if show_angle_texts Luxor.move(sz) - Luxor.arc2r(Point(0, 0), sz, project(p) * ratio, :stroke) + Luxor.arc2r(Point(0, 0), sz, project(proj, p) * ratio, :stroke) Luxor.text("θ", sz - Point(0, ball_size*0.07)) end # show equator projection and ϕ - equatorp = Point3D(p[1], p[2], 0) - sx = project(Point3D(ball_size*ratio, 0, 0)) + equatorp = Point3D(p.x, p.y, 0) + sx = project(proj, Point3D(ball_size*ratio, 0, 0)) if show_angle_texts Luxor.move(sx) - Luxor.carc2r(Point(0, 0), sx, project(equatorp) * ratio, :stroke) + Luxor.carc2r(Point(0, 0), sx, project(proj, equatorp) * ratio, :stroke) Luxor.text("ϕ", sx - Point(ball_size*0.12, 0)) end @layer begin Luxor.setdash("dot") Luxor.setline(1) - Luxor.line(project(p), project(equatorp), :stroke) - Luxor.line(Point(0, 0), project(equatorp), :stroke) + Luxor.line(project(proj, p), project(proj, equatorp), :stroke) + Luxor.line(Point(0, 0), project(proj, equatorp), :stroke) end end end @@ -253,6 +253,7 @@ state_to_cartesian(state) = polar_to_cartesian(state_to_polar(state)...) # Draw labelled 3D axes with length `n`. function axes3D(n::Int; + proj, axes_lw = BlochStyles.axes_lw[], axes_textsize = BlochStyles.textsize[], axes_colors = BlochStyles.axes_colors, @@ -262,10 +263,10 @@ function axes3D(n::Int; Luxor.fontsize(axes_textsize) Luxor.setline(axes_lw) for i = 1:3 - axis1 = project(Point3D(0.1, 0.1, 0.1)) + axis1 = project(proj, Point3D(0.1, 0.1, 0.1)) axis2 = [0.1, 0.1, 0.1] axis2[i] = n - axis2 = project(Point3D(axis2...)) + axis2 = project(proj, Point3D(axis2...)) Luxor.sethue(axes_colors[i]) if (axis1 !== nothing) && (axis2 !== nothing) && !isapprox(axis1, axis2) Luxor.arrow(axis1, axis2) diff --git a/lib/YaoPlots/src/vizcircuit.jl b/lib/YaoPlots/src/vizcircuit.jl index d4d28cb9..90e6a004 100644 --- a/lib/YaoPlots/src/vizcircuit.jl +++ b/lib/YaoPlots/src/vizcircuit.jl @@ -34,7 +34,7 @@ module CircuitStyles const lw = Ref(1.0) const textsize = Ref(16.0) const paramtextsize = Ref(10.0) - const fontfamily = Ref("monospace") + const fontfamily = Ref("JuliaMono") #const fontfamily = Ref("Dejavu Sans") const linecolor = Ref("#000000") const gate_bgcolor = Ref("transparent") @@ -421,7 +421,7 @@ get_brush_texts(c, ::ConstGate.P0Gate) = (c.gatestyles.g, "P₀") get_brush_texts(c, ::ConstGate.P1Gate) = (c.gatestyles.g, "P₁") get_brush_texts(c, b::PrimitiveBlock) = (c.gatestyles.g, string(b)) get_brush_texts(c, b::TimeEvolution) = (c.gatestyles.g, string(b)) -get_brush_texts(c, b::ShiftGate) = (c.gatestyles.g, "ϕ($(pretty_angle(b.theta)))") +get_brush_texts(c, b::ShiftGate) = (c.gatestyles.g, "φ($(pretty_angle(b.theta)))") get_brush_texts(c, b::PhaseGate) = (CircuitStyles.Phase("$(pretty_angle(b.theta))"), "") function get_brush_texts(c, b::T) where T<:ConstantGate namestr = string(T.name.name) @@ -462,7 +462,7 @@ They are defined as: * CircuitStyles.lw = Ref(1.0) # line width * CircuitStyles.textsize = Ref(16.0) # text size * CircuitStyles.paramtextsize = Ref(10.0) # text size (longer texts) -* CircuitStyles.fontfamily = Ref("monospace") # font family +* CircuitStyles.fontfamily = Ref("JuliaMono") # font family * CircuitStyles.linecolor = Ref("#000000") # line color * CircuitStyles.gate_bgcolor = Ref("transparent") # gate background color * CircuitStyles.textcolor = Ref("#000000") # text color diff --git a/lib/YaoPlots/test/vizcircuit.jl b/lib/YaoPlots/test/vizcircuit.jl index bf063aee..d1bf25ec 100644 --- a/lib/YaoPlots/test/vizcircuit.jl +++ b/lib/YaoPlots/test/vizcircuit.jl @@ -9,7 +9,7 @@ using Luxor c = YaoPlots.CircuitGrid(1) @test YaoPlots.get_brush_texts(c, X)[2] == "X" @test YaoPlots.get_brush_texts(c, Rx(0.5))[2] == "Rx(0.5)" - @test YaoPlots.get_brush_texts(c, shift(0.5))[2] == "ϕ(0.5)" + @test YaoPlots.get_brush_texts(c, shift(0.5))[2] == "φ(0.5)" @test YaoPlots.get_brush_texts(c, YaoBlocks.phase(0.5))[2] == "" end From 51fe39d1acc1006cbd7f2c92110ce5c89890785a Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Sun, 16 Jun 2024 23:25:32 +0900 Subject: [PATCH 2/5] fix tests --- lib/YaoBlocks/test/primitive/time_evolution.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/YaoBlocks/test/primitive/time_evolution.jl b/lib/YaoBlocks/test/primitive/time_evolution.jl index 6c11bf05..a7474cf8 100644 --- a/lib/YaoBlocks/test/primitive/time_evolution.jl +++ b/lib/YaoBlocks/test/primitive/time_evolution.jl @@ -108,16 +108,16 @@ end mpb = mat(pb) allpass = true for i=basis(pb), j=basis(pb) - allpass &= pb[i, j] ≈ mpb[Int(i)+1, Int(j)+1] + allpass &= isapprox(pb[i, j], mpb[Int(i)+1, Int(j)+1]; atol=1e-6) end @test allpass allpass = true for j=basis(pb) - allpass &= vec(pb[:, j]) ≈ mpb[:, Int(j)+1] - allpass &= vec(pb[j,:]) ≈ mpb[Int(j)+1,:] - allpass &= vec(pb[:, EntryTable([j], [1.0+0im])]) ≈ mpb[:, Int(j)+1] - allpass &= vec(pb[EntryTable([j], [1.0+0im]),:]) ≈ mpb[Int(j)+1,:] + allpass &= isapprox(vec(pb[:, j]), mpb[:, Int(j)+1]; atol=1e-6) + allpass &= isapprox(vec(pb[j,:]), mpb[Int(j)+1,:]; atol=1e-6) + allpass &= isapprox(vec(pb[:, EntryTable([j], [1.0+0im])]), mpb[:, Int(j)+1]; atol=1e-6) + allpass &= isapprox(vec(pb[EntryTable([j], [1.0+0im]),:]), mpb[Int(j)+1,:]; atol=1e-6) allpass &= isclean(pb[:,j]) end @test allpass From 8e90cc192f1f97f5734872b30fed89dcddee872b Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Tue, 2 Jul 2024 14:11:11 +0800 Subject: [PATCH 3/5] annotate a single line --- docs/src/man/registers.md | 2 +- lib/YaoPlots/src/YaoPlots.jl | 2 ++ lib/YaoPlots/src/helperblock.jl | 18 ++++++++++++++---- lib/YaoPlots/src/vizcircuit.jl | 12 ++++++++++++ lib/YaoPlots/test/helperblock.jl | 7 +++++++ 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/docs/src/man/registers.md b/docs/src/man/registers.md index 51c36f43..b0342119 100644 --- a/docs/src/man/registers.md +++ b/docs/src/man/registers.md @@ -140,7 +140,7 @@ We also have some "cheating" version [`measure`](@ref) that does not collapse st ```@repl register measure!(reg0, 1) # measure the qubit, the state collapses measure!(reg0) # measure all qubits -measure(reg0, 3) # measure the qubit 3 times, the state does not collapse (hacky) +measure(reg0, 3) # measure the qubit at location 3, the state does not collapse (hacky) reorder!(reg0, 7:-1:1) # reorder the qubits measure!(reg0) invorder!(reg0) # reverse the order of qubits diff --git a/lib/YaoPlots/src/YaoPlots.jl b/lib/YaoPlots/src/YaoPlots.jl index baa89090..931ee97a 100644 --- a/lib/YaoPlots/src/YaoPlots.jl +++ b/lib/YaoPlots/src/YaoPlots.jl @@ -8,10 +8,12 @@ import Thebes using Luxor: @layer, Point using Thebes: Point3D, project using LinearAlgebra: tr +using YaoBlocks export CircuitStyles, vizcircuit, darktheme!, lighttheme! export bloch_sphere, BlochStyles export plot +export LabelBlock, addlabel, LineAnnotation, line_annotation """An alias of `vizcircuit`""" plot(;kwargs...) = x->plot(x;kwargs...) diff --git a/lib/YaoPlots/src/helperblock.jl b/lib/YaoPlots/src/helperblock.jl index 057a92bb..84ccb4be 100644 --- a/lib/YaoPlots/src/helperblock.jl +++ b/lib/YaoPlots/src/helperblock.jl @@ -1,6 +1,3 @@ -using YaoBlocks -export LabelBlock - """ LabelBlock{BT,D} <: TagBlock{BT,D} @@ -31,7 +28,6 @@ Base.adjoint(x::LabelBlock) = LabelBlock(adjoint(content(x)), endswith(x.name, " Base.copy(x::LabelBlock) = LabelBlock(copy(content(x)), x.name, x.color) YaoBlocks.Optimise.to_basictypes(block::LabelBlock) = block -export addlabel addlabel(b::AbstractBlock; name=string(b), color="transparent") = LabelBlock(b, name, color) # to fix issue @@ -49,3 +45,17 @@ function YaoBlocks.print_tree( ) print(io, node.name) end + +""" + LineAnnotation{D} <: TrivialGate{D} +""" +struct LineAnnotation{D} <: TrivialGate{D} + name::String + color::String +end +line_annotation(name::String; color="black", nlevel=2) = LineAnnotation{nlevel}(name, color) + +Base.copy(x::LineAnnotation) = LineAnnotation(x.name, x.color) +YaoBlocks.Optimise.to_basictypes(block::LineAnnotation) = block +YaoBlocks.nqudits(::LineAnnotation) = 1 +YaoBlocks.print_block(io::IO, blk::LineAnnotation) = YaoBlocks.printstyled(io, blk.name; color=Symbol(blk.color)) \ No newline at end of file diff --git a/lib/YaoPlots/src/vizcircuit.jl b/lib/YaoPlots/src/vizcircuit.jl index 76348c0b..458d624c 100644 --- a/lib/YaoPlots/src/vizcircuit.jl +++ b/lib/YaoPlots/src/vizcircuit.jl @@ -374,6 +374,18 @@ function draw!(c::CircuitGrid, cb::LabelBlock, address, controls) CircuitStyles.gate_bgcolor[] = temp end +function draw!(c::CircuitGrid, cb::LineAnnotation, address, controls) + @assert length(address) == 1 && isempty(controls) "LineAnnotation should be a single line, without control." + CircuitStyles.textcolor[], temp = cb.color, CircuitStyles.textcolor[] + _annotate!(c, address[1], cb.name) + CircuitStyles.textcolor[] = temp +end +function _annotate!(c::CircuitGrid, loc::Integer, name::AbstractString) + wspace, fontsize = text_width_and_size(name) + i = frontier(c, loc) + 0.1 + CircuitStyles.render(CircuitStyles.Text(fontsize), (c[i, loc-0.2], name, wspace, fontsize)) +end + # [:KronBlock, :RepeatedBlock, :CachedBlock, :Subroutine, :(YaoBlocks.AD.NoParams)] function draw!(c::CircuitGrid, p::CompositeBlock, address, controls) barrier_style = CircuitStyles.barrier_for_chain[] diff --git a/lib/YaoPlots/test/helperblock.jl b/lib/YaoPlots/test/helperblock.jl index a279634b..79a0ee17 100644 --- a/lib/YaoPlots/test/helperblock.jl +++ b/lib/YaoPlots/test/helperblock.jl @@ -27,3 +27,10 @@ using Test @test vizcircuit(c1) isa Drawing @test vizcircuit(c2) isa Drawing end + +@testset "annotate line" begin + ann = line_annotation("test"; color="red") + @test ann isa LineAnnotation + c = chain(put(5, 2=>X), put(5, 2=>ann), put(5, 3=>Y)) + @test vizcircuit(c) isa Drawing +end \ No newline at end of file From b9e3a53ed8de2b0cfdc70a19442560b2b5397157 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Tue, 2 Jul 2024 17:10:00 +0800 Subject: [PATCH 4/5] fix barrier --- lib/YaoPlots/src/vizcircuit.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/YaoPlots/src/vizcircuit.jl b/lib/YaoPlots/src/vizcircuit.jl index accc4b77..36ef1c9c 100644 --- a/lib/YaoPlots/src/vizcircuit.jl +++ b/lib/YaoPlots/src/vizcircuit.jl @@ -315,8 +315,8 @@ end function draw!(c::CircuitGrid, p::ChainBlock, address, controls) for block in subblocks(p) draw!(c, block, address, controls) - CircuitStyles.barrier_for_chain[] && set_barrier!(c, Int[address..., controls...]) end + CircuitStyles.barrier_for_chain[] && set_barrier!(c, Int[address..., controls...]) end function set_barrier!(c::CircuitGrid, locs::AbstractVector{Int}) From 4665797e5e74e093e90804e562bd17b08bb482da Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Wed, 3 Jul 2024 11:12:50 +0800 Subject: [PATCH 5/5] fix barrier --- lib/YaoPlots/src/vizcircuit.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/YaoPlots/src/vizcircuit.jl b/lib/YaoPlots/src/vizcircuit.jl index 36ef1c9c..a054bce8 100644 --- a/lib/YaoPlots/src/vizcircuit.jl +++ b/lib/YaoPlots/src/vizcircuit.jl @@ -313,6 +313,7 @@ end # composite function draw!(c::CircuitGrid, p::ChainBlock, address, controls) + CircuitStyles.barrier_for_chain[] && set_barrier!(c, Int[address..., controls...]) for block in subblocks(p) draw!(c, block, address, controls) end