Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
New multiqubit gate (#40)
Browse files Browse the repository at this point in the history
* new measure

* new mutiple qubit gates

* multi-gate labeling
  • Loading branch information
GiggleLiu committed Dec 20, 2020
1 parent 0669bd0 commit 06fe241
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 7 deletions.
1 change: 1 addition & 0 deletions examples/circuits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ chain(5, [put(5, 2=>ConstGate.Sdag), put(5, 3=>ConstGate.Tdag),
put(5, (2,)=>ConstGate.T),
]) |> vizcircuit |> _save("constgates.png")

chain(5, [put(5, (2,3)=>label(SWAP, "SWAP")'), put(5, 2=>label(I2, "id")), put(5, 2=>label(X, "X")), control(5, (5,3), (2,4,1)=>put(3, (1,3)=>label(SWAP, "SWAP")))]) |> vizcircuit |> _save("multiqubit.png")
Binary file modified examples/google53.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/multiqubit.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/qft.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/YaoPlots.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ using Compose

plot(;kwargs...) = x->plot(x;kwargs...)

include("helperblock.jl")
include("vizcircuit.jl")
include("zx_plot.jl")

Expand Down
35 changes: 35 additions & 0 deletions src/helperblock.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using YaoBlocks
export LabelBlock

"""
LabelBlock{BT,N} <: TagBlock{N}
A marker to mark a circuit applying on a continous block for better plotting.
"""
struct LabelBlock{BT<:AbstractBlock,N} <: TagBlock{BT,N}
content::BT
name::String
end

YaoBlocks.content(cb::LabelBlock) = cb.content
function LabelBlock(x::BT, name::String) where {N,BT<:AbstractBlock{N}}
LabelBlock{BT,N}(x, name)
end

function is_continuous_chunk(x)
length(x) == 0 && return true
return length(x) == maximum(x)-minimum(x)+1
end

YaoBlocks.PropertyTrait(::LabelBlock) = YaoBlocks.PreserveAll()
YaoBlocks.mat(::Type{T}, blk::LabelBlock) where {T} = mat(T, content(blk))
YaoBlocks.apply!(reg::YaoBlocks.AbstractRegister, blk::LabelBlock) = apply!(reg, content(blk))
YaoBlocks.chsubblocks(blk::LabelBlock, target::AbstractBlock) = LabelBlock(target, blk.name)

Base.adjoint(x::LabelBlock) = LabelBlock(adjoint(content(x)), endswith(x.name, "") ? x.name[1:end-1] : x.name*"")
Base.copy(x::LabelBlock) = LabelBlock(copy(content(x)), x.name)
YaoBlocks.Optimise.to_basictypes(block::LabelBlock) = block

export label
label(b::AbstractBlock, str::String) = LabelBlock(b, str)

43 changes: 36 additions & 7 deletions src/vizcircuit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module CircuitStyles
(context(), polygon([(0.0, -r[]), (0.0, r[])]), stroke("black"), linewidth(lw[]))
)
WG() = compose(context(), rectangle(-1.5*r[], -r[], 3*r[], 2*r[]), fill("white"), stroke("black"), linewidth(lw[]))
MULTIGATE(h) = compose(context(), rectangle(-1.5*r[], -(h/2+r[]), 3*r[], (h+2*r[])), fill("white"), stroke("black"), linewidth(lw[]))
LINE() = compose(context(), line(), stroke("black"), linewidth(lw[]))
TEXT() = compose(context(), text(0.0, 0.0, "", hcenter, vcenter), fontsize(textsize[]), font(fontfamily[]))
PARAMTEXT() = compose(context(), text(0.0, 0.0, "", hcenter, vcenter), fontsize(paramtextsize[]), font(fontfamily[]))
Expand Down Expand Up @@ -77,21 +78,24 @@ end

function _draw!(c::CircuitGrid, loc_brush_texts)
isempty(loc_brush_texts) && return
locs = getindex.(loc_brush_texts, 1)
# a loc can be a integer, or a range
locs = Iterators.flatten(getindex.(loc_brush_texts, 1)) |> collect
i = frontier(c, locs...) + 1
local jpre
loc_brush_texts = sort(loc_brush_texts, by=x->x[1])
loc_brush_texts = sort(loc_brush_texts, by=x->first(x[1]))
for (k, (j, b, txt)) in enumerate(loc_brush_texts)
b >> c[i, j]
length(j) == 0 && continue
jmid = (minimum(j)+maximum(j))/2
b >> c[i, jmid]
if length(txt) >= 3
CircuitStyles.PARAMTEXT() >> (c[i, j], txt)
CircuitStyles.PARAMTEXT() >> (c[i, jmid], txt)
elseif length(txt) >= 1
CircuitStyles.TEXT() >> (c[i, j], txt)
CircuitStyles.TEXT() >> (c[i, jmid], txt)
end
if k!=1
CircuitStyles.LINE() >> c[(i, j); (i, jpre)]
CircuitStyles.LINE() >> c[(i, jmid); (i, jpre)]
end
jpre = j
jpre = jmid
end

jmin, jmax = min(locs..., nline(c)), max(locs..., 1)
Expand All @@ -101,6 +105,25 @@ function _draw!(c::CircuitGrid, loc_brush_texts)
end
end

function _draw_continuous_multiqubit!(c::CircuitGrid, loc_text)
(start, stop), txt = loc_text
stop-start<0 && return
b = CircuitStyles.MULTIGATE((stop-start) * c.w_line)
i = frontier(c, start:stop...) + 1
j = (stop+start)/2

b >> c[i, j]
if length(txt) >= 3
CircuitStyles.PARAMTEXT() >> (c[i, j], txt)
elseif length(txt) >= 1
CircuitStyles.TEXT() >> (c[i, j], txt)
end
for j = start:stop
CircuitStyles.LINE() >> c[(i, j); (c.frontier[j], j)]
c.frontier[j] = i
end
end

function finalize!(c::CircuitGrid)
i = frontier(c, 1, nline(c)) + 1
for j=1:nline(c)
Expand Down Expand Up @@ -163,6 +186,12 @@ function draw!(c::CircuitGrid, cb::ControlBlock{N,GT,C}, address, controls) wher
draw!(c, cb.content, locs, [controls..., mycontrols...])
end

function draw!(c::CircuitGrid, cb::LabelBlock{GT,N}, address, controls) where {N,GT}
length(address) == 0 && return
is_continuous_chunk(address) || error("address not continuous in a block marked as continous.")
_draw!(c, [controls..., (minimum(address):maximum(address), CircuitStyles.MULTIGATE((length(address)-1)*c.w_line), cb.name)])
end

for (GATE, SYM) in [(:XGate, :Rx), (:YGate, :Ry), (:ZGate, :Rz)]
@eval get_brush_texts(b::RotationGate{1,T,<:$GATE}) where T = [(CircuitStyles.WG(), "$($(SYM))($(pretty_angle(b.theta)))")]
end
Expand Down
28 changes: 28 additions & 0 deletions test/helperblock.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using YaoPlots, Yao
using Test

@testset "LabelBlock" begin
x = put(5, (2,3)=>matblock(rand_unitary(4)))
cb = LabelBlock(x, "x")
@test mat(copy(cb)) == mat(cb)
@test isunitary(cb)
@test ishermitian(cb) == ishermitian(x)
@test isreflexive(cb) == isreflexive(x)
@test mat(cb) == mat(x)
reg = rand_state(5)
@test apply!(copy(reg), cb) apply!(copy(reg), x)
@test cb' isa LabelBlock && mat(cb') mat(cb)'
@test (cb').name == "x†" && (cb'').name == "x"

y = put(5, (3,4)=>matblock(rand_unitary(4)))
cc = chsubblocks(cb, y)
@test YaoPlots.is_continuous_chunk([1,2,3]) == true
@test YaoPlots.is_continuous_chunk([1,2,4]) == false
@test YaoPlots.is_continuous_chunk([3,2,4]) == true

c1 = chain(5, [put(5, (2,3)=>label(SWAP, "SWAP")), put(5, 2=>label(I2, "id")), put(5, 2=>label(X, "X")), control(5, (5,3), (2,4,1)=>put(3, (1,3)=>label(SWAP, "SWAP")))])
c2 = chain(5, [put(5, (2,3)=>label(SWAP, "SWAP")), put(5, 2=>label(I2, "id")), put(5, 2=>label(X, "X")), control(5, (5,3), (2,4,1)=>put(3, (1,2)=>label(SWAP, "SWAP")))])

@test vizcircuit(c1) isa Context
@test_throws ErrorException vizcircuit(c2)
end
4 changes: 4 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
using YaoPlots, ZXCalculus, LightGraphs
using Test

@testset "helperblock" begin
include("helperblock.jl")
end

@testset "vizcircuit" begin
include("vizcircuit.jl")
end
Expand Down

0 comments on commit 06fe241

Please sign in to comment.