Commit d692122d authored by Peter Jentsch's avatar Peter Jentsch
Browse files

tests pass

parent 239cdbbb
......@@ -81,7 +81,7 @@ Assumes the simulation begins on Thursday arbitrarily.
"""
function time_dep_mixing_graphs(len,base_network,demographics,index_vectors,ws_matrix_tuple,rest_matrix_tuple)
home_static_edges = WeightedGraph(base_network,demographics,index_vectors,contact_time_distributions.hh) #network with households and LTC homes
home_static_edges = WeightedGraph(base_network,demographics,contact_time_distributions.hh) #network with households and LTC homes
ws_static_edges = WeightedGraph(demographics,index_vectors,ws_matrix_tuple.daily,contact_time_distributions.ws)
ws_weekly_edges = WeightedGraph(demographics,index_vectors,ws_matrix_tuple.twice_a_week,contact_time_distributions.ws)
......@@ -122,13 +122,11 @@ function remake!(t,time_dep_mixing_graph,index_vectors,demographics)
remake!(wg,index_vectors)
end
# display_degree(time_dep_mixing_graph.resampled_graphs[1])
for wg in time_dep_mixing_graph.resampled_graphs
if wg in time_dep_mixing_graph.graph_list[t]
sample_mixing_edges!(wg.weights_dict,wg.sampler_matrix,demographics)
end
end
# display_degree(time_dep_mixing_graph.resampled_graphs[1])
end
......@@ -141,14 +139,6 @@ Fields
Stores the actual graph structure
contact_array::Matrix{Tuple{Vector{Int},Vector{Int}}}
A matrix of vector pairs, such that one node is in the first vector and the other is in the second. The position of the vector pairs in the matrix corresponds to the distribution in sampler_matrix used to sample them. There is probably a better way to represent these, I did this so they could be sampled fast. We only use the upper triangle of this but Julia lacks a good Symmetric matrix type.
sample_cache::Matrix{Vector{Int}}
The structure that pre-allocates the space for the weights of the edges in contact array. This is filled with weights and then the weights are added to weights_dict. We only use the upper triangle of this but Julia lacks a good Symmetric matrix type.
weights_dict::Dictionary{GraphEdge,UInt8}
Stores the weights used in the graph, so they can be easily resampled.
......@@ -163,7 +153,7 @@ Matrix of distributions determining node degrees
Matrix of distributions determining the edge weights
"""
mutable struct WeightedGraph{G,M1,M2}
struct WeightedGraph{G,M1,M2}
g::G
weights_dict::Dictionary{GraphEdge,UInt8}
mixing_matrix::M1
......@@ -171,18 +161,7 @@ mutable struct WeightedGraph{G,M1,M2}
function WeightedGraph(demographics::AbstractVector,index_vectors,mixing_matrix::M1, sampler_matrix::M2) where {M1,M2}
g = Graph(length(demographics))
weights_dict = Dictionary{GraphEdge,UInt8}()
for i in 1:3, j in 1:i #diagonal
if i != j
edges = fast_chung_lu_bipartite(index_vectors[i],index_vectors[j],mixing_matrix[i,j],mixing_matrix[j,i])
else #from one group to itself we need another algorithm
edges = fast_chung_lu(index_vectors[i],mixing_matrix[i,i])
end
for e in edges
edge_weight_k = rand(Random.default_rng(Threads.threadid()),sampler_matrix[j,i])
set!(weights_dict, e, edge_weight_k)
add_edge!(g,e.a,e.b)
end
end
assemble_graph!(g,weights_dict,index_vectors,mixing_matrix,sampler_matrix)
return new{typeof(g),M1,M2}(
g,
weights_dict,
......@@ -190,7 +169,7 @@ mutable struct WeightedGraph{G,M1,M2}
sampler_matrix,
)
end
function WeightedGraph(g::G,demographics,index_vectors,sampler_matrix::M2) where {G<:SimpleGraph,M2}
function WeightedGraph(g::G,demographics,sampler_matrix::M2) where {G<:SimpleGraph,M2}
weights_dict = Dictionary{GraphEdge,UInt8}(;sizehint = ne(g))
for e in edges(g)
j = src(e)
......@@ -211,27 +190,26 @@ function remake!(wg::WeightedGraph,index_vectors)
empty!.(wg.g.fadjlist) #empty all the vector edgelists
wg.g.ne = 0
empty!(wg.weights_dict)
assemble_graph!(wg.g,wg.weights_dict,index_vectors,wg.mixing_matrix,wg.sampler_matrix)
end
function assemble_graph!(g,weights_dict,index_vectors,mixing_matrix,sampler_matrix)
for i in 1:3, j in 1:i #diagonal
if i != j
edges = fast_chung_lu_bipartite(index_vectors[i],index_vectors[j],wg.mixing_matrix[i,j],wg.mixing_matrix[j,i])
edges = fast_chung_lu_bipartite(index_vectors[i],index_vectors[j],mixing_matrix[i,j],mixing_matrix[j,i])
else #from one group to itself we need another algorithm
edges = fast_chung_lu(index_vectors[i],wg.mixing_matrix[i,i])
edges = fast_chung_lu(index_vectors[i],mixing_matrix[i,i])
end
for e in edges
edge_weight_k = rand(Random.default_rng(Threads.threadid()),wg.sampler_matrix[j,i])
set!(wg.weights_dict, e, edge_weight_k)
add_edge!(wg. g,e.a,e.b)
edge_weight_k = rand(Random.default_rng(Threads.threadid()),sampler_matrix[j,i])
set!(weights_dict, e, edge_weight_k)
end
end
for e in keys(weights_dict)
add_edge!(g,e.a,e.b)
end
end
neighbors(g::WeightedGraph,i) = neighbors(g.g,i)
get_weight(g::WeightedGraph,e) = g.weights_dict[e]
function Base.show(io::IO, g::WeightedGraph)
print(io, "WG $(ne(g.g))")
end
function fast_chung_lu_bipartite(pop_i,pop_j,mixing_dist_ij,mixing_dist_ji)
num_degrees_ij = similar(pop_i)
num_degrees_ji = similar(pop_j)
......@@ -245,6 +223,7 @@ function fast_chung_lu_bipartite(pop_i,pop_j,mixing_dist_ij,mixing_dist_ji)
end
return GraphEdge.(stubs_i,stubs_j)
end
function fast_chung_lu(pop_i,mixing_dist)
num_degrees_ii = similar(pop_i)
generate_contact_vectors!(mixing_dist,num_degrees_ii)
......@@ -257,4 +236,12 @@ function fast_chung_lu(pop_i,mixing_dist)
sample!(Random.default_rng(Threads.threadid()),pop_i,Weights(num_degrees_ii./m),stubs_j)
end
return GraphEdge.(stubs_i,stubs_j)
end
\ No newline at end of file
end
neighbors(g::WeightedGraph,i) = neighbors(g.g,i)
get_weight(g::WeightedGraph,e) = g.weights_dict[e]
function Base.show(io::IO, g::WeightedGraph)
print(io, "WG $(ne(g.g))")
end
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment