diff --git a/src/utils.jl b/src/utils.jl index 16166a2..d043242 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,8 +1,11 @@ export zephyr_to_linear, - unique_neighbors + unique_neighbors, + load_openGM import Base.Prehashed +using HDF5 + """ $(TYPEDSIGNATURES) @@ -88,3 +91,84 @@ unique_neighbors(ig::LabelledGraph, i::Int) = filter(j -> j > i, neighbors(ig, i (@nref $N A d->d == dim ? sort!(uniquerows) : (axes(A, d))), indexin(uniquerow, uniquerows) end end + +""" +$(TYPEDSIGNATURES) +Loads some factored graphs written in openGM format. Assumes rectangular lattice. + +Args: + file_name (str): a path to file with factor graph in openGM format. + ints Nx, Ny: it is assumed that graph if forming an :math:N_x \times N_y lattice with + nearest-neighbour interactions only. + +Returns: + dictionary with factors and funcitons defining the energy functional. +""" +function load_openGM(fname::String, Nx::Integer, Ny::Integer) + file = h5open(fname, "r") + + file_keys = collect(keys(read(file))) + data = read(file[file_keys[1]]) + H = collect(Int64, data["header"]) + F = Array{Int64}(data["factors"]) + J = Array{Int64}(data["function-id-16000"]["indices"]) + V = Array{Real}(data["function-id-16000"]["values"]) + N = Array{Int64}(data["numbers-of-states"]) + + F = reverse(F) + factors = Dict() + + while length(F) > 0 + f1 = pop!(F) + z1 = pop!(F) + nn = pop!(F) + n = [] + + for _ in 1:nn + tt = pop!(F) + ny, nx = divrem(tt, Nx) + push!(n, ny, nx) + end + + if length(n) == 4 + if abs(n[1] - n[3]) + abs(n[2] - n[4]) != 1 + throw(ErrorException("Not nearest neighbour")) + end + end + + if length(n) == 2 + if (n[1] >= Ny) || (n[2] >= Nx) + throw(ErrorException("Wrong size")) + end + end + + factors[tuple(n...)] = f1 + + if z1 != 0 + throw(ErrorException("Something wrong with the expected convention.")) + end + end + + J = reverse(J) + functions = Dict() + ii = -1 + lower = 0 + + while length(J) > 0 + ii += 1 + nn = pop!(J) + n = [] + + for _ in 1:nn + push!(n, pop!(J)) + end + + upper = lower + prod(n) + functions[ii] = reshape(V[lower + 1:upper], reverse(n)...)' + + lower = upper + end + + result = Dict("fun" => functions, "fac" => factors, "N" => reshape(N, (Ny, Nx)), "Nx" => Nx, "Ny" => Ny) + result +end \ No newline at end of file