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

Commit

Permalink
seperate zx calculus
Browse files Browse the repository at this point in the history
  • Loading branch information
GiggleLiu committed Jun 17, 2022
1 parent 1b17e50 commit 14ff467
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 374 deletions.
14 changes: 1 addition & 13 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
name = "YaoPlots"
uuid = "32cfe2d9-419e-45f2-8191-2267705d8dbc"
version = "0.7.5"
version = "0.8.0"

[deps]
BitBasis = "50ba71b6-fa0f-514d-ae9a-0916efc90dcf"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc"
Multigraphs = "7ebac608-6c66-46e6-9856-b5f43e107bac"
Yao = "5872b779-8223-5990-8dd0-5abbb0748c8c"
ZXCalculus = "3525faa3-032d-4235-a8d4-8c2939a218dd"

[compat]
BitBasis = "0.8"
Colors = "0.11, 0.12"
Luxor = "3"
GraphPlot = "0.5"
Graphs = "1.7"
Multigraphs = "0.3"
Yao = "0.8"
ZXCalculus = "0.5"
julia = "1"

[extras]
Expand Down
67 changes: 9 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@

```julia
using Yao.EasyBuild, YaoPlots
using Compose

# show a qft circuit
plot(qft_circuit(5))
vizcircuit(qft_circuit(5))
```

If you are using a Pluto/Jupyter notebook, Atom/VSCode editor, you should see the following image in your plotting panel.

![qft](examples/qft.png)

Otherwise, you might be interested to learn [how to save it as an image](https://giovineitalia.github.io/Compose.jl/latest/tutorial/).

See more [examples](examples/circuits.jl).

### Adjusting the plot attributes
Expand All @@ -29,9 +26,9 @@ The plot can be modified, if we change the following attributes
- `YaoPlots.CircuitStyles.linecolor[]` for line color, default value being `"#000000"` (black color)
- `YaoPlots.CircuitStyles.gate_bgcolor[]` for background color of square blocks, the default value being `"#FFFFFF"` (white color)
- `YaoPlots.CircuitStyles.textcolor[]` for text color, default value being `"#000000`
- `YaoPlots.CircuitStyles.lw[]` for line width, default value being `1pt`
- `YaoPlots.CircuitStyles.textsize[]` for text size, default value being `16pt`
- `YaoPlots.CircuitStyles.paramtextsize[]` for parameter text size, for parameterized gates, default value being `10pt`
- `YaoPlots.CircuitStyles.lw[]` for line width, default value being `1` (pt)
- `YaoPlots.CircuitStyles.textsize[]` for text size, default value being `16` (pt)
- `YaoPlots.CircuitStyles.paramtextsize[]` for parameter text size, for parameterized gates, default value being `10` (pt)

For example,

Expand All @@ -41,57 +38,11 @@ YaoPlots.CircuitStyles.linecolor[] = "pink"
YaoPlots.CircuitStyles.gate_bgcolor[] = "yellow"
YaoPlots.CircuitStyles.textcolor[] = "#000080" # the navy blue color
YaoPlots.CircuitStyles.fontfamily[] = "JuliaMono"
YaoPlots.CircuitStyles.lw[] = 2.5pt
YaoPlots.CircuitStyles.textsize[] = 13pt
YaoPlots.CircuitStyles.paramtextsize[] = 8pt
YaoPlots.CircuitStyles.lw[] = 2.5
YaoPlots.CircuitStyles.textsize[] = 13
YaoPlots.CircuitStyles.paramtextsize[] = 8

plot(chain(3, put(1=>X), repeat(3, H), put(2=>Y), repeat(3, Rx/2))))
```

![attribute_example_2](examples/attr_circuit_2.svg)


## Example 2: Visualize ZX-diagrams in ZXCalculus
```julia
using ZXCalculus, YaoPlots
using Compose

