Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.jl.*.cov
*.jl.mem

build/
docs/build/
docs/site/
docs/src/tutorial/
Expand Down
14 changes: 4 additions & 10 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,19 @@ version = "0.1.0"

[deps]
BitBasis = "50ba71b6-fa0f-514d-ae9a-0916efc90dcf"
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
LuxurySparse = "d05aeea4-b7d4-55ac-b691-9e7fabb07ba2"
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Yao = "5872b779-8223-5990-8dd0-5abbb0748c8c"
YaoArrayRegister = "e600142f-9330-5003-8abb-0ebd767abc51"
YaoBlocks = "418bc28f-b43b-5e0b-a6e7-61bbc1a2c1df"
YaoExtensions = "7a06699c-c960-11e9-3c98-9f78548b5f0f"

[compat]
julia = ">=1.0.0"
Yao = ">=0.4.0"
julia = ">=1.0.0"

[extras]
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "OrdinaryDiffEq"]
test = ["Test"]
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

A curated implementation of quantum algorithms with [Yao.jl](https://github.com/QuantumBFS/Yao.jl)

*Note*: part of functionalities has been moved to [YaoExtensions](https://github.com/QuantumBFS/YaoExtensions.jl).

## Installation

QuAlgorithmZoo.jl is not registered yet, please use the following command:
Expand All @@ -19,22 +21,26 @@ Disclaimer: **this package is still under development and needs further polish.*

## Contents

- [x] Quantum Circuit Born Machine
- [x] [QFT](https://github.com/QuantumBFS/YaoExtensions.jl)
- [x] Grover search
- [x] HHL
- [x] QFT
- [x] Phase Estimation
- [x] QuGAN
- [x] QCBM
- [x] Hamiltonian Solver
- [x] QAOA
- [x] Variational quantum eigensolver
- [x] QuODE
- [x] Imaginary Time Evolution Quantum Eigensolver
- [x] Variational Quantum Eigensolver
- [x] Hadamard Test
- [x] State Overlap Algorithms
- [x] Quantum SVD

In examples folder, you will find

- [x] HHL
- [x] QAOA
- [x] Quantum Circuit Born Machine
- [x] QuGAN
- [x] Shor

- [x] [QuODE](https://github.com/QuantumBFS/QuDiffEq.jl)
- [x] [TensorNetwork Inspired Circuits](https://github.com/GiggleLiu/QuantumPEPS.jl)

## License

QuAlgorithmZoo.jl is released under Apache License 2.0.
12 changes: 12 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[deps]
BitBasis = "50ba71b6-fa0f-514d-ae9a-0916efc90dcf"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77"
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
Weave = "44d3d7a6-8a23-5bf8-98c5-b353f8df5ec9"
YaoArrayRegister = "e600142f-9330-5003-8abb-0ebd767abc51"
YaoBase = "a8f54c17-34bc-5a9d-b050-f522fe3f755f"
YaoBlocks = "418bc28f-b43b-5e0b-a6e7-61bbc1a2c1df"
76 changes: 39 additions & 37 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,56 @@ add Documenter Literate Plots Yao

using Documenter, Literate, QuAlgorithmZoo

const Examples = ["Grover", "VQE", "Shor"]

const PATH = (
tutorial = joinpath(@__DIR__, "src/tutorial"),
examples = joinpath(@__DIR__, "..", "examples")
)

function process_literate_scripts(;excludes=["make.jl", "README.md"])
function process_literate_scripts()
TUTORIALS = []
for (root, dirs, files) in walkdir(PATH.examples)
for file in files
file in excludes && continue
filepath = joinpath(root, file)
Literate.markdown(filepath, PATH.tutorial)

filename, _ = splitext(file)
mdfile = join([filename, ".md"])
# TODO: use PATH.tutorial rather then manual path
push!(TUTORIALS, relpath(joinpath("tutorial", mdfile)))
end
for token in Examples
file = "$token.jl"
filepath = joinpath(PATH.examples, token, file)
Literate.markdown(filepath, PATH.tutorial)

filename, _ = splitext(file)
mdfile = join([filename, ".md"])
# TODO: use PATH.tutorial rather then manual path
push!(TUTORIALS, relpath(joinpath("tutorial", mdfile)))
end
TUTORIALS
end

const TUTORIALS = process_literate_scripts()

#-----------------------------------------------

makedocs(
modules = [QuAlgorithmZoo],
clean = false,
format = :html,
sitename = "Quantum Algorithm Zoo",
linkcheck = !("skiplinks" in ARGS),
analytics = "UA-89508993-1",
pages = [
"Home" => "index.md",
"Tutorial" => TUTORIALS,
"Manual" => Any[
"man/zoo.md",
function generate(islocal::Bool="local" in ARGS)
makedocs(
modules = [QuAlgorithmZoo],
clean = false,
format = :html,
sitename = "Quantum Algorithm Zoo",
linkcheck = !("skiplinks" in ARGS),
analytics = "UA-89508993-1",
pages = [
"Home" => "index.md",
"Algorithms" => process_literate_scripts(),
"Manual" => Any[
"man/zoo.md",
],
],
],
html_prettyurls = !("local" in ARGS),
html_canonical = "https://quantumbfs.github.io/QuAlgorithmZoo.jl/latest/",
)
html_prettyurls = !islocal,
html_canonical = "https://quantumbfs.github.io/QuAlgorithmZoo.jl/latest/",
)

deploydocs(
repo = "github.com/QuantumBFS/QuAlgorithmZoo.jl.git",
target = "build",
julia = "1.0",
deps = nothing,
make = nothing,
)
end

deploydocs(
repo = "github.com/QuantumBFS/QuAlgorithmZoo.jl.git",
target = "build",
julia = "1.0",
deps = nothing,
make = nothing,
)
generate(true)
5 changes: 2 additions & 3 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ A curated implementation of quantum algorithms with [Yao.jl](https://github.com/
## Tutorial
```@contents
Pages = [
"tutorial/Grover.md",
"tutorial/QCBM.md",
"tutorial/QuGAN.md",
"tutorial/VQE.md",
"tutorial/Shor.md",
]
Depth = 1
```
Expand Down
5 changes: 5 additions & 0 deletions docs/src/man/zoo.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@
Modules = [QuAlgorithmZoo]
Order = [:module, :constant, :type, :macro, :function]
```

```@autodocs
Modules = [QuAlgorithmZoo.NumberTheory]
Order = [:module, :constant, :type, :macro, :function]
```
35 changes: 0 additions & 35 deletions examples/Grover.jl

This file was deleted.

119 changes: 119 additions & 0 deletions examples/Grover/Grover.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# # [Grover Search](@id Grover)
using Yao
using YaoExtensions: variational_circuit
using LinearAlgebra

# ## Grover Step
# A single grover step is consist of applying oracle circuit and reflection circuit.
# The `reflection_circuit` function takes the wave function generator `U` as the input and returns `U|0><0|U'`.
function grover_step!(reg::AbstractRegister, oracle, U::AbstractBlock)
apply!(reg |> oracle, reflect_circuit(U))
end

function reflect_circuit(gen::AbstractBlock{N}) where N
reflect0 = control(N, -collect(1:N-1), N=>-Z)
chain(gen', reflect0, gen)
end

# Compute the propotion of target states to estimate the number of iterations,
# which requires computing the output state.
function solution_state(oracle, gen::AbstractBlock{N}) where N
reg= zero_state(N) |> gen
reg.state[real.(statevec(ArrayReg(ones(ComplexF64, 1<<N)) |> oracle)) .> 0] .= 0
normalize!(reg)
end

function num_grover_step(oracle, gen::AbstractBlock{N}) where N
reg = zero_state(N) |> gen
ratio = abs2(solution_state(oracle, gen)'*reg)
Int(round(pi/4/sqrt(ratio)))-1
end

# #### Run
# First, we define the problem by an oracle, it finds bit string `bit"000001100100"`.
num_bit = 12
oracle = matblock(Diagonal((v = ones(ComplexF64, 1<<num_bit); v[Int(bit"000001100100")+1]*=-1; v)))

# then solve the above problem
gen = repeat(num_bit, H, 1:num_bit)
reg = zero_state(num_bit) |> gen

target_state = solution_state(oracle, gen)

for i = 1:num_grover_step(oracle, gen)
grover_step!(reg, oracle, gen)
overlap = abs(reg'*target_state)
println("step $(i-1), overlap = $overlap")
end

# ## Rejection Sampling
# In practise, it is often not possible to determine the number of iterations before actual running.
# we can use rejection sampling technique to avoid estimating the number of grover steps.

using Random; Random.seed!(2) #src

# In a single try, we `apply` the grover algorithm for `nstep` times.
function single_try(oracle, gen::AbstractBlock{N}, nstep::Int; nbatch::Int) where N
reg = zero_state(N+1; nbatch=nshot)
focus!(reg, 1:N) do r
r |> gen
for i = 1:nstep
grover_step!(r, oracle, gen)
end
return r
end
reg |> checker
res = measure_remove!(reg, (N+1))
return res, reg
end

# After running the grover search, we have a checker program that flips the ancilla qubit
# if the output is the desired value, we assume the checker program can be implemented in polynomial time.
# to gaurante the output is correct.
# We contruct a checker "program", if the result is correct, flip the ancilla qubit
ctrl = -collect(1:num_bit); ctrl[[3,6,7]] *= -1
checker = control(num_bit+1,ctrl, num_bit+1=>X)

# The register is batched, with batch dimension `nshot`.
# [`focus!`](@ref Yao.focus!) views the first 1-N qubts as system.
# For a batched register, [`measure_remove!`](@ref Yao.measure_remove!)
# returns a vector of bitstring as output.

# #### Run
maxtry = 100
nshot = 3

for nstep = 0:maxtry
println("number of iter = $nstep")
res, reg = single_try(oracle, gen, nstep; nbatch=3)

## success!
if any(==(1), res)
overlap_final = viewbatch(reg, findfirst(==(1), res))'*target_state
println("success, overlap = $(overlap_final)")
break
end
end

# The final state has an overlap of `1` with the target state.

# ## Amplitude Amplification
# Given a circuit to generate a state,
# now we want to project out the subspace with [1,3,5,8,9,11,12] fixed to 1 and [4,6] fixed to 0.
# We can construct an oracle
evidense = [1, 3, -4, 5, -6, 8, 9, 11, 12]
function inference_oracle(nbit::Int, locs::Vector{Int})
control(nbit, locs[1:end-1], abs(locs[end]) => (locs[end]>0 ? Z : -Z))
end
oracle = inference_oracle(nqubits(reg), evidense)

# We use a variational circuit generator defined in `YaoExtensions`
gen = dispatch!(variational_circuit(num_bit), :random)
reg = zero_state(num_bit) |> gen

# #### Run
solution = solution_state(oracle, gen)
for i = 1:num_grover_step(oracle, gen)
grover_step!(reg, oracle, gen)
println("step $(i-1), overlap = $(abs(reg'*solution))")
end
Loading