Skip to content

Commit

Permalink
Merge 59d5cfe into a3a39e8
Browse files Browse the repository at this point in the history
  • Loading branch information
lpawela committed Oct 28, 2020
2 parents a3a39e8 + 59d5cfe commit 0b38803
Show file tree
Hide file tree
Showing 14 changed files with 261 additions and 36 deletions.
12 changes: 12 additions & 0 deletions Manifest.toml
Expand Up @@ -120,6 +120,18 @@ uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[DocStringExtensions]]
deps = ["LibGit2", "Markdown", "Pkg", "Test"]
git-tree-sha1 = "50ddf44c53698f5e784bbebb3f4b21c5807401b1"
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.8.3"

[[Documenter]]
deps = ["Base64", "Dates", "DocStringExtensions", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"]
git-tree-sha1 = "fb1ff838470573adc15c71ba79f8d31328f035da"
uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
version = "0.25.2"

[[ExprTools]]
git-tree-sha1 = "7fce513fcda766962ff67c5596cb16c463dfd371"
uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
Expand Down
1 change: 1 addition & 0 deletions Project.toml
Expand Up @@ -7,6 +7,7 @@ version = "0.0.1"
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231"
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
2 changes: 2 additions & 0 deletions src/SpinGlassPEPS.jl
Expand Up @@ -6,13 +6,15 @@ module SpinGlassPEPS
using LightGraphs
using MetaGraphs
using CSV
const product = Iterators.product

include("base.jl")
include("compressions.jl")
include("contractions.jl")
include("ising.jl")
include("graph.jl")
include("PEPS.jl")
include("search.jl")
include("utils.jl")

function __init__()
Expand Down
24 changes: 20 additions & 4 deletions src/base.jl
@@ -1,4 +1,6 @@
export bond_dimension
export _verify_bonds

for (T, N) in ((:MPO, 4), (:MPS, 3))
AT = Symbol(:Abstract, T)
@eval begin
Expand All @@ -16,7 +18,7 @@ for (T, N) in ((:MPO, 4), (:MPS, 3))
$T(L::Int) = $T(Float64, L)

Base.setindex!(a::$AT, A::AbstractArray{<:Number, $N}, i::Int) = a.tensors[i] = A
bond_dimension(a::$AT) = maixmum(size.(a.tensors, $N))
bond_dimension(a::$AT) = maximum(size.(a.tensors, $N))
Base.copy(a::$T) = $T(copy(a.tensors))
Base.eltype(::$AT{T}) where {T} = T
end
Expand All @@ -36,12 +38,14 @@ Base.length(a::AbstractMPSorMPO) = length(a.tensors)
Base.size(a::AbstractMPSorMPO) = (length(a.tensors), )


function MPS(vec::Vector{<:Number})
function MPS(vec::Vector{Vector{T}}) where {T <: Number}
L = length(vec)
ψ = MPS(L)
ψ = MPS(T, L)
for i 1:L
ψ[i] = reshape(copy(vec[i]), 1, :, 1)
A = reshape(vec[i], 1, :, 1)
ψ[i] = copy(A)
end
return ψ
end

function MPO::MPS)
Expand Down Expand Up @@ -91,6 +95,17 @@ function _verify_square(ψ::AbstractMPS)
@assert isqrt.(arr) .^ 2 == arr "Incorrect MPS dimensions"
end

function _verify_bonds::AbstractMPS)
L = length(ψ)

@assert size(ψ[1], 1) == 1 "Incorrect size on the left boundary."
@assert size(ψ[end], 3) == 1 "Incorrect size on the right boundary."

for i 1:L-1
@assert size(ψ[i], 3) == size(ψ[i+1], 1) "Incorrect link between $i and $(i+1)."
end
end

function Base.show(::IO, ψ::AbstractMPS)
L = length(ψ)
σ_list = [size(ψ[i], 2) for i 1:L]
Expand All @@ -99,6 +114,7 @@ function Base.show(::IO, ψ::AbstractMPS)
println("Matrix product state on $L sites:")
println("Physical dimensions: ")
_show_sizes(σ_list)
println(" ")
println("Bond dimensions: ")
_show_sizes(χ_list)
end
Expand Down
10 changes: 6 additions & 4 deletions src/compressions.jl
@@ -1,7 +1,4 @@
export truncate!, canonise!, compress

# TODO
# 1) write two sites compress function
export truncate!, canonise!, compress, compress!

