diff --git a/scratch_code/sampler_performance.jl b/scratch_code/sampler_performance.jl
new file mode 100644
index 0000000000000000000000000000000000000000..a13e115e2294af36a7be854539db5ee2d5ea9f82
--- /dev/null
+++ b/scratch_code/sampler_performance.jl
@@ -0,0 +1,62 @@
+using Distributions
+using Random
+using RandomNumbers.Xorshifts
+struct ZWDist{BaseDistType,T} <: Sampleable{Univariate,Discrete}
+    α::T
+    base_dist::BaseDistType
+end
+
+function r1!(rng::AbstractRNG, s::ZWDist, l::T) where T<:AbstractVector
+    Random.rand!(rng,l)
+    l[l .< s.α] .= 0
+    Random.rand!(rng,s.base_dist,@view l[l .>= s.α])
+    return nothing
+end
+function r2!(rng::AbstractRNG, s::ZWDist, l::T) where T<:AbstractVector
+    rand!(rng, l)
+    l .= (l .>= s.α) .* rand(rng, s.base_dist, length(l))
+end
+function r3!(rng::AbstractRNG, s::ZWDist, l::T) where T<:AbstractVector
+    rand!(rng, l)
+    tmp = rand(rng, s.base_dist, length(l))
+    @inbounds for i in eachindex(l)
+     l[i] = (l[i] >= s.α) * tmp[i]
+    end
+    nothing
+end
+@views function r4!(rng::AbstractRNG, s::ZWDist, l::T) where T<:AbstractVector
+    rand!(rng, l)
+    mask = l .< s.α
+    fill!( l[mask], zero(eltype(l)))
+    mask .= .!mask
+    rand!(rng, s.base_dist, l[mask])
+    return nothing
+end
+using BenchmarkTools
+l = zeros(1000)
+r = Xoroshiro128Plus(1)
+s = ZWDist(0.5,Poisson())
+# @btime r1!(r,s,l);
+# @btime r2!(r,s,l);
+
+# @btime r3!(r,s,l);
+
+# @btime r4!(r,s,l);
+
+function test()
+    
+    s = ZWDist(0.5,Poisson())
+    res = Matrix{Float64}(undef, 4, 5)
+    for (i,size) in enumerate([10, 100, 1000, 10_000, 100_000])
+        l = zeros(size)
+        r = Xoroshiro128Plus(1)
+        res[1,i] = mean(@benchmark r1!(r,s,l)) |> time
+        r = Xoroshiro128Plus(1)
+        res[2,i] = mean(@benchmark r2!(r,s,l)) |> time
+        r = Xoroshiro128Plus(1)
+        res[3,i] = mean(@benchmark r3!(r,s,l)) |> time
+        r = Xoroshiro128Plus(1)
+        res[4,i] = mean(@benchmark r4!(r,s,l)) |> time
+    end
+    res
+end
\ No newline at end of file
diff --git a/src/utils.jl b/scratch_code/utils.jl
similarity index 100%
rename from src/utils.jl
rename to scratch_code/utils.jl
diff --git a/src/CovidAlertVaccinationModel.jl b/src/CovidAlertVaccinationModel.jl
index bf610af2b411c72f289caba1d3a5af79e01f348c..96c4c8e8cdb92e27d103243607319e856d5e7b43 100644
--- a/src/CovidAlertVaccinationModel.jl
+++ b/src/CovidAlertVaccinationModel.jl
@@ -17,6 +17,7 @@ using NamedTupleTools
 using NetworkLayout:Stress
 using NetworkLayout:SFDP
 import Base.rand
+import Random.rand!
 import LightGraphs.add_edge!
 
 include("agents.jl")
@@ -26,6 +27,7 @@ include("model.jl")
 include("plotting.jl")
 include("graphs.jl")
 
+const RNG = Xoroshiro128Star(1)
 const population = 14.57e6 #population of ontario
 
 const color_palette = palette(:seaborn_bright) #color theme for the plots
@@ -39,12 +41,12 @@ default(dpi = 300)
 default(framestyle = :box)
 using BenchmarkTools
 function main()
-    rng = Xoroshiro128Star(1)
-    agent_model = AgentModel(rng,5000,2)
+    agent_model = AgentModel(5000,2)
     # display(size.(agent_model.demographic_index_vectors))
