Skip to content

Commit

Permalink
add docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
annamariadziubyna committed Oct 2, 2023
1 parent 69fedcf commit 1614f46
Show file tree
Hide file tree
Showing 9 changed files with 722 additions and 29 deletions.
53 changes: 53 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,66 @@ CurrentModule = SpinGlassNetworks
ising_graph
inter_cluster_edges
prune
couplings
```

## Clustered Hamiltonian
```@docs
split_into_clusters
clustered_hamiltonian
decode_clustered_hamiltonian_state
rank_reveal
energy
energy_2site
cluster_size
bond_energy
exact_cond_prob
truncate_clustered_hamiltonian
```

## Lattice
```@docs
super_square_lattice
pegasus_lattice
zephyr_lattice
```

## Belief propagation
```@docs
local_energy
interaction_energy
get_neighbors
belief_propagation
MergedEnergy
update_message
clustered_hamiltonian_2site
merge_vertices_cl_h
projector
SparseCSC
```

## Projectors
```@docs
PoolOfProjectors
get_projector!
add_projector!
empty!
```

## Spectrum
```@docs
Spectrum
matrix_to_integers
gibbs_tensor
brute_force
```

## Truncate
```@docs
truncate_clustered_hamiltonian_1site_BP
truncate_clustered_hamiltonian_2site_BP
truncate_clustered_hamiltonian_2site_energy
select_numstate_best
```

## Auxiliary Functions
Expand Down
2 changes: 1 addition & 1 deletion docs/src/userguide.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ cl_h = clustered_hamiltonian(
```

