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

Implement ProjectedEntangledPair ansatz #71

Merged
merged 12 commits into from
Jul 5, 2023
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ makedocs(
"Quantum Tensor Networks"=>[
"Introduction" => "quantum/index.md",
"Matrix Product States (MPS)" => "quantum/mps.md",
"Projected Entangled Pair States (PEPS)" => "quantum/peps.md",
],
"Examples"=>[
"Google's Quantum Advantage experiment" => "examples/google-rqc.md",
Expand Down
51 changes: 51 additions & 0 deletions docs/src/quantum/peps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Projected Entangled Pair States (PEPS)

Projected Entangled Pair States (PEPS) are a Quantum Tensor Network ansatz whose tensors are laid out in a 2D lattice. Depending on the boundary conditions, the chains can be open or closed (i.e. periodic boundary conditions).

```@setup viz
using Makie
Makie.inline!(true)
set_theme!(resolution=(800,400))

using CairoMakie

using Tenet
using NetworkLayout
```

```@example viz
fig = Figure() # hide

tn_open = rand(PEPS{Open}, rows=10, cols=10, χ=4) # hide
tn_periodic = rand(PEPS{Periodic}, rows=10, cols=10, χ=4) # hide

plot!(fig[1,1], tn_open, layout=Stress(seed=1)) # hide
plot!(fig[1,2], tn_periodic, layout=Stress(seed=10,dim=2,iterations=100000)) # hide

Label(fig[1,1, Bottom()], "Open") # hide
Label(fig[1,2, Bottom()], "Periodic") # hide

fig # hide
```

## Projected Entangled Pair Operators (PEPO)

```@example viz
fig = Figure() # hide

tn_open = rand(PEPO{Open}, rows=10, cols=10, χ=4) # hide
tn_periodic = rand(PEPO{Periodic}, rows=10, cols=10, χ=4) # hide

plot!(fig[1,1], tn_open, layout=Stress(seed=1)) # hide
plot!(fig[1,2], tn_periodic, layout=Stress(seed=10,dim=2,iterations=100000)) # hide

Label(fig[1,1, Bottom()], "Open") # hide
Label(fig[1,2, Bottom()], "Periodic") # hide

fig # hide
```

```@docs
ProjectedEntangledPair
ProjectedEntangledPair(::Any)
```
192 changes: 192 additions & 0 deletions src/Quantum/PEP.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
using UUIDs: uuid4

"""
ProjectedEntangledPair{P<:Plug,B<:Boundary} <: Quantum

A generic ansatz representing Projected Entangled Pair States (PEPS) and Projected Entangled Pair Operators (PEPO).
Type variable `P` represents the `Plug` type (`State` or `Operator`) and `B` represents the `Boundary` type (`Open` or `Periodic`).

# Ansatz Fields

- `χ::Union{Nothing,Int}` Maximum virtual bond dimension.
"""
abstract type ProjectedEntangledPair{P,B} <: Quantum where {P<:Plug,B<:Boundary} end

boundary(::Type{<:ProjectedEntangledPair{P,B}}) where {P,B} = B
plug(::Type{<:ProjectedEntangledPair{P}}) where {P} = P

Check warning on line 16 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L15-L16

Added lines #L15 - L16 were not covered by tests

function ProjectedEntangledPair{P}(arrays; boundary::Type{<:Boundary} = Open, kwargs...) where {P<:Plug}
ProjectedEntangledPair{P,boundary}(arrays; kwargs...)

Check warning on line 19 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L18-L19

Added lines #L18 - L19 were not covered by tests
end

metadata(T::Type{<:ProjectedEntangledPair}) = merge(metadata(supertype(T)), @NamedTuple begin
χ::Union{Nothing,Int}

Check warning on line 23 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L22-L23

Added lines #L22 - L23 were not covered by tests
end)

function checkmeta(::Type{ProjectedEntangledPair{P,B}}, tn::TensorNetwork) where {P,B}

Check warning on line 26 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L26

Added line #L26 was not covered by tests
# meta has correct value
isnothing(tn.χ) || tn.χ > 0 || return false

Check warning on line 28 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L28

Added line #L28 was not covered by tests

# no virtual index has dimensionality bigger than χ
all(i -> isnothing(tn.χ) || size(tn, i) <= tn.χ, labels(tn, :virtual)) || return false

Check warning on line 31 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L31

Added line #L31 was not covered by tests

return true

Check warning on line 33 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L33

Added line #L33 was not covered by tests
end

function _sitealias(::Type{ProjectedEntangledPair{P,Open}}, order, size, pos) where {P<:Plug}
m, n = size
i, j = pos

Check warning on line 38 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L36-L38

Added lines #L36 - L38 were not covered by tests

order = [order...]

Check warning on line 40 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L40

Added line #L40 was not covered by tests

filter(order) do dir
!(i == 1 && dir === :u || i == m && dir === :d || j == 1 && dir === :l || j == n && dir === :r)

Check warning on line 43 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L42-L43

Added lines #L42 - L43 were not covered by tests
end
end
_sitealias(::Type{ProjectedEntangledPair{P,Periodic}}, order, _, _) where {P<:Plug} = tuple(order...)

Check warning on line 46 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L46

Added line #L46 was not covered by tests

defaultorder(::Type{ProjectedEntangledPair{State}}) = (:l, :r, :u, :d, :o)
defaultorder(::Type{ProjectedEntangledPair{Operator}}) = (:l, :r, :u, :d, :i, :o)

Check warning on line 49 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L48-L49

Added lines #L48 - L49 were not covered by tests

"""
ProjectedEntangledPair{P,B}(arrays::Matrix{AbstractArray}; χ::Union{Nothing,Int} = nothing, order = defaultorder(ProjectedEntangledPair{P}))

Construct a [`TensorNetwork`](@ref) with [`ProjectedEntangledPair`](@ref) ansatz, from the arrays of the tensors.

# Keyword Arguments

- `χ` Maximum virtual bond dimension. Defaults to `nothing`.
- `order` Order of the tensor indices on `arrays`. Defaults to `(:l, :r, :u, :d, :o)` if `P` is a `State`, `(:l, :r, :u, :d, :i, :o)` if `Operator`.
"""
function ProjectedEntangledPair{P,B}(

Check warning on line 61 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L61

Added line #L61 was not covered by tests
arrays;
χ = nothing,
order = defaultorder(ProjectedEntangledPair{P}),
metadata...,
) where {P<:Plug,B<:Boundary}
issetequal(order, defaultorder(ProjectedEntangledPair{P})) || throw(

Check warning on line 67 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L67

Added line #L67 was not covered by tests
ArgumentError(
"`order` must be a permutation of $(join(String.(defaultorder(ProjectedEntangledPair{P})), ',', " and "))",
),
)

m, n = size(arrays)
hinds = Dict((i, j) => Symbol(uuid4()) for i in 1:m, j in ringpeek(1:n))
vinds = Dict((i, j) => Symbol(uuid4()) for i in ringpeek(1:m), j in 1:n)
oinds = Dict((i, j) => Symbol(uuid4()) for i in 1:m, j in 1:n)
iinds = Dict((i, j) => Symbol(uuid4()) for i in 1:m, j in 1:n)

Check warning on line 77 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L73-L77

Added lines #L73 - L77 were not covered by tests

interlayer = if P <: State
[Bijection(Dict(i + j * m => index for ((i, j), index) in oinds))]
elseif P <: Operator
[

Check warning on line 82 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L79-L82

Added lines #L79 - L82 were not covered by tests
Bijection(Dict(i + j * m => index for ((i, j), index) in iinds)),
Bijection(Dict(i + j * m => index for ((i, j), index) in oinds)),
]
else
throw(ErrorException("Plug $P is not valid"))

Check warning on line 87 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L87

Added line #L87 was not covered by tests
end

tensors = map(zip(Iterators.map(Tuple, eachindex(IndexCartesian(), arrays)), arrays)) do ((i, j), array)
dirs = _sitealias(ProjectedEntangledPair{P,B}, order, (m, n), (i, j))

Check warning on line 91 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L90-L91

Added lines #L90 - L91 were not covered by tests

labels = map(dirs) do dir
if dir === :l
hinds[(i, (mod1(j - 1, n), j))]
elseif dir === :r
hinds[(i, (j, mod1(j + 1, n)))]
elseif dir === :u
vinds[((mod1(i - 1, n), i), j)]
elseif dir === :d
vinds[((i, mod1(i + 1, n)), j)]
elseif dir === :i
iinds[(i, j)]
elseif dir === :o
oinds[(i, j)]

Check warning on line 105 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L93-L105

Added lines #L93 - L105 were not covered by tests
end
end
alias = Dict(dir => label for (dir, label) in zip(dirs, labels))

Check warning on line 108 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L108

Added line #L108 was not covered by tests

Tensor(array, labels; alias = alias)

Check warning on line 110 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L110

Added line #L110 was not covered by tests
end |> vec

return TensorNetwork{ProjectedEntangledPair{P,B}}(tensors; χ, plug = P, interlayer, metadata...)

Check warning on line 113 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L113

Added line #L113 was not covered by tests
end

const PEPS = ProjectedEntangledPair{State}
const PEPO = ProjectedEntangledPair{Operator}

# TODO normalize
# TODO let choose the orthogonality center
# TODO different input/output physical dims
function Base.rand(rng::Random.AbstractRNG, sampler::TNSampler{ProjectedEntangledPair{P,Open}}) where {P<:Plug}
rows = sampler.rows
cols = sampler.cols
χ = sampler.χ
p = get(sampler, :p, 2)
T = get(sampler, :eltype, Float64)

Check warning on line 127 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L122-L127

Added lines #L122 - L127 were not covered by tests

arrays::Matrix{AbstractArray{T,N} where {N}} = reshape(

Check warning on line 129 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L129

Added line #L129 was not covered by tests
map(Iterators.product(1:rows, 1:cols)) do (i, j)
shape = filter(

Check warning on line 131 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L131

Added line #L131 was not covered by tests
!=(1),
[
i === 1 ? 1 : χ,
i === rows ? 1 : χ,
j === 1 ? 1 : χ,
j === cols ? 1 : χ,
p,
if P <: State
1
elseif P <: Operator
p

Check warning on line 142 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L140-L142

Added lines #L140 - L142 were not covered by tests
else
throw(ErrorException("$P is not a valid Plug type"))

Check warning on line 144 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L144

Added line #L144 was not covered by tests
end,
],
)

rand(rng, T, shape...)

Check warning on line 149 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L149

Added line #L149 was not covered by tests
end,
rows,
cols,
)

# normalize state
arrays[1, 1] ./= P <: State ? sqrt(p) : p

Check warning on line 156 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L156

Added line #L156 was not covered by tests

ProjectedEntangledPair{P,Open}(arrays; χ)

Check warning on line 158 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L158

Added line #L158 was not covered by tests
end

# TODO normalize
# TODO let choose the orthogonality center
# TODO different input/output physical dims
function Base.rand(rng::Random.AbstractRNG, sampler::TNSampler{ProjectedEntangledPair{P,Periodic}}) where {P<:Plug}
rows = sampler.rows
cols = sampler.cols
χ = sampler.χ
p = get(sampler, :p, 2)
T = get(sampler, :eltype, Float64)

Check warning on line 169 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L164-L169

Added lines #L164 - L169 were not covered by tests

arrays::Matrix{AbstractArray{T,N} where {N}} = reshape(

Check warning on line 171 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L171

Added line #L171 was not covered by tests
map(Iterators.product(1:rows, 1:cols)) do (i, j)
shape = tuple([χ, χ, χ, χ]..., ([if P <: State
(p,)
elseif P <: Operator
(p, p)

Check warning on line 176 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L173-L176

Added lines #L173 - L176 were not covered by tests
else
throw(ErrorException("$P is not a valid Plug type"))

Check warning on line 178 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L178

Added line #L178 was not covered by tests
end]...)...)

# A = gramschmidt!(rand(rng, T, shape[1], prod(shape[1:end])))
A = rand(rng, T, shape...)

Check warning on line 182 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L182

Added line #L182 was not covered by tests
end,
rows,
cols,
)

# normalize state
arrays[1, 1] ./= P <: State ? sqrt(p) : p

Check warning on line 189 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L189

Added line #L189 was not covered by tests

ProjectedEntangledPair{P,Periodic}(arrays; χ)

Check warning on line 191 in src/Quantum/PEP.jl

View check run for this annotation

Codecov / codecov/patch

src/Quantum/PEP.jl#L191

Added line #L191 was not covered by tests
end
1 change: 1 addition & 0 deletions src/Quantum/Quantum.jl
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,4 @@ function marginal(ψ, site)
end

include("MP.jl")
include("PEP.jl")
1 change: 1 addition & 0 deletions src/Tenet.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export Plug, plug, Property, State, Operator
export sites, fidelity

export MatrixProduct
export ProjectedEntangledPair, PEPS, PEPO

if !isdefined(Base, :get_extension)
using Requires
Expand Down
Loading