-    u_0 = get_u_0(rng,length(agent_model.demographics))
-    steps = 10
-    @btime solve!($rng,$u_0,$get_parameters(),$steps,$agent_model,$vaccinate_uniformly!);
+    u_0 = get_u_0(length(agent_model.demographics))
+    steps = 300
+    @btime solve!($u_0,$get_parameters(),$steps,$agent_model,$vaccinate_uniformly!);
+    # solve!(u_0,get_parameters(),steps,agent_model,vaccinate_uniformly!);
     # plot_model(agent_model.base_network,graphs,sol1)
 end
 
diff --git a/src/agents.jl b/src/agents.jl
index 9c5dd7e60211b7bfbe1a7904afa4fe1d1f44331b..1632925ac3cc22d2eb2f1896cf11c521a1c4d568 100644
--- a/src/agents.jl
+++ b/src/agents.jl
@@ -15,17 +15,45 @@ end
 end
 
 
-struct AgentModel{GraphType,DistMatrix1,DistMatrix2}
+struct AgentModel{GraphType,DistMatrixList1,DistMatrixList2,DistMatrixList3}
     demographics::Vector{AgentDemographic}
     demographic_index_vectors::Vector{Vector{Int}}
     base_network::GraphType
-    workschool_contacts_mean_adjusted::DistMatrix1
-    rest_contacts_mean_adjusted::DistMatrix2
-    function AgentModel(rng,num_households,num_ltc)
-        pop_list,base_network,index_vectors = generate_population(rng,num_households,num_ltc)
-        workschool_contacts_mean_adjusted = symmetrize_means(length.(index_vectors),initial_workschool_mixing_matrix)
-        rest_contacts_mean_adjusted = symmetrize_means(length.(index_vectors),initial_rest_mixing_matrix)
-        return new{typeof(base_network),typeof(workschool_contacts_mean_adjusted),typeof(rest_contacts_mean_adjusted)}(pop_list,index_vectors,base_network,workschool_contacts_mean_adjusted,rest_contacts_mean_adjusted)
+    workschool_contacts_mean_adjusted_list::DistMatrixList1
+    rest_contacts_mean_adjusted_list::DistMatrixList2
+    home_contacts_duration_list::DistMatrixList3
+    function AgentModel(num_households,num_ltc)
+        pop_list,base_network,index_vectors = generate_population(num_households,num_ltc)
+        pop_sizes = length.(index_vectors)
+
+        workschool_contacts_mean_adjusted_list = [symmetrize_means(pop_sizes,initial_workschool_mixing_matrix)]
+        rest_contacts_mean_adjusted_list = [symmetrize_means(pop_sizes,initial_rest_mixing_matrix)]
+        home_contacts_duration_list = [symmetrize_means(pop_sizes,contact_time_distribution_matrix)]
+
+
+        workplace_data, distancing_data,residential_data = get_distancing_data_sets()
+        @assert length(workplace_data) == length(distancing_data) == length(residential_data) "uh oh your data is different lengths!"
+        
+        for t in 1:length(workplace_data)
+            push!(workschool_contacts_mean_adjusted_list, adjust_distributions_mean(workschool_contacts_mean_adjusted_list[1], workplace_data[t]))
+            push!(rest_contacts_mean_adjusted_list, adjust_distributions_mean(rest_contacts_mean_adjusted_list[1], distancing_data[t]))
+            push!(home_contacts_duration_list, adjust_distributions_mean(home_contacts_duration_list[1], residential_data[t]))
+        end
+
+
+        return new{
+            typeof(base_network),
+            typeof(workschool_contacts_mean_adjusted_list),
+            typeof(rest_contacts_mean_adjusted_list),
+            typeof(home_contacts_duration_list)
+        }(
+            pop_list,
+            index_vectors,
+            base_network,
+            workschool_contacts_mean_adjusted_list,
+            rest_contacts_mean_adjusted_list,
+            home_contacts_duration_list
+            )
     end
 end
 
diff --git a/src/data.jl b/src/data.jl
index 0f2f7093507a6734fc769e62b5da4ab28705bd50..f125cffb81346d8c46416e5c6480be2d2ac90485 100644
--- a/src/data.jl
+++ b/src/data.jl
@@ -10,7 +10,15 @@ function get_canada_demographic_distribution()::Vector{Float64}
     source_bins = map(parse_string_as_float_pair, df[:,:demographic_data_bins])
     return [sum(binned_data[1:5]),sum(binned_data[6:13]),sum(binned_data[14:end])]
 end