function generate_example()
zxd = ZXDiagram(4)
push_gate!(zxd, Val{:Z}(), 1, 3//2)
push_gate!(zxd, Val{:H}(), 1)
push_gate!(zxd, Val{:Z}(), 1, 1//2)
push_gate!(zxd, Val{:H}(), 4)
push_gate!(zxd, Val{:CZ}(), 4, 1)
push_gate!(zxd, Val{:CNOT}(), 1, 4)
push_gate!(zxd, Val{:H}(), 1)
push_gate!(zxd, Val{:H}(), 4)
push_gate!(zxd, Val{:Z}(), 1, 1//4)
push_gate!(zxd, Val{:Z}(), 4, 3//2)
push_gate!(zxd, Val{:X}(), 4, 1//1)
push_gate!(zxd, Val{:H}(), 1)
push_gate!(zxd, Val{:Z}(), 4, 1//2)
push_gate!(zxd, Val{:X}(), 4, 1//1)
push_gate!(zxd, Val{:Z}(), 2, 1//2)
push_gate!(zxd, Val{:CNOT}(), 3, 2)
push_gate!(zxd, Val{:H}(), 2)
push_gate!(zxd, Val{:CNOT}(), 3, 2)
push_gate!(zxd, Val{:Z}(), 2, 1//4)
push_gate!(zxd, Val{:Z}(), 3, 1//2)
push_gate!(zxd, Val{:H}(), 2)
push_gate!(zxd, Val{:H}(), 3)
push_gate!(zxd, Val{:Z}(), 3, 1//2)
push_gate!(zxd, Val{:CNOT}(), 3, 2)

return zxd
end

zxd = generate_example() # define a example
plot(zxd) # draw a ZX-diagram
plot(ZXGraph(zxd)) # draw a graph-like ZX-diagram
vizcircuit(chain(3, put(1=>X), repeat(3, H), put(2=>Y), repeat(3, Rx/2))))
```

If you are using a Pluto/Jupyter notebook, Atom/VSCode editor, you should see the following images in your plotting panel.

![zxd](examples/demo_zxd.svg)
![zxg](examples/demo_zxg.svg)
![attribute_example_2](examples/attr_circuit_2.svg)
Binary file modified examples/google53.png
Loading
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/supremacy2d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 0 additions & 38 deletions examples/zx_diagrams.jl

This file was deleted.

6 changes: 5 additions & 1 deletion src/YaoPlots.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
module YaoPlots

using Yao
import Luxor

export CircuitStyles, CircuitGrid, circuit_canvas, vizcircuit, darktheme!, lighttheme!
export plot

plot(;kwargs...) = x->plot(x;kwargs...)
plot(blk::AbstractBlock; kwargs...) = vizcircuit(blk; kwargs...)

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

end
58 changes: 47 additions & 11 deletions src/vizcircuit.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
using Yao
using BitBasis
import Luxor

export CircuitStyles, CircuitGrid, circuit_canvas, vizcircuit, darktheme!, lighttheme!

module CircuitStyles
using Luxor
const unit = Ref(60) # number of points in a unit
Expand Down Expand Up @@ -233,7 +227,7 @@ end

function initialize!(c::CircuitGrid; starting_texts, starting_offset)
starting_texts !== nothing && for j=1:nline(c)
CircuitStyles.render(c.gatestyles.text, (c[starting_offset, j], string(starting_texts[j])))
CircuitStyles.render(c.gatestyles.text, (c[starting_offset, j], string(starting_texts[j]), c.w_depth, c.w_line))
end
end

Expand All @@ -242,7 +236,7 @@ function finalize!(c::CircuitGrid; show_ending_bar, ending_offset, ending_texts)
for j=1:nline(c)
show_ending_bar && CircuitStyles.render(c.gatestyles.line, c[(i, j-0.2); (i, j+0.2)])
CircuitStyles.render(c.gatestyles.line, c[(i, j); (c.frontier[j], j)])
ending_texts !== nothing && CircuitStyles.render(c.gatestyles.text, (c[i+ending_offset, j], string(ending_texts[j])))
ending_texts !== nothing && CircuitStyles.render(c.gatestyles.text, (c[i+ending_offset, j], string(ending_texts[j]), c.w_depth, c.w_line))
end
end

Expand Down Expand Up @@ -310,7 +304,8 @@ function draw!(c::CircuitGrid, m::YaoBlocks.Measure, address, controls)
for (i, loc) in enumerate(locs)
_draw!(c, [(loc, c.gatestyles.measure, "")])
if m.postprocess isa ResetTo
val = readbit(m.postprocess.x, i)
# read i-th bit value
val = Int(m.postprocess.x)>>(i-1) & 1
_draw!(c, [(loc, c.gatestyles.g, val == 1 ? "P₁" : "P₀")])
end
end
Expand Down Expand Up @@ -345,7 +340,7 @@ get_brush_texts(c, ::EasyBuild.SqrtYGate) = (c.gatestyles.g, "√Y")

pretty_angle(theta) = string(theta)
function pretty_angle(theta::AbstractFloat)
c = ZXCalculus.continued_fraction(theta/π, 10)
c = continued_fraction(theta/π, 10)
if c.den < 100
res = if c.num == 1
"π"
Expand All @@ -364,6 +359,18 @@ function pretty_angle(theta::AbstractFloat)
"$(round(theta; digits=2))"
end
end
"""
continued_fraction(ϕ, n::Int) -> Rational
Obtain `s` and `r` from `ϕ` that satisfies `|s//r - ϕ| ≦ 1/2r²`
"""
function continued_fraction(fl, n::Int)
if n == 1 || abs(mod(fl, 1)) < 1e-10
Rational(floor(Int, fl), 1)
else
floor(Int, fl) + 1//continued_fraction(1/mod(fl, 1), n-1)
end
end

get_brush_texts(c, ::ConstGate.SdagGate) = (c.gatestyles.g, "S'")
get_brush_texts(c, ::ConstGate.TdagGate) = (c.gatestyles.g, "T'")
Expand All @@ -389,7 +396,36 @@ get_cbrush_texts(c, ::XGate) = (c.gatestyles.not, "")
get_cbrush_texts(c, ::ZGate) = (c.gatestyles.c, "")

# front end
plot(blk::AbstractBlock; kwargs...) = vizcircuit(blk; kwargs...)
"""
vizcircuit(circuit; w_depth=0.85, w_line=0.75, format=:svg, filename=nothing,
show_ending_bar=false, starting_texts=nothing, starting_offset=-0.3,
ending_texts=nothing, ending_offset=0.3)
Visualize a `Yao` quantum circuit.
### Keyword Arguments
* `w_depth` is the circuit column width.
* `w_line` is the circuit row width.
* `format` can be `:svg`, `:png` or `:pdf`.
* `filename` can be `"*.svg"`, `"*.png"`, `"*.pdf"` or nothing (not saving to a file).
* `starting_texts` and `ending_texts` are texts shown before and after the circuit.
* `starting_offset` and `end_offset` are offsets (real values) for starting and ending texts.
* `show_ending_bar` is a boolean switch to show ending bar.
### Styles
To change the gates styles like colors and lines, please modify the constants in submodule `CircuitStyles`.
They are defined as:
* CircuitStyles.unit = Ref(60) # number of points in a unit
* CircuitStyles.r = Ref(0.2) # size of nodes
* 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.linecolor = Ref("#000000") # line color
* CircuitStyles.gate_bgcolor = Ref("transparent") # gate background color
* CircuitStyles.textcolor = Ref("#000000") # text color
"""
function vizcircuit(blk::AbstractBlock; w_depth=0.85, w_line=0.75, format=:svg, filename=nothing,
show_ending_bar=false, starting_texts=nothing, starting_offset=-0.3,
ending_texts=nothing, ending_offset=0.3, gatestyles=CircuitStyles.GateStyles())
Expand Down
Loading

0 comments on commit 14ff467

Please sign in to comment.