function LinearAlgebra.qr(M::AbstractMatrix, Dcut::Int)
fact = pqrfact(M, rank=Dcut)
Expand Down Expand Up @@ -113,6 +110,11 @@ function compress(ψ::AbstractMPS, Dcut::Int, tol::Number, max_sweeps::Int=4)
return ϕ
end

function compress!::MPS, Dcut::Int, tol::Number, max_sweeps::Int=4)
ϕ = compress(ψ, Dcut, tol, max_sweeps)
ψ = copy(ϕ)
end

function _left_sweep_var!!::MPS, env::Vector{<:AbstractMatrix}, ψ::MPS, Dcut::Int)
S = eltype(ϕ)

Expand Down
7 changes: 1 addition & 6 deletions src/contractions.jl
@@ -1,4 +1,4 @@

using Base
export left_env, right_env, dot!

# --------------------------- Conventions ------------------------
Expand All @@ -9,11 +9,6 @@ export left_env, right_env, dot!
# 3 - 1 0 -
# ---------------------------------------------------------------
#
# TODO
# 1) right moving dot version
# 2) write right_env analogous to left_env
# 3) combine 1-2 into one function
# 4) Add more general dots and envs (MPS, MPO, MPS)

function LinearAlgebra.dot::MPS, ψ::MPS)
T = promote_type(eltype(ψ), eltype(ϕ))
Expand Down
45 changes: 33 additions & 12 deletions src/ising.jl
@@ -1,9 +1,30 @@
export ising_graph, energy
export gibbs_tensor
export GibbsControl

function energy(ig::MetaGraph, σ::Vector{<:Number})
"""
Calculate the Ising energy as E = -sum_<i,j> s_i * J_ij * s_j - sum_j h_i * s_j.
"""
struct GibbsControl
β::Number
β_schedule::Vector{<:Number}
end

function gibbs_tensor(ig::MetaGraph, opts::GibbsControl)
L = nv(ig)
β = opts.β

all_states = product(fill([-1, 1], L)...)
rank = fill(2, L)

r = exp.(-β * energy.(all_states, Ref(ig)))
# r = [exp(-β * energy(ig, collect(σ))) for σ ∈ all_states]
ρ = reshape(r, rank...)
ρ / sum(ρ)
end


"""
Calculate the Ising energy as E = -sum_<i,j> s_i * J_ij * s_j - sum_j h_i * s_j.
"""
function energy::Union{Vector, NTuple}, ig::MetaGraph)

energy = 0
# quadratic
Expand All @@ -18,17 +39,17 @@ function energy(ig::MetaGraph, σ::Vector{<:Number})
h = get_prop(ig, i, :h)
energy += h * σ[i]
end
return -energy
-energy
end

"""
Create a graph that represents the Ising Hamiltonian.
"""
function ising_graph(instance::String, L::Int, β::Number=1)
"""
Create a graph that represents the Ising Hamiltonian.
"""

# load the Ising instance
ising = CSV.File(instance, types=[Int, Int, Float64])
ig = MetaGraph(L, 0.0)
ig = MetaGraph(L, 0.0)

set_prop!(ig, :description, "The Ising model.")

Expand All @@ -44,13 +65,13 @@ function ising_graph(instance::String, L::Int, β::Number=1)
end

# state and corresponding energy
state = [rand() < 0.5 ? -1 : 1 for _ 1:L]
state = 2(rand(L) .< 0.5) .- 1

set_prop!(ig, :state, state)
set_prop!(ig, :energy, energy(ig, state)) || error("Unable to calculate the Ising energy!")
set_prop!(ig, :energy, energy(state, ig)) || error("Unable to calculate the Ising energy!")

# store extra information
set_prop!(ig, , β)

return ig
ig
end
106 changes: 104 additions & 2 deletions src/search.jl
@@ -1,4 +1,106 @@
export MPS_from_gates, unique_neighbors
export MPSControl

function MPS(ig::MetaGraph)
return
struct MPSControl
max_bond::Int
ϵ::Number
max_sweeps::Int
end

function unique_neighbors(ig::MetaGraph, i::Int)
nbrs = neighbors(ig::MetaGraph, i::Int)
filter(j -> j > i, nbrs)
end

function _apply_bias!::AbstractMPS, ig::MetaGraph, dβ::Number, i::Int)
M = ψ[i]
if has_prop(ig, i, :h)
h = get_prop(ig, i, :h)
v = [exp(-0.5 ** h * σ) for σ [-1, 1]]
@cast M[x, σ, y] = M[x, σ, y] * v[σ]
end
ψ[i] = M
end

function _apply_exponent!::AbstractMPS, ig::MetaGraph, dβ::Number, i::Int, j::Int)
δ = I(2)
M = ψ[j]

J = get_prop(ig, i, j, :J)
C = [exp(-0.5 ** k * J * l) for k [-1, 1], l [-1, 1]]

if j == length(ψ)
@cast M̃[(x, a), σ, b] := C[x, σ] * δ[x, 1] * M[a, σ, b]
else
@cast M̃[(x, a), σ, (y, b)] := C[x, σ] * δ[x, y] * M[a, σ, b]
end
ψ[j] =
end

function _apply_projector!::AbstractMPS, i::Int)
δ = I(2)
M = ψ[i]

if i == 1
@cast M̃[a, σ, (y, b)] := δ[σ, y] * δ[1, y] * M[a, σ, b]
else
@cast M̃[(x, a), σ, (y, b)] := δ[σ, y] * δ[x, y] * M[a, σ, b]
end
ψ[i] =
end

function _apply_nothing!::AbstractMPS, i::Int)
δ = I(2)
M = ψ[i]

if i == 1
@cast M̃[a, σ, (y, b)] := δ[1, y] * M[a, σ, b]
elseif i == length(ψ)
@cast M̃[(x, a), σ, b] := δ[x, 1] * M[a, σ, b]
else
@cast M̃[(x, a), σ, (y, b)] := δ[x, y] * M[a, σ, b]
end
ψ[i] =
end

function MPS_from_gates(ig::MetaGraph, mps::MPSControl, gibbs::GibbsControl)
L = nv(ig)

# control for MPS
Dcut = mps.max_bond
tol = mps.ϵ
max_sweeps = mps.max_sweeps

# control for Gibbs state
β = gibbs.β
schedule = gibbs.β_schedule

@assert β sum(schedule) "Incorrect β schedule."

# prepare ~ Hadamard state as MPS
prod_state = fill([1., 1.], nv(ig))
ρ = MPS(prod_state)

for schedule, i 1:L
_apply_bias!(ρ, ig, dβ, i)

nbrs = unique_neighbors(ig, i)
if !isempty(nbrs)
for j nbrs
_apply_exponent!(ρ, ig, dβ, i, j)
end

_apply_projector!(ρ, i)

for l setdiff(1:L, union(i, nbrs))
_apply_nothing!(ρ, l)
end
end

# reduce bond dimension
if bond_dimension(ρ) > Dcut
ρ = compress(ρ, Dcut, tol, max_sweeps)
end
end
ρ
end
20 changes: 20 additions & 0 deletions test/base.jl
Expand Up @@ -7,6 +7,7 @@ T = ComplexF64

@testset "Random MPS" begin
ψ = randn(MPS{T}, sites, D, d)
@test _verify_bonds(ψ) == nothing

@test ψ == ψ
@test ψ ψ
Expand All @@ -22,6 +23,25 @@ T = ComplexF64
show(ψ)
end

@testset "Retrieving bond dimension" begin
S = Float64
size = 5
D = 6
d = 2
ψ = randn(MPS{S}, sites, D, d)

@test bond_dimension(ψ) D
end

@testset "MPS from Product state" begin
L = 3

prod_state = [ [1, 1.] / sqrt(2) for _ 1:L]
ϕ = MPS(prod_state)

show(ϕ)
end

@testset "Random MPO" begin
O = randn(MPO{T}, sites, D, d)

Expand Down
1 change: 1 addition & 0 deletions test/contractions.jl
Expand Up @@ -28,4 +28,5 @@ end
@testset "Cauchy-Schwarz inequality" begin
@test abs(dot(ϕ, ψ)) <= norm(ϕ) * norm(ψ)
end

end
2 changes: 1 addition & 1 deletion test/cuda/compressions.jl
Expand Up @@ -89,7 +89,7 @@ end
dist1 = 2 - 2 * real(overlap)
dist2 = norm(Ψ)^2 + norm(Φ)^2 - 2 * real(overlap)

@test abs(dist1 - dist2) < 1e-14
@test abs(dist1 - dist2) < 1e-5

println("(Φ, Ψ) = ", overlap)
println("dist(Φ, Ψ)^2 = ", dist2)
Expand Down

0 comments on commit 0b38803

Please sign in to comment.