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
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
JL = julia --project

default: init test

init:
$(JL) -e 'using Pkg; Pkg.precompile(); Pkg.activate("docs"); Pkg.develop(path="."), Pkg.precompile()'

update:
$(JL) -e 'using Pkg; Pkg.update(); Pkg.precompile(); Pkg.activate("docs"); Pkg.update(); Pkg.precompile()'

test:
$(JL) -e 'using Pkg; Pkg.test()'

coverage:
$(JL) -e 'using Pkg; Pkg.test(; coverage=true)'

serve:
$(JL) -e 'using Pkg; Pkg.activate("docs"); using LiveServer; servedocs(;skip_dirs=["docs/src/assets", "docs/src/generated"], literate_dir="examples")'

clean:
rm -rf docs/build
find . -name "*.cov" -type f -print0 | xargs -0 /bin/rm -f

.PHONY: init test coverage serve clean update
9 changes: 6 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "TensorInference"
uuid = "c2297e78-99bd-40ad-871d-f50e56b81012"
authors = ["Jin-Guo Liu", "Martin Roa Villescas"]
version = "0.4.2"
version = "0.4.3"

[deps]
Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
Expand All @@ -17,10 +17,13 @@ StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
TropicalNumbers = "b3a74e9c-7526-4576-a4eb-79c0d4c32334"

[compat]
Artifacts = "1"
CUDA = "4, 5"
DocStringExtensions = "0.8.6, 0.9"
GenericTensorNetworks = "1"
OMEinsum = "0.7"
GenericTensorNetworks = "2"
LinearAlgebra = "1"
OMEinsum = "0.8"
Pkg = "1"
PrecompileTools = "1"
Requires = "1"
StatsBase = "0.34"
Expand Down
17 changes: 8 additions & 9 deletions examples/hard-core-lattice-gas/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@

a, b = (1, 0), (0.5, 0.5*sqrt(3))
Na, Nb = 10, 10
sites = [a .* i .+ b .* j for i=1:Na, j=1:Nb]
sites = vec([50 .* (a .* i .+ b .* j) for i=1:Na, j=1:Nb])

# There exists blockade interactions between hard-core particles.
# We connect two lattice sites within blockade radius by an edge.
# Two ends of an edge can not both be occupied by particles.
blockade_radius = 1.1
blockade_radius = 55
using GenericTensorNetworks: show_graph, unit_disk_graph
using GenericTensorNetworks.Graphs: edges, nv
graph = unit_disk_graph(vec(sites), blockade_radius)
show_graph(graph; locs=sites, texts=fill("", length(sites)))
show_graph(graph, sites; texts=fill("", length(sites)))

# These constraints defines an independent set problem that characterized by the following energy based model.
# Let $G = (V, E)$ be a graph, where $V$ is the set of vertices and $E$ is the set of edges.
Expand All @@ -39,7 +39,7 @@ show_graph(graph; locs=sites, texts=fill("", length(sites)))
# The independent set problem involves finding a set of vertices in a graph such that no two vertices in the set are adjacent (i.e., there is no edge connecting them).
# One can create a tensor network based modeling of an independent set problem with package [`GenericTensorNetworks.jl`](https://github.com/QuEraComputing/GenericTensorNetworks.jl).
using GenericTensorNetworks
problem = IndependentSet(graph; optimizer=GreedyMethod());
problem = IndependentSet(graph)

# There are plenty of discussions related to solution space properties in the `GenericTensorNetworks` [documentaion page](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/IndependentSet/).
# In this example, we show how to use `TensorInference` to use probabilistic inference for understand the finite temperature properties of this statistical model.
Expand All @@ -59,15 +59,14 @@ partition_func[]

# The marginal probabilities can be computed with the [`marginals`](@ref) function, which measures how likely a site is occupied.
mars = marginals(pmodel)
show_graph(graph; locs=sites, vertex_colors=[(b = mars[[i]][2]; (1-b, 1-b, 1-b)) for i in 1:nv(graph)], texts=fill("", nv(graph)))
show_graph(graph, sites; vertex_colors=[(b = mars[[i]][2]; (1-b, 1-b, 1-b)) for i in 1:nv(graph)], texts=fill("", nv(graph)))
# The can see the sites at the corner is more likely to be occupied.
# To obtain two-site correlations, one can set the variables to query marginal probabilities manually.
pmodel2 = TensorNetworkModel(problem, β; mars=[[e.src, e.dst] for e in edges(graph)])
mars = marginals(pmodel2);

# We show the probability that both sites on an edge are not occupied
show_graph(graph; locs=sites, edge_colors=[(b = mars[[e.src, e.dst]][1, 1]; (1-b, 1-b, 1-b)) for e in edges(graph)], texts=fill("", nv(graph)),
edge_line_widths=edge_colors=[8*mars[[e.src, e.dst]][1, 1] for e in edges(graph)])
show_graph(graph, sites; edge_colors=[(b = mars[[e.src, e.dst]][1, 1]; (1-b, 1-b, 1-b)) for e in edges(graph)], texts=fill("", nv(graph)), config=GraphDisplayConfig(; edge_line_width=5))

# ## The most likely configuration
# The MAP and MMAP can be used to get the most likely configuration given an evidence.
Expand All @@ -78,7 +77,7 @@ mars = marginals(pmodel3)
logp, config = most_probable_config(pmodel3)

# The log probability is 102. Let us visualize the configuration.
show_graph(graph; locs=sites, vertex_colors=[(1-b, 1-b, 1-b) for b in config], texts=fill("", nv(graph)))
show_graph(graph, sites; vertex_colors=[(1-b, 1-b, 1-b) for b in config], texts=fill("", nv(graph)))
# The number of particles is
sum(config)

Expand All @@ -87,7 +86,7 @@ pmodel3 = TensorNetworkModel(problem, β; evidence=Dict(1=>0))
logp2, config2 = most_probable_config(pmodel)

# The log probability is 99, which is much smaller.
show_graph(graph; locs=sites, vertex_colors=[(1-b, 1-b, 1-b) for b in config2], texts=fill("", nv(graph)))
show_graph(graph, sites; vertex_colors=[(1-b, 1-b, 1-b) for b in config2], texts=fill("", nv(graph)))
# The number of particles is
sum(config2)

Expand Down
17 changes: 8 additions & 9 deletions src/generictensornetworks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ Convert a constraint satisfiability problem (or energy model) to a probabilistic
* `problem` is a `GraphProblem` instance in [`GenericTensorNetworks`](https://github.com/QuEraComputing/GenericTensorNetworks.jl).
* `β` is the inverse temperature.
"""
function TensorInference.TensorNetworkModel(problem::GraphProblem, β::Real; evidence::Dict=Dict{Int,Int}(),
optimizer=GreedyMethod(), simplifier=nothing, mars=[[l] for l in labels(problem)])
ixs = getixsv(problem.code)
iy = getiyv(problem.code)
function TensorInference.TensorNetworkModel(problem::GraphProblem, β::Real; evidence::Dict=Dict{eltype(labels(problem)),Int}(),
optimizer=GreedyMethod(), openvars=empty(labels(problem)), simplifier=nothing, mars=[[l] for l in labels(problem)])
ixs = [GenericTensorNetworks.energy_terms(problem)..., GenericTensorNetworks.extra_terms(problem)...]
lbs = labels(problem)
nflavors = length(flavors(problem))
# generate tensors for x = e^β
tensors = generate_tensors(exp(β), problem)
factors = [Factor((ix...,), t) for (ix, t) in zip(ixs, tensors)]
return TensorNetworkModel(lbs, fill(nflavors, length(lbs)), factors; openvars=iy, evidence, optimizer, simplifier, mars)
return TensorNetworkModel(lbs, fill(nflavors, length(lbs)), factors; openvars, evidence, optimizer, simplifier, mars)
end

"""
Expand All @@ -43,18 +42,18 @@ end

function TensorInference.MMAPModel(problem::GraphProblem, β::Real;
queryvars,
evidence = Dict{labeltype(problem.code), Int}(),
openvars = empty(labels(problem)),
evidence = Dict{eltype(labels(problem)), Int}(),
optimizer = GreedyMethod(), simplifier = nothing,
marginalize_optimizer = GreedyMethod(), marginalize_simplifier = nothing
)::MMAPModel
ixs = getixsv(problem.code)
iy = getiyv(problem.code)
ixs = [GenericTensorNetworks.energy_terms(problem)..., GenericTensorNetworks.extra_terms(problem)...]
nflavors = length(flavors(problem))
# generate tensors for x = e^β
tensors = generate_tensors(exp(β), problem)
factors = [Factor((ix...,), t) for (ix, t) in zip(ixs, tensors)]
lbs = labels(problem)
return MMAPModel(lbs, fill(nflavors, length(lbs)), factors; queryvars, openvars=iy, evidence,
return MMAPModel(lbs, fill(nflavors, length(lbs)), factors; queryvars, openvars, evidence,
optimizer, simplifier,
marginalize_optimizer, marginalize_simplifier)
end
Expand Down
4 changes: 2 additions & 2 deletions test/generictensornetworks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ using GenericTensorNetworks, TensorInference
problem = IndependentSet(g)
model = TensorNetworkModel(problem, β; mars=[[2, 3]])
mars = marginals(model)[[2, 3]]
problem2 = IndependentSet(g; openvertices=[2,3])
mars2 = TensorInference.normalize!(GenericTensorNetworks.solve(problem2, PartitionFunction(β)), 1)
problem2 = IndependentSet(g)
mars2 = TensorInference.normalize!(GenericTensorNetworks.solve(GenericTensorNetwork(problem2; openvertices=[2, 3]), PartitionFunction(β)), 1)
@test mars ≈ mars2

# update temperature
Expand Down