Commit d692122d by Peter Jentsch

### 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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!