## Pegasus graphs
The Pegasus graph is a type of graph architecture used in quantum computing systems, particularly in the quantum annealing machines developed by D-Wave Systems. It is a two-dimensional lattice of unit cells, each consisting of a bipartite graph of $K_{4,4}$ complete bipartite subgraphs. Futer details can be found [here](https://docs.dwavesys.com/docs/latest/c_gs_4.html#pegasus-graph).
The Pegasus graph is a type of graph architecture used in quantum computing systems, particularly in the quantum annealing machines developed by D-Wave Systems. It is designed to provide a grid of qubits with specific connectivity patterns optimized for solving certain optimization problems. Futer details can be found [here](https://docs.dwavesys.com/docs/latest/c_gs_4.html#pegasus-graph).
```@raw html
<img src="../images/peg.pdf" width="200%" class="center"/>
```
Expand Down
178 changes: 172 additions & 6 deletions src/bp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,32 @@
export
belief_propagation,
clustered_hamiltonian_2site,
projector


projector,
get_neighbors,
MergedEnergy,
update_message,
merge_vertices_cl_h,
local_energy,
interaction_energy,
SparseCSC

"""
Perform belief propagation on a given clustered hamiltonian.
# Arguments:
- `cl_h::LabelledGraph{S, T}`: The clustered hamiltonian represented as a labeled graph.
- `beta::Real`: The temperature parameter for the belief propagation algorithm.
- `tol::Real (optional, default=1e-6)`: The convergence tolerance. The algorithm stops when the message updates between iterations are smaller than this value.
- `iter::Int (optional, default=1)`: The maximum number of iterations to perform.
# Returns:
- `beliefs::Dict`: A dictionary where keys are vertices of clustered hamiltonian, and values are the resulting beliefs after belief propagation.
The function implements belief propagation on the given clustered hamiltonian `cl_h` to calculate beliefs for each vertex.
Belief propagation is an iterative algorithm that computes beliefs by passing messages between vertices and edges of the clustered hamiltonian.
The algorithm continues until convergence or until the specified maximum number of iterations is reached.
The beliefs are computed based on the temperature parameter `beta`, which controls the influence of energy values on the beliefs.
"""
function belief_propagation(cl_h::LabelledGraph{S, T}, beta::Real; tol=1e-6, iter=1) where {S, T}
messages_ve = Dict()
messages_ev = Dict()
Expand Down Expand Up @@ -65,6 +88,21 @@ function belief_propagation(cl_h::LabelledGraph{S, T}, beta::Real; tol=1e-6, ite
beliefs
end

"""
Returns the neighbors of a given vertex in a clustered Hamiltonian.
# Arguments:
- `cl_h::LabelledGraph{S, T}`: The clustered Hamiltonian represented as a labeled graph.
- `vertex::NTuple`: The vertex for which neighbors are to be retrieved.
# Returns:
- `neighbors::Vector{Tuple}`: A vector of tuples representing the neighbors of the specified vertex. Each tuple contains the following information:
- `dst_node::T`: The neighboring vertex.
- `pv::Matrix`: The projector associated with the edge connecting the vertex and its neighbor.
- `en::Real`: The energy associated with the edge connecting the vertex and its neighbor.
This function retrieves the neighbors of a given vertex in a clustered Hamiltonian graph. It iterates through the edges of the graph and identifies edges connected to the specified vertex. For each neighboring edge, it extracts and returns the neighboring vertex, the associated projector, and the energy.
"""
function get_neighbors(cl_h::LabelledGraph{S, T}, vertex::NTuple) where {S, T}
neighbors = []
for edge in edges(cl_h)
Expand All @@ -84,6 +122,19 @@ function get_neighbors(cl_h::LabelledGraph{S, T}, vertex::NTuple) where {S, T}
return neighbors
end

"""
A custom Julia struct representing energy values in a merged format for use in specific calculations.
# Fields:
- `e11::AbstractMatrix{T}`
- `e12::AbstractMatrix{T}`
- `e21::AbstractMatrix{T}`
- `e22::AbstractMatrix{T}`
The `MergedEnergy` struct is used to represent energy values that are organized in a merged format. This format is often utilized in certain computational tasks, where energy values are categorized based on combinations of left and right factors.
Each field of the `MergedEnergy` struct stores energy values as an `AbstractMatrix{T}` of type `T`, where `T` is a subtype of the `Real` abstract type. The specific organization and interpretation of these energy values depend on the context in which this struct is used.
"""
struct MergedEnergy{T <: Real}
e11::AbstractMatrix{T}
e12::AbstractMatrix{T}
Expand All @@ -93,11 +144,41 @@ end

Base.adjoint(s::MergedEnergy) = MergedEnergy(s.e11', s.e21', s.e12', s.e22')

"""
Update a message using energy values and temperature.
# Arguments:
- `E_bond::AbstractArray`: An array of energy values associated with a bond or interaction.
- `message::Vector`: The input message vector to be updated.
- `beta::Real`: The temperature parameter controlling the influence of energy values.
# Returns:
- `updated_message::Vector`: The updated message vector after applying the energy-based update.
This function takes energy values `E_bond` associated with a bond or interaction, an input message vector `message`, and a temperature parameter `beta`. It updates the message by first adjusting the energy values relative to their minimum value, exponentiating them with a negative sign and scaling by `beta`, and then multiplying them element-wise with the input message.
The result is an updated message that reflects the influence of energy values and temperature.
"""
function update_message(E_bond::AbstractArray, message::Vector, beta::Real)
E_bond = E_bond .- minimum(E_bond)
exp.(-beta * E_bond) * message
end

"""
Update a message using energy values and temperature in a merged energy format.
# Arguments:
- `E_bond::MergedEnergy`: An instance of the `MergedEnergy` type representing energy values for the bond or interaction.
- `message::Vector`: The input message vector to be updated.
- `beta::Real`: The temperature parameter controlling the influence of energy values.
# Returns:
- `updated_message::Vector`: The updated message vector after applying the energy-based update.
This function takes energy values `E_bond` in a merged energy format, an input message vector `message`, and a temperature parameter `beta`. It updates the message based on the energy values and temperature using a specified algorithm.
The `MergedEnergy` type represents energy values in a merged format, and the function processes these values accordingly to update the message vector.
"""
function update_message(E_bond::MergedEnergy, message::Vector, beta::Real)
e11, e12, e21, e22 = E_bond.e11, E_bond.e12, E_bond.e21, E_bond.e22
# equivalent to
Expand Down Expand Up @@ -143,7 +224,20 @@ function update_message(E_bond::MergedEnergy, message::Vector, beta::Real)
R
end


"""
Constructs a clustered Hamiltonian for a given clustered Hamiltonian with a 2-site cluster approximation.
# Arguments:
- `cl_h::LabelledGraph{S, T}`: The clustered Hamiltonian represented as a labeled graph.
- `beta::Real`: The temperature parameter for the 2-site cluster Hamiltonian construction.
# Returns:
- `new_cl_h::LabelledGraph{MetaDiGraph}`: A new labeled graph representing the 2-site cluster Hamiltonian.
This function constructs a clustered Hamiltonian `cl_h` by applying a 2-site cluster approximation. It combines and merges vertices and edges of the original graph to create a simplified representation of the Hamiltonian.
The resulting `new_cl_h` graph represents the 2-site cluster Hamiltonian with simplified interactions between clusters. The energy values, projectors, and spectra associated with the new vertices and edges are computed based on the provided temperature parameter `beta`.
"""
function clustered_hamiltonian_2site(cl_h::LabelledGraph{S, T}, beta::Real) where {S, T}

unified_vertices = unique([vertex[1:2] for vertex in vertices(cl_h)])
Expand Down Expand Up @@ -173,7 +267,7 @@ function clustered_hamiltonian_2site(cl_h::LabelledGraph{S, T}, beta::Real) wher

add_edge!(new_cl_h, (v1, v2), (w1, w2))

E, pl, pr = merge_vertices(cl_h, beta, v, w)
E, pl, pr = merge_vertices_cl_h(cl_h, beta, v, w)
ipl = add_projector!(new_lp, pl)
ipr = add_projector!(new_lp, pr)
set_props!(new_cl_h, (v1, v2), (w1, w2), Dict(:ipl => ipl, :en => E, :ipr => ipr))
Expand All @@ -183,7 +277,25 @@ function clustered_hamiltonian_2site(cl_h::LabelledGraph{S, T}, beta::Real) wher
new_cl_h
end

function merge_vertices(cl_h::LabelledGraph{S, T}, β::Real, node1::NTuple{3, Int64}, node2::NTuple{3, Int64}
"""
Merge two vertices in a clustered Hamiltonian to create a single merged vertex.
# Arguments:
- `cl_h::LabelledGraph{S, T}`: The clustered Hamiltonian represented as a labeled graph.
- `β::Real`: The temperature parameter controlling the influence of energy values.
- `node1::NTuple{3, Int64}`: The coordinates of the first vertex to merge.
- `node2::NTuple{3, Int64}`: The coordinates of the second vertex to merge.
# Returns:
- `merged_energy::MergedEnergy`: An instance of the `MergedEnergy` type representing the merged energy values.
- `pl::AbstractVector`: The merged left projector.
- `pr::AbstractVector`: The merged right projector.
This function merges two vertices in a clustered Hamiltonian graph `cl_h` to create a single merged vertex. The merging process combines projectors and energy values associated with the original vertices based on the provided temperature parameter `β`.
The merged energy values, left projector `pl`, and right projector `pr` are computed based on the interactions between the original vertices and their respective projectors.
"""
function merge_vertices_cl_h(cl_h::LabelledGraph{S, T}, β::Real, node1::NTuple{3, Int64}, node2::NTuple{3, Int64}
) where {S, T}
i1, j1, _ = node1
i2, j2, _ = node2
Expand Down Expand Up @@ -220,10 +332,38 @@ function merge_vertices(cl_h::LabelledGraph{S, T}, β::Real, node1::NTuple{3, In
MergedEnergy(e11, e12, e21, e22), pl, pr
end

"""
Get the local energy associated with a vertex in a clustered Hamiltonian.
# Arguments:
- `cl_h::LabelledGraph{S, T}`: The clustered Hamiltonian represented as a labeled graph.
- `v::NTuple{3, Int64}`: The coordinates of the vertex for which the local energy is requested.
# Returns:
- `local_energy::AbstractVector`: An abstract vector containing the local energy values associated with the specified vertex.
This function retrieves the local energy values associated with a given vertex `v` in a clustered Hamiltonian graph `cl_h`. If the vertex exists in the graph and has associated energy values, it returns those values; otherwise, it returns a vector of zeros.
The local energy values are typically obtained from the spectrum associated with the vertex.
"""
function local_energy(cl_h::LabelledGraph{S, T}, v::NTuple{3, Int64}) where {S, T}
has_vertex(cl_h, v) ? get_prop(cl_h, v, :spectrum).energies : zeros(1)
end

"""
Get the interaction energy between two vertices in a clustered Hamiltonian.
# Arguments:
- `cl_h::LabelledGraph{S, T}`: The clustered Hamiltonian represented as a labeled graph.
- `v::NTuple{3, Int64}`: The coordinates of the first vertex.
- `w::NTuple{3, Int64}`: The coordinates of the second vertex.
# Returns:
- `interaction_energy::AbstractMatrix`: An abstract matrix containing the interaction energy values between the specified vertices.
This function retrieves the interaction energy values between two vertices, `v` and `w`, in a clustered Hamiltonian graph `cl_h`. If there is a directed edge from `w` to `v`, it returns the corresponding energy values; if there is a directed edge from `v` to `w`, it returns the transpose of the energy values; otherwise, it returns a matrix of zeros.
The interaction energy values represent the energy associated with the interaction or connection between the two vertices.
"""
function interaction_energy(cl_h::LabelledGraph{S, T}, v::NTuple{3, Int64}, w::NTuple{3, Int64}) where {S, T}
if has_edge(cl_h, w, v)
get_prop(cl_h, w, v, :en)'
Expand All @@ -234,6 +374,19 @@ function interaction_energy(cl_h::LabelledGraph{S, T}, v::NTuple{3, Int64}, w::N
end
end

"""
Get the projector associated with an edge between two vertices in a clustered Hamiltonian.
# Arguments:
- `cl_h::LabelledGraph{S, T}`: The clustered Hamiltonian represented as a labeled graph.
- `v::NTuple{N, Int64}`: The coordinates of one of the two vertices connected by the edge.
- `w::NTuple{N, Int64}`: The coordinates of the other vertex connected by the edge.
# Returns:
- `p::AbstractVector`: An abstract vector representing the projector associated with the specified edge.
This function retrieves the projector associated with an edge between two vertices, `v` and `w`, in a clustered Hamiltonian graph `cl_h`. If there is a directed edge from `w` to `v`, it returns the index of right projector (`:ipr`); if there is a directed edge from `v` to `w`, it returns the index of left projector (`:ipl`). If no edge exists between the vertices, it returns a vector of ones.
"""
function projector(cl_h::LabelledGraph{S, T}, v::NTuple{N, Int64}, w::NTuple{N, Int64}) where {S, T, N}
if has_edge(cl_h, w, v)
idx_p = get_prop(cl_h, w, v, :ipr)
Expand All @@ -256,6 +409,19 @@ function outer_projector(p1::Array{T, 1}, p2::Array{T, 1}) where T <: Number
reshape(reshape(p1, :, 1) .+ maximum(p1) .* reshape(p2 .- 1, 1, :), :)
end

"""
Create a sparse column-compressed (CSC) matrix with specified column indices and values.
# Arguments:
- `::Type{R}`: The element type of the sparse matrix (e.g., `Float64`, `Int64`).
- `p::Vector{Int64}`: A vector of column indices for the non-zero values.
# Returns:
- `sparse_matrix::SparseMatrixCSC{R}`: A sparse column-compressed matrix with non-zero values at specified columns.
This constructor function creates a sparse column-compressed (CSC) matrix of element type `R` based on the provided column indices `p` and values. The resulting matrix has non-zero values at the specified column indices, while all other elements are zero.
The `SparseCSC` constructor is useful for creating sparse matrices with specific column indices and values efficiently.
"""
function SparseCSC(::Type{R}, p::Vector{Int64}) where R <: Real
n = length(p)
mp = maximum(p)
Expand Down
Loading

0 comments on commit 1614f46

Please sign in to comment.