Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc + Structural Improvement #103

Merged
merged 11 commits into from
Oct 20, 2023
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

Check warning on line 9 in src/Utils/parameter.jl

View check run for this annotation

Codecov / codecov/patch

src/Utils/parameter.jl#L9

Added line #L9 was not covered by tests
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
Loading