-
+function get_distancing_data_sets()::NTuple{3,Vector{Float64}}
+    f = readdlm(joinpath(PACKAGE_FOLDER,"data/csv/distancing_data.csv"), ',')
+    df = filter(row -> row[:country_region_code] == "CA" && row[:sub_region_1] == "Ontario", DataFrame([f[1,i] => f[2:end, i] for i = 1:length(f[1,:])]))
+    distancing_data = df[:,:retail_and_recreation_percent_change_from_baseline] ./ 100
+    workplace_data = df[:,:workplaces_percent_change_from_baseline] ./ 100
+    residental_data = df[:,:residential_percent_change_from_baseline] ./ 100
+    
+    return (workplace_data, distancing_data,residental_data)
+end
 
 function get_canada_case_fatality()::Tuple{Vector{Tuple{Float64,Float64}},Vector{Float64}}
     f = readdlm(joinpath(PACKAGE_FOLDER,"data/csv/case_fatality_data.csv"), ',')
@@ -35,12 +43,12 @@ function find_household_composition(df_row)
     age_distribution[age_resp_to_bin[df_row[:AGERESP]]] += 1
     return age_distribution
 end
-function sample_household_data(rng,n)
+function sample_household_data(n)
     f = readdlm(joinpath(PACKAGE_FOLDER,"data/csv/home_compositions.csv"), ',')
     df = DataFrame([f[1,i] => f[2:end, i] for i = 1:length(f[1,:])])
     weight_vector::Vector{Float64} = df[!,:WGHT_PER]/sum(df[!,:WGHT_PER])
     households = map(find_household_composition,eachrow(df))
-    return sample(rng,households, Weights(weight_vector),n)
+    return sample(RNG,households, Weights(weight_vector),n)
     # https://www.publichealthontario.ca/-/media/documents/ncov/epi/covid-19-severe-outcomes-ontario-epi-summary.pdf?la=en
 end
 
diff --git a/src/graphs.jl b/src/graphs.jl
index 6f9d02a797869c7b648c3038c5a61e059df5f340..dc6874975f29eb1c710b0454dab3f25b55dba393 100644
--- a/src/graphs.jl
+++ b/src/graphs.jl
@@ -1,48 +1,61 @@
 
 #add a bipartite graph derived from mixing matrices onto g
-function generate_mixing_graph!(rng,g,index_vectors,mixing_matrix)
+function generate_mixing_graph!(g,index_vectors,mixing_matrix)
     for i in 1:5, j in 1:i #diagonal
             agent_contact_dist_i = mixing_matrix[i,j]
             agent_contact_dist_j = mixing_matrix[j,i]
-            i_to_j_contacts = rand(rng,agent_contact_dist_i,length(index_vectors[i]))
-            
-            j_to_i_contacts = rand(rng,agent_contact_dist_j,length(index_vectors[j]))
-            
-            # equalize_degree_lists!(rng,i_to_j_contacts,j_to_i_contacts)
+            l_i = length(index_vectors[i])
+            l_j = length(index_vectors[j])
+            i_to_j_contacts = rand(RNG,agent_contact_dist_i,l_i)
+            j_to_i_contacts = rand(RNG,agent_contact_dist_j,l_j)
             contacts_sums = sum(i_to_j_contacts) - sum(j_to_i_contacts)
 
-            while contacts_sums != 0
-                i_index = sample(rng,1:length(index_vectors[i]))
-                j_index = sample(rng,1:length(index_vectors[j]))
-
-                contacts_sums -= i_to_j_contacts[i_index]  
-                contacts_sums += j_to_i_contacts[j_index]  
-
-                i_to_j_contacts[i_index] = rand(rng,agent_contact_dist_i)
-                j_to_i_contacts[j_index] = rand(rng,agent_contact_dist_j)
 
-                contacts_sums += i_to_j_contacts[i_index]  
-                contacts_sums -= j_to_i_contacts[j_index]  
+            # display((mean(agent_contact_dist_i)*l_i,mean(agent_contact_dist_j)*l_j))
+            sample_list_length = max(l_j,l_i) #better heuristic for this based on stddev of dist?
+            index_list_i = sample(RNG,1:l_i,sample_list_length)
+            index_list_j = sample(RNG,1:l_j,sample_list_length)
+            sample_list_i = rand(RNG,agent_contact_dist_i,sample_list_length)
+            sample_list_j = rand(RNG,agent_contact_dist_j,sample_list_length)
+            for k = 1:sample_list_length
+                if (contacts_sums != 0)
+                    i_index = index_list_i[k]
+                    j_index = index_list_j[k]    
+                    contacts_sums +=  j_to_i_contacts[j_index] - i_to_j_contacts[i_index]
+
+                    i_to_j_contacts[i_index] = sample_list_i[k]
+                    j_to_i_contacts[j_index] = sample_list_j[k]    
+                    contacts_sums += i_to_j_contacts[i_index] -  j_to_i_contacts[j_index]
+                else
+                    break
+                end
+            end
+            while contacts_sums != 0
+                i_index = sample(RNG,1:l_i)
+                j_index = sample(RNG,1:l_j)
+                contacts_sums +=  j_to_i_contacts[j_index] - i_to_j_contacts[i_index]
+                i_to_j_contacts[i_index] = rand(RNG,agent_contact_dist_i)
+                j_to_i_contacts[j_index] = rand(RNG,agent_contact_dist_j)
+                contacts_sums += i_to_j_contacts[i_index] -  j_to_i_contacts[j_index]
             end
-            # random_bipartite_graph_fast_CL!(rng,g,index_vectors[i],index_vectors[j],i_to_j_contacts,j_to_i_contacts)
+            random_bipartite_graph_fast_CL!(g,index_vectors[i],index_vectors[j],i_to_j_contacts,j_to_i_contacts)
     end
     return g
 end
-# function searchsortedfirst(l,things_to_find::T) where T<:AbstractVector
-
-# end
-
 
 #modify g so that nodes specified in anodes and bnodes are connected by a bipartite graph with expected degrees given by aseq and bseq
 #implemented from Aksoy, S. G., Kolda, T. G., & Pinar, A. (2017). Measuring and modeling bipartite graphs with community structure
 #simple algorithm, might produce parallel edges for small graphs
-function random_bipartite_graph_fast_CL!(rng,g,anodes,bnodes,aseq,bseq) 
+
+using StatsBase
+
+function random_bipartite_graph_fast_CL!(g,anodes,bnodes,aseq,bseq) 
     lena = length(aseq)
     lenb = length(bseq)
-    m = sum(aseq)
+    m = Int(sum(aseq))
     @assert sum(aseq) == sum(bseq) "degree sequences must have equal sum"
-    astubs = sample(rng,anodes,StatsBase.weights(aseq./m), m; replace = true)
-    bstubs = sample(rng,bnodes,StatsBase.weights(bseq./m), m; replace = true)
+    astubs = sample(RNG,anodes,StatsBase.weights(aseq./m), m)
+    bstubs = sample(RNG,bnodes,StatsBase.weights(bseq./m), m)
     for k in 1:m
         add_edge!(g,astubs[k],bstubs[k])
     end
@@ -51,35 +64,33 @@ end
 
 function symmetrize_means(population_sizes,mixing_matrix::Matrix{<:ZWDist})
     mixing_means = mean.(mixing_matrix)
-    symmetrized_mixing = similar(mixing_matrix)
+    symmetrized_means = zeros((length(population_sizes),length(population_sizes)))
     for i in 1:length(population_sizes), j in 1:length(population_sizes)
-        symmetrized_mean = 0.5*(mixing_means[i,j] + population_sizes[j]/population_sizes[i] * mixing_means[j,i])
-        symmetrized_mixing[i,j] = from_mean(typeof(mixing_matrix[i,j]),mixing_matrix[i,j].α,symmetrized_mean)
+        symmetrized_means[i,j] = 0.5*(mixing_means[i,j] + population_sizes[j]/population_sizes[i] * mixing_means[j,i])
     end
-    return symmetrized_mixing
+    return map(((dst,sym_mean),)->from_mean(typeof(dst),dst.α,sym_mean), zip(mixing_matrix,symmetrized_means))
 end
 
 
 function symmetrize_means(population_sizes,mixing_matrix::Matrix{<:Distribution})
     mixing_means = mean.(mixing_matrix)
-    symmetrized_mixing = similar(mixing_matrix)
+    symmetrized_means = zeros((length(population_sizes),length(population_sizes)))
+
     for i in 1:length(population_sizes), j in 1:length(population_sizes)
-        symmetrized_mean = 0.5*(mixing_means[i,j] + population_sizes[j]/population_sizes[i] * mixing_means[j,i])
-       
-        symmetrized_mixing[i,j] = from_mean(typeof(mixing_matrix[i,j]),symmetrized_mean)
+        symmetrized_means[i,j] = 0.5*(mixing_means[i,j] + population_sizes[j]/population_sizes[i] * mixing_means[j,i])
     end
-    return symmetrized_mixing
+    return map(((dst,sym_mean),)->from_mean(typeof(dst),sym_mean), zip(mixing_matrix,symmetrized_means))
 end
 
 #generate population with households distributed according to household_size_distribution
 #Assume 5% of elderly are in LTC roughly, these are divide evenly among a specific number of LTC ltc_homes
 #LTC homes and households are assumed to be complete static graphs.
-function generate_population(rng,num_households,num_LTC)
+function generate_population(num_households,num_LTC)
     # LTC_sizes = rand(LTC_distribution,num_LTC)
     prob_adult_is_HCW = 0.01#assume 1% of adults are HCW
     prob_elderly_in_LTC = 0.05 #5% of elderly are in LTC
 
-    households_composition = sample_household_data(rng,num_households)
+    households_composition = sample_household_data(num_households)
     households = map( l -> [fill(AgentDemographic(i),n) for (i,n) in enumerate(l)],households_composition) |>
                     l -> reduce(vcat,l) |>
                     l -> reduce(vcat,l)
@@ -90,7 +101,7 @@ function generate_population(rng,num_households,num_LTC)
     ltc_pop_list = fill(ElderlyLTC,ltc_pop)
 
     adults_indices = findall(x -> x == Adult, households)
-    households[sample(rng,adults_indices,hcw_pop)] .= AdultHCW
+    households[sample(RNG,adults_indices,hcw_pop)] .= AdultHCW
 
     ltc_home_size = Int(ceil(ltc_pop/num_LTC))
     @assert ltc_home_size != 0 error("must have at least one LTC resident,make problem larger")
diff --git a/src/mixing_distributions.jl b/src/mixing_distributions.jl
index 40b69fc65d05065cc27a30814b99788e160b3aec..e052f8bf0f6e3960c6856f05eb1d9c4456d285b1 100644
--- a/src/mixing_distributions.jl
+++ b/src/mixing_distributions.jl
@@ -3,18 +3,27 @@ struct ZWDist{BaseDistType,T} <: Sampleable{Univariate,Discrete}
     α::T
     base_dist::BaseDistType
 end
-function Base.rand(rng::AbstractRNG, s::ZWDist)
-    if Base.rand(rng) < s.α
-        return 0
-    else
-        return Base.rand(rng,s.base_dist)
-    end
+function Base.rand(rng::AbstractRNG,  s::ZWDist{DType,EType}, n::T) where {T<:Int, EType, DType}
+    l = Vector{EType}(undef,n)
+    Random.rand!(rng,l)
+    l[l .< s.α] .= 0
+    Random.rand!(rng,s.base_dist,@view l[l .>= s.α])
+    return l
+end
+function Random.rand!(rng::AbstractRNG, s::ZWDist, l::T) where T<:AbstractVector
+    Random.rand!(rng,l)
+    l[l .< s.α] .= 0
+    Random.rand!(rng,s.base_dist,@view l[l .>= s.α])
+    return l
 end
 
-function Base.rand(rng::AbstractRNG, s::ZWDist, n::T) where T<:Int
-    return ifelse.(Base.rand(rng,n) .< s.α, 0, Base.rand(rng,s.base_dist,n))
+
+function Base.rand(rng::AbstractRNG, s::ZWDist{DType,T}) where {DType,T}
+    return ifelse(Base.rand(rng) < s.α, zero(T), Base.rand(rng,s.base_dist))
 end
 
+
+
 function from_mean(::Type{Geometric{T}},μ) where T
     if μ > 1.0
         return Geometric(1/(μ+1))
@@ -36,27 +45,43 @@ function ZeroGeometric(α,p)
     return ZWDist(α,Geometric(p))
 end
 
+function adjust_distributions_mean(distribution_matrix::AbstractArray{T},mean_shift_percentage) where T<:ZWDist
+    return map(distribution_matrix) do dist
+        new_mean = mean(dist)*(1 + mean_shift_percentage)
+        return from_mean(typeof(dist),dist.α, new_mean)
+    end
+end
+function adjust_distributions_mean(distribution_matrix::AbstractArray{T},mean_shift_percentage) where T<:Distribution
+    return map(distribution_matrix) do dist
+        new_mean = mean(dist)*(1 + mean_shift_percentage)
+        return from_mean(typeof(dist), new_mean)
+    end
+end
+
+
+
 StatsBase.mean(d::ZWDist{Dist,T}) where {Dist,T} = (1 - d.α)*StatsBase.mean(d.base_dist)
+
 const initial_workschool_type = Union{ZWDist{Geometric{Float64},Float64},ZWDist{Poisson{Float64},Float64}}
 
-const initial_workschool_mixing_matrix = map(t->from_mean(t...),[
+const initial_workschool_mixing_matrix = convert(Array{initial_workschool_type},map(t->from_mean(t...),[
     (ZWDist{Geometric{Float64},Float64}, 0.433835,4.104848) (ZWDist{Geometric{Float64},Float64},0.406326,2.568782) (ZWDist{Poisson{Float64},Float64},0.888015,0.017729) (ZWDist{Geometric{Float64},Float64},0.406326,2.568782) (ZWDist{Poisson{Float64},Float64},0.888015,0.017729)
     (ZWDist{Geometric{Float64},Float64}, 0.600966,0.975688) (ZWDist{Geometric{Float64},Float64},0.4306,5.057572) (ZWDist{Poisson{Float64},Float64}, 0.84513,0.021307) (ZWDist{Geometric{Float64},Float64},0.4306,5.057572) (ZWDist{Poisson{Float64},Float64}, 0.84513,0.021307)
     (ZWDist{Poisson{Float64},Float64},0.887392,0.001937)   (ZWDist{Poisson{Float64},Float64},0.793004,0.00722)   (ZWDist{Poisson{Float64},Float64},0.940473, 0.022134) (ZWDist{Poisson{Float64},Float64},0.793004,0.00722)   (ZWDist{Poisson{Float64},Float64},0.940473, 0.022134)
     (ZWDist{Geometric{Float64},Float64}, 0.600966,0.975688) (ZWDist{Geometric{Float64},Float64},0.4306,5.057572) (ZWDist{Poisson{Float64},Float64}, 0.84513,0.021307) (ZWDist{Geometric{Float64},Float64},0.4306,5.057572) (ZWDist{Poisson{Float64},Float64}, 0.84513,0.021307)
     (ZWDist{Poisson{Float64},Float64},0.887392,0.001937)   (ZWDist{Poisson{Float64},Float64},0.793004,0.00722)   (ZWDist{Poisson{Float64},Float64},0.940473, 0.022134) (ZWDist{Poisson{Float64},Float64},0.793004,0.00722)   (ZWDist{Poisson{Float64},Float64},0.940473, 0.022134)
-])
+]))
 
 
 const initial_rest_type = Union{Geometric{Float64},Poisson{Float64}}
-const initial_rest_mixing_matrix = map(t->from_mean(t...),[
+const initial_rest_mixing_matrix =  convert(Array{initial_rest_type},map(t->from_mean(t...),[
     (Geometric{Float64},2.728177)  (Geometric{Float64},1.382557)        (Poisson{Float64},0.206362)    (Geometric{Float64},1.382557)        (Poisson{Float64},0.206362) 
     (Poisson{Float64},1.139072)    (Geometric{Float64},3.245594)        (Poisson{Float64},0.785297)    (Geometric{Float64},3.245594)        (Poisson{Float64},0.785297)   
     (Poisson{Float64},0.264822)    (Poisson{Float64},0.734856)          (Poisson{Float64},0.667099)    (Poisson{Float64},0.734856)          (Poisson{Float64},0.667099)  
     (Poisson{Float64},1.139072)    (Geometric{Float64},3.245594)        (Poisson{Float64},0.785297)    (Geometric{Float64},3.245594)        (Poisson{Float64},0.785297)   
     (Poisson{Float64},0.264822)    (Poisson{Float64},0.734856)          (Poisson{Float64},0.667099)    (Poisson{Float64},0.734856)          (Poisson{Float64},0.667099)  
-])
+]))
 
-const contact_time_distribution_matrix = [Geometric() for i in 1:AgentDemographic.size + 1, j in 1:AgentDemographic.size + 1]
+const contact_time_distribution_matrix = convert(Array{initial_rest_type},[Geometric() for i in 1:AgentDemographic.size + 1, j in 1:AgentDemographic.size + 1])
 
 
diff --git a/src/model.jl b/src/model.jl
index dd28dbbcaa35d7254c45ad3daa8dcb6322fb5a3b..43bedcc996204d5ae43445aabbfbf3a3d30a7925 100644
--- a/src/model.jl
+++ b/src/model.jl
@@ -1,41 +1,41 @@
-function get_u_0(rng,nodes)
+function get_u_0(nodes)
     u_0 = fill(Susceptible,nodes)
-    init_indices = rand(rng, 1:nodes, 5)
+    init_indices = rand(RNG, 1:nodes, 5)
     u_0[init_indices] .= Infected #start with two infected
     return u_0
 end
 
-function contact_weight(rand_gen,p, agent_v,agent_w) 
-    contact_time = rand(rand_gen,contact_time_distribution_matrix[Int(agent_v),Int(agent_w)])
+function contact_weight(p, agent_v,agent_w) 
+    contact_time = rand(RNG,contact_time_distribution_matrix[Int(agent_v),Int(agent_w)])
     return 1 - (1-p)^contact_time
 end
 
-function vaccinate_uniformly!(rng,num_vaccines,u_next,u,graph,population_list,index_vectors) #vaccination_algorithm
-    vaccination_indices = rand(rng,1:length(u),num_vaccines)
+function vaccinate_uniformly!(num_vaccines,u_next,u,graph,population_list,index_vectors) #vaccination_algorithm
+    vaccination_indices = rand(RNG,1:length(u),num_vaccines)
     u_next[vaccination_indices] .= Immunized
 end
-function hotspotting!(rng,num_vaccines,u_next,u,graph,population_list,index_vectors) #vaccination_algorithm
-    # vaccination_indices = rand(rng,1:length(u),num_vaccines)
+function hotspotting!(num_vaccines,u_next,u,graph,population_list,index_vectors) #vaccination_algorithm
+    # vaccination_indices = rand(RNG,1:length(u),num_vaccines)
     # u_next[vaccination_indices] .= Immunized
 end
-function agents_step!(rand_gen,t,u_next,u,population_list,graph,params,index_vectors,vaccination_algorithm!)
+function agents_step!(t,u_next,u,population_list,graph,params,index_vectors,vaccination_algorithm!)
     @unpack p, recovery_rate, vaccines_per_day,vaccination_start_day  = params  
     u_next .= u#keep state the same if nothing else happens
     
     if t >= vaccination_start_day
-        vaccination_algorithm!(rand_gen,Int(floor(vaccines_per_day*length(u))),u_next,u,graph,population_list,index_vectors) 
+        vaccination_algorithm!(Int(floor(vaccines_per_day*length(u))),u_next,u,graph,population_list,index_vectors) 
     end
     for i in 1:length(u)
         agent_status = u[i]
         agent_demo = population_list[i]
         if agent_status == Susceptible
             for j in LightGraphs.neighbors(graph,i)
-                if u[j] == Infected && rand(rand_gen) < contact_weight(rand_gen,p, agent_demo,population_list[j])
+                if u[j] == Infected && rand(RNG) < contact_weight(p, agent_demo,population_list[j])
                     u_next[i] = Infected
                 end
             end
         elseif agent_status == Infected
-            if rand(rand_gen) < recovery_rate
+            if rand(RNG) < recovery_rate
                 u_next[i] = Recovered
             end
         end
@@ -43,7 +43,7 @@ function agents_step!(rand_gen,t,u_next,u,population_list,graph,params,index_vec
 end
 
 
-function solve!(rng,u_0,params,steps,agent_model,vaccination_algorithm!)
+function solve!(u_0,params,steps,agent_model,vaccination_algorithm!)
     solution = vcat([u_0], [fill(Susceptible,length(u_0)) for i in 1:steps])
 
     population_list = agent_model.demographics #list of demographic status for each agent
@@ -52,10 +52,10 @@ function solve!(rng,u_0,params,steps,agent_model,vaccination_algorithm!)
     graphs = [base_network]
     for t in 1:steps
         graph_t = deepcopy(base_network) #copy static network to modify with dynamic workschool/rest contacts
-        generate_mixing_graph!(rng,graph_t,index_vectors,agent_model.workschool_contacts_mean_adjusted) #add workschool contacts
-        # generate_mixing_graph!(rng,graph_t,index_vectors,agent_model.rest_contacts_mean_adjusted) #add rest contacts
-        # push!(graphs,graph_t) #add the generated graph for this timestep onto the list of graphs 
-        # agents_step!(rng,t,solution[t+1],solution[t],population_list,graph_t,params,index_vectors,vaccination_algorithm!) 
+        generate_mixing_graph!(graph_t,index_vectors,agent_model.workschool_contacts_mean_adjusted_list[t]) #add workschool contacts
+        generate_mixing_graph!(graph_t,index_vectors,agent_model.rest_contacts_mean_adjusted_list[t]) #add rest contacts
+        push!(graphs,graph_t) #add the generated graph for this timestep onto the list of graphs 
+        agents_step!(t,solution[t+1],solution[t],population_list,graph_t,params,index_vectors,vaccination_algorithm!) 
         #advance agent states based on the new network, vaccination process given by vaccination_algorithm!, which is just a function defined as above
     end
    
diff --git a/src/vaccination.jl b/src/vaccination.jl
deleted file mode 100644
index af509e65eb6d6be249294b0418c39ac592b2e84b..0000000000000000000000000000000000000000
--- a/src/vaccination.jl
+++ /dev/null
@@ -1,3 +0,0 @@
-abstract type VaccinationStrategy end
-
-
diff --git a/test/runtests.jl b/test/runtests.jl
index 49e2c0b5d83157b4db641622eb6db05c7ea1316e..8eda42451d45ceb7492805320f2147005b106037 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -3,44 +3,47 @@ using RandomNumbers.Xorshifts
 using Test
 using ThreadsX
 import StatsBase.mean
-rng = Xoroshiro128Plus(1)
-model_sizes = [(100,1),(1000,3),(5000,3),(5000,50)]
+model_sizes = [(100,1),(1000,3),(5000,3)]
 vaccination_stratgies = [vaccinate_uniformly!]
 vaccination_rates = [0.0001,0.001,0.005,0.01,0.05]
 infection_rates = [0.01,0.05,0.1]
-agent_models = ThreadsX.map(model_size -> AgentModel(rng,model_size...), model_sizes)
+agent_models = ThreadsX.map(model_size -> AgentModel(model_size...), model_sizes)
 dem_cat = AgentDemographic.size + 1
 
 
 
 @testset "mixing matrices, size: $sz" for (m,sz) in zip(agent_models,model_sizes)
-    ws_dist = m.workschool_contacts_mean_adjusted
-    r_dist = m.rest_contacts_mean_adjusted
+    ws_dist = m.workschool_contacts_mean_adjusted_list
+    r_dist = m.rest_contacts_mean_adjusted_list
     index_vec =m.demographic_index_vectors
     @testset "workschool" for i in dem_cat, j in dem_cat
-        @test mean(ws_dist[i,j])*length(index_vec[i]) == mean(ws_dist[j,i])*length(index_vec[j])
+        for t in 1:length(ws_dist)
+            @test mean(ws_dist[t][i,j])*length(index_vec[i]) == mean(ws_dist[t][j,i])*length(index_vec[j])
+        end
      end
      @testset "rest" for i in dem_cat, j in dem_cat
-        @test mean(r_dist[i,j])*length(index_vec[i]) == mean(r_dist[j,i])*length(index_vec[j])
+        for t in 1:length(ws_dist)
+            @test mean(r_dist[t][i,j])*length(index_vec[i]) == mean(r_dist[t][j,i])*length(index_vec[j])
+        end
     end
 end
 
 
 function vac_rate_test(model,vac_strategy, vac_rate; rng = Xoroshiro128Plus()) 
-    u_0 = get_u_0(rng,length(model.demographics))
+    u_0 = get_u_0(length(model.demographics))
     params = merge(get_parameters(),(vaccines_per_day = vac_rate,))
     steps = 300
-    sol1,graphs = solve!(rng,u_0,params,steps,model,vac_strategy);
+    sol1,graphs = solve!(u_0,params,steps,model,vac_strategy);
     total_infections = count(x->x == AgentStatus(3),sol1[end])
     return total_infections
 end
 
 
 function infection_rate_test(model, inf_parameter; rng = Xoroshiro128Plus()) 
-    u_0 = get_u_0(rng,length(model.demographics))
+    u_0 = get_u_0(length(model.demographics))
     params = merge(get_parameters(),(p = inf_parameter,))
     steps = 300
-    sol1,graphs = solve!(rng,u_0,params,steps,model,vaccinate_uniformly!);
+    sol1,graphs = solve!(u_0,params,steps,model,vaccinate_uniformly!);
     total_infections = count(x->x == AgentStatus(3),sol1[end])
 
     return total_infections
@@ -54,11 +57,11 @@ end
 
 @testset "vaccination efficacy $sz" for (m,sz) in zip(deepcopy(agent_models),model_sizes)
     @testset "strategy" for strat in vaccination_stratgies
-        @test test_comparison(x->vac_rate_test(m,strat,x),vaccination_rates,>=)
+        @test test_comparison(x->vac_rate_test(m,strat,x),vaccination_rates,>)
     end
 end
 
 @testset "infection efficacy $sz" for (m,sz) in zip(deepcopy(agent_models),model_sizes)
-    @test test_comparison(x->infection_rate_test(m,x),infection_rates,<=)
+    @test test_comparison(x->infection_rate_test(m,x),infection_rates,<)
 end