Skip to content

Commit

Permalink
Doc + Structural Improvement (#103)
Browse files Browse the repository at this point in the history
* add placeholder for doc imporvement

* relocate utils and zx into own module

* port most of ZXW

* finish porting ZXW

* finish all porting

* change docs

* fix docs not building issue

* restructure module folders

* add usings to each test file

* replace import with using
  • Loading branch information
exAClior authored Oct 20, 2023
1 parent 6cbafe4 commit ec0d611
Show file tree
Hide file tree
Showing 53 changed files with 547 additions and 581 deletions.
4 changes: 2 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ using Documenter
using DocThemeIndigo

using ZXCalculus
using ZXCalculus: ZXW, ZW
using Multigraphs

indigo = DocThemeIndigo.install(ZXCalculus)
makedocs(;
modules = [ZXCalculus, ZXW, ZW],
modules = Module[ZXCalculus, ZXCalculus.ZX, ZXCalculus.ZXW, ZXCalculus.ZW, ZXCalculus.Utils, ZXCalculus.Application, ZXCalculus.PMG],
format=Documenter.HTML(;
# ...
# put your indigo css in assets
Expand All @@ -21,6 +20,7 @@ makedocs(;
],
repo = "https:/github.com/QuantumBFS/ZXCalculus.jl",
sitename = "ZXCalculus.jl",
warnonly=true,
)

deploydocs(repo = "github.com/QuantumBFS/ZXCalculus.jl.git")
148 changes: 3 additions & 145 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -1,148 +1,6 @@
# APIs

```@meta
CurrentModule = ZXCalculus
```@autodocs
Modules = [ZXCalculus, ZXCalculus.ZX, ZXCalculus.ZXW, ZXCalculus.ZW, ZXCalculus.Utils, ZXCalculus.PMG]
Order = [:function, :type]
```

## ZX-diagrams

```@docs
ZXCalculus.ZXDiagram
ZXDiagram(nbit::Int)
ZXCalculus.ZXGraph
ZXCalculus.ZXGraph(::ZXDiagram)
ZXCalculus.ZXLayout
ZXCalculus.qubit_loc
spider_type(zxd::ZXDiagram{T, P}, v::T) where {T<:Integer, P}
ZXCalculus.phase(zxd::ZXDiagram{T, P}, v::T) where {T<:Integer, P}
Graphs.nv(zxd::ZXDiagram)
Graphs.ne(::ZXDiagram)
Graphs.neighbors(::ZXDiagram, v)
ZXCalculus.is_interior(zxg::ZXGraph{T, P}, v::T) where {T, P}
ZXCalculus.add_spider!
ZXCalculus.insert_spider!
ZXCalculus.rem_spiders!
ZXCalculus.rem_spider!
```

## Pushing gates
```@docs
ZXCalculus.push_gate!
ZXCalculus.pushfirst_gate!
```

## Simplification
```@docs
ZXCalculus.phase_teleportation
ZXCalculus.clifford_simplification
Rule{L} where L
ZXCalculus.simplify!
ZXCalculus.replace!
ZXCalculus.match
ZXCalculus.rewrite!
ZXCalculus.Match
```

## Circuit extraction
```@docs
ZXCalculus.circuit_extraction(zxg::ZXGraph{T, P}) where {T, P}
```

## ZXW-diagram
```@docs
ZXCalculus.ZXW.add_inout!
ZXCalculus.ZXW.substitute_variables!
ZXCalculus.biadjacency
ZXCalculus.ZXW.rem_spider!
ZXCalculus.continued_fraction
ZXCalculus.ZXW.symbol_vertices
ZXCalculus.ZXW.dagger
ZXCalculus.ZXW.add_spider!
ZXCalculus.tcount
ZXCalculus.Phase
ZXCalculus.round_phases!
ZXCalculus.gaussian_elimination
ZXCalculus.Scalar
ZXCalculus.ZXW.expval_circ!
Graphs.SimpleGraphs.rem_edge!
ZXCalculus.ZXW.parameter
ZXCalculus.ZXW.int_prep!
ZXCalculus.update_frontier!
ZXCalculus.ZXW.integrate!
ZXCalculus.set_column!
ZXCalculus.set_phase!
ZXCalculus.prev
ZXCalculus.ancilla_extraction
Graphs.SimpleGraphs.add_edge!
ZXCalculus.ZXW.stack_zxwd!
ZXCalculus.ZXW.get_outputs
ZXCalculus.scalar
ZXCalculus.get_inputs
ZXCalculus.ZW.get_inputs
ZXCalculus.column_loc
ZXCalculus.GEStep
ZXCalculus.ZXW.spider_type
ZXCalculus.ZXW.print_spider
ZXCalculus.ZXW.Parameter
ZXCalculus.ZXW.nqubits
ZXCalculus.set_qubit!
ZXCalculus.ZXW.insert_wtrig!
ZXCalculus.ZXW.concat!
ZXCalculus.ZXW.rem_spiders!
ZXCalculus.ZXW.insert_spider!
ZXCalculus.set_loc!
ZXCalculus.spiders
ZXCalculus.split_edge!
ZXCalculus.ZXW.import_edges!
ZXCalculus.get_outputs
ZXCalculus.ZXW.get_inputs
ZXCalculus.ZXW.import_non_in_out!
ZXCalculus.ZXW.set_phase!
ZXCalculus.ZXW.nout
```

# Planar Multigraph
```@docs
ZXCalculus.PlanarMultigraph
ZXCalculus.is_boundary
ZXCalculus.trace_face
ZXCalculus.new_edge
ZXCalculus.ϕ
ZXCalculus.nqubits
ZXCalculus.erase_facet!
ZXCalculus.create_face!
ZXCalculus.surrounding_half_edge
ZXCalculus.add_facet_to_boarder!
ZXCalculus.split_facet!
ZXCalculus.split_vertex!
ZXCalculus.add_vertex_and_facet_to_boarder!
ZXCalculus.create_edge!
ZXCalculus.join_facet!
ZXCalculus.create_vertex!
ZXCalculus.σ_inv
ZXCalculus.σ
ZXCalculus.make_hole!
ZXCalculus.gc_vertex!
ZXCalculus.HalfEdge
ZXCalculus.out_half_edge
ZXCalculus.n_conn_comp
ZXCalculus.join_vertex!
```

# ZW-diagrams
```@docs
ZXCalculus.ZW.ZWDiagram
ZXCalculus.ZW.insert_spider!
ZXCalculus.ZW.get_output_idx
ZXCalculus.ZW.nqubits
ZXCalculus.ZW.round_phases!
ZXCalculus.ZW.nout
ZXCalculus.ZW.get_input_idx
ZXCalculus.ZW.set_phase!
ZXCalculus.ZW.get_outputs
ZXCalculus.ZW.add_spider!
ZXCalculus.ZW.parameter
ZXCalculus.ZW.print_spider
ZXCalculus.ZW.spider_type
```

42 changes: 12 additions & 30 deletions docs/src/tutorials.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Tutorials

ZX-diagrams are the basic objects in ZX-calculus. In our implementation, each ZX-diagram consists of a multigraph and vertices information including the type of vertices and the phase of vertices. [`ZXDiagram`](@ref) is the data structure for representing
ZX-diagrams are the basic objects in ZX-calculus. In our implementation, each ZX-diagram consists of a multigraph and vertices information including the type of vertices and the phase of vertices. [`ZXCalculus.ZX.ZXDiagram`](@ref) is the data structure for representing
ZX-diagrams.

There are 5 types of vertices: `In`, `Out`, `Z`, `X`, `H` which represent the inputs of quantum circuits, outputs of quantum circuits, Z-spiders, X-spiders, H-boxes. There can be a phase for each vertex. The phase of a vertex of `Z` or `X` is the phase of a Z or X-spider. For the other types of vertices, the phase is zero by default.
Expand All @@ -9,21 +9,15 @@ In each `ZXDiagram`, there is a `layout` for storing layout information for the

## Construction of ZX-diagrams

As we usually focus on quantum circuits, the recommended way to construct `ZXDiagram`s is by the following function.
```@docs
ZXDiagram(nbit::T) where T<:Integer
```
Then one can use `push_gate!` to push quantum gates at the end of a quantum circuit, or use `pushfirst_gate!` to push gates at the beginning of a quantum circuit.
```@docs
push_gate!(zxd::ZXDiagram{T, P}, ::Val{:Z}, loc::T, phase = zero(P); autoconvert::Bool=true) where {T, P}
pushfirst_gate!(zxd::ZXDiagram{T, P}, ::Val{:Z}, loc::T, phase::P = zero(P)) where {T, P}
```
As we usually focus on quantum circuits, the recommended way to construct `ZXDiagram`s is by the following function [`ZXCalculus.ZX.ZXDiagram(nbits::T) where {T<:Integer}`](@ref).

Then one can use [`ZXCalculus.ZX.push_gate!`](@ref) to push quantum gates at the end of a quantum circuit, or use [`ZXCalculus.ZX.pushfirst_gate!`](@ref)to push gates at the beginning of a quantum circuit.

For example, in `example\ex1.jl`, one can generate the demo circuit by the function
```julia
using ZXCalculus
function generate_example()
zxd = ZXDiagram(4)
zxd = ZXCalculus.ZX.ZXDiagram(4)
push_gate!(zxd, Val(:Z), 1, 3//2)
push_gate!(zxd, Val(:H), 1)
push_gate!(zxd, Val(:Z), 1, 1//2)
Expand Down Expand Up @@ -53,11 +47,7 @@ function generate_example()
end
```

In the paper [arXiv:1902.03178](https://arxiv.org/abs/1902.03178), they introduced a special type of ZX-diagrams, graph-like ZX-diagrams, which consists of Z-spiders with 2 different types of edges only. We use [`ZXGraph`](@ref) for representing this special type of ZX-diagrams. One can convert a `ZXDiagram` into a `ZXGraph` by simply use the construction function:
```@docs
ZXGraph(zxd::ZXDiagram{T, P}) where {T, P}
```

In the paper [arXiv:1902.03178](https://arxiv.org/abs/1902.03178), they introduced a special type of ZX-diagrams, graph-like ZX-diagrams, which consists of Z-spiders with 2 different types of edges only. We use [`ZXCalculus.ZX.ZXGraph`](@ref) for representing this special type of ZX-diagrams. One can convert a `ZXDiagram` into a `ZXGraph` by simply use the construction function [`ZXCalculus.ZX.ZXGraph(zxd::ZXCalculus.ZX.ZXDiagram{T, P}) where {T, P}`](@ref):

## Visualization

Expand All @@ -75,18 +65,12 @@ With `ZXCalculus.jl`, one can manipulate ZX-diagrams at different levels.
- Rewriting ZX-diagrams with rules
- Rewriting ZX-diagrams at the graphical level

The highest level is the circuit simplification algorithms. By now there are two algorithms are available:
```@docs
clifford_simplification(circ::ZXDiagram)
phase_teleportation(circ::ZXDiagram{T, P}) where {T, P}
```
The highest level is the circuit simplification algorithms. By now there are two algorithms are available: [`ZXCalculus.ZX.clifford_simplification`](@ref) and [`ZXCalculus.ZX.phase_teleportation`](ref).

The input of these algorithms will be a ZX-diagram representing a quantum circuit. And these algorithms will return a ZX-diagram of a simplified quantum circuit. For more details, please refer to [Clifford simplification](https://arxiv.org/abs/1902.03178) and [phase teleportation](https://arxiv.org/abs/1903.10477).

One can rewrite ZX-diagrams with rules. In `ZXCalculus.jl`, rules are identified as data structures [`Rule`](@ref). And we can use the following functions to simplify ZX-diagrams:
```@docs
simplify!(r::ZXCalculus.AbstractRule, zxd::AbstractZXDiagram)
replace!(r::ZXCalculus.AbstractRule, zxd::AbstractZXDiagram)
```
One can rewrite ZX-diagrams with rules. In `ZXCalculus.jl`, rules are identified as data structures [`Rule`](@ref). And we can use the following functions to simplify ZX-diagrams: [`ZXCalculus.ZX.simplify!`](@ref) and [`ZXCalculus.ZX.replace!`](@ref).

For example, in `example/ex1.jl`, we can get a simplified graph-like ZX-diagram by:
```julia
zxd = generate_example()
Expand All @@ -99,10 +83,8 @@ replace!(Rule{:pab}(), zxg)
The difference between `simplify!` and `replace!` is that `replace!` only matches vertices and tries to rewrite with all matched vertices once, while `simplify!` will keep matching until nothing matched.

The following APIs are useful for more detailed rewriting.
```@docs
match(::ZXCalculus.AbstractRule, zxd::AbstractZXDiagram{T, P}) where {T, P}
rewrite!(r::ZXCalculus.AbstractRule, zxd::AbstractZXDiagram{T, P}, matches::Vector{Match{T}}) where {T, P}
```
1. [`ZXCalculus.ZX.match`](@ref)
2. [`ZXCalculus.ZX.rewrite!`](@ref)

The lowest level for rewriting ZX-diagrams is manipulating the multigraphs directly. This way is not recommended unless one wants to develop new rules in ZX-calculus.

Expand Down
9 changes: 9 additions & 0 deletions src/Application/Application.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Application

using OMEinsum, MLStyle
using ..ZXW: ZXWDiagram, Z, X, W, H, D, Input, Output
using ..Utils: PiUnit, Factor, Parameter, unwrap_scalar
using ..ZXW: get_outputs, get_inputs, degree, neighbors, vertices, scalar, nin, nout

include("to_eincode.jl")
end # module Application
2 changes: 1 addition & 1 deletion src/to_eincode.jl → src/Application/to_eincode.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function to_eincode(zxwd::ZXWDiagram{T,P}) where {T,P}

scalar_tensor = zeros(ComplexF64, ())

scalar_tensor[] = ZXCalculus.unwrap_scalar(scalar(zxwd))
scalar_tensor[] = unwrap_scalar(scalar(zxwd))
push!(ixs, Tuple{T,T,T}[])
push!(tensors, scalar_tensor)
return EinCode(ixs, iy), tensors
Expand Down
12 changes: 12 additions & 0 deletions src/PMG/PMG.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module PMG

using Graphs

import Graphs: AbstractEdge, src, dst, nv, ne, neighbors
import Graphs.SimpleGraphs: vertices

export HalfEdge, src, dst, new_edge, PlanarMultigraph

include("planar_multigraph.jl")

end # module PlanarMultigraph
4 changes: 0 additions & 4 deletions src/planar_multigraph.jl → src/PMG/planar_multigraph.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import Graphs: AbstractEdge, src, dst, nv, ne, neighbors
import Graphs.SimpleGraphs: vertices
export HalfEdge, src, dst, new_edge, PlanarMultigraph

"""
HalfEdge{T<:Integer}(src ,dst)
Expand Down
10 changes: 10 additions & 0 deletions src/Utils/Utils.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Utils

using Expronicon.ADT: @const_use, @adt
using MLStyle

include("scalar.jl")
include("phase.jl")
include("parameter.jl")

end
21 changes: 20 additions & 1 deletion src/parameter.jl → src/Utils/parameter.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
using .ZXW: Parameter, PiUnit, Factor
"""
Parameter
The Algebraic Data Type for representing parameter related to spider.
`PiUnit(x)` represents the the phase of a number `exp(im*x*π)`.
`Factor(x)` represents a number `x`.
"""
@adt Parameter begin

struct PiUnit
pu
pu_type::Type
end

struct Factor
f::Number
f_type::Type
end

end
@const_use Parameter:PiUnit, Factor

"""
Parameter
Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions src/scalar.jl → src/Utils/scalar.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export Scalar

"""
Scalar
Expand Down
43 changes: 43 additions & 0 deletions src/ZW/ZW.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module ZW
using Expronicon.ADT: @adt, @const_use
using MLStyle, Graphs
using ..ZXW: _round_phase, Parameter

# these will be changed to using PlanarMultigraph: vertices after we split out package
using ..PMG:
vertices,
nv,
has_vertex,
ne,
neighbors,
rem_edge!,
add_edge!,
degree,
next,
split_vertex!,
split_edge!,
face,
trace_face,
make_hole!,
add_vertex_and_facet_to_boarder!,
split_facet!,
twin,
prev,
add_multiedge!,
join_facet!,
trace_vertex,
join_vertex!

# these remains
using ..Utils: add_phase!, Scalar, Phase, Parameter, PiUnit, Factor, add_power!
using ..PMG: PlanarMultigraph, HalfEdge, new_edge, src, dst
import ..Utils: add_power!
import ..ZX: add_global_phase!, scalar, spiders, rem_spider!
import Graphs.rem_edge!

export ZWDiagram

include("zw_adt.jl")
include("zw_diagram.jl")
include("zw_utils.jl")
end # module ZW
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit ec0d611

Please sign in to comment.