int main() { // Construct Network Network net("name", false); net.populate(10000); // Let's connect the network using an arbitrary degree distribution // Out of 10 nodes, none will have degrees 0 or 1, 1 will have degree 2 // 3 with degree 3, 2 with degree 4, 1 with degree 5, and 3 with degree 3 vector<double> degree_dist; double tmp_array[] = {0, 0, 1, 3, 2, 1, 3}; degree_dist.assign(tmp_array,tmp_array+7); // 5 == the length of tmp_array // Now make those probabilities that sum to 1 degree_dist = normalize_dist(degree_dist, sum(degree_dist)); // Finally, connect up the network using that user-defined degree distribution // Note that poisson, exponential, and scale-free random network generators are built-in net.rand_connect_user(degree_dist); // Simulation parameters int infectious_period = 10; // 10 days, hours, whatever double T = 0.05; // per timestep, per outbound edge probability of transmission for (int i = 0; i < 10; i++){ // Choose and run simulation ChainBinomial_Sim sim(&net, infectious_period, T); sim.rand_infect(1); sim.run_simulation(); cout << sim.epidemic_size() << endl; sim.reset(); } return 0; }
// generate a truncated, discretized powerlaw distribution (= zeta dist?) vector<double> gen_trunc_powerlaw(double alpha, double kappa, int min, int max) { vector<double> dist(max + 1); double sum = 0; for (int k = min; k <= max; k++) { double pk = powl(k, (long double) -alpha) * expl(-k/(long double) kappa); dist[k] = pk; sum += pk; if (pk/sum < EPSILON) break; } // Norm the distribution return normalize_dist(dist, sum); }
vector<double> gen_trunc_exponential(double lambda, int min, int max) { vector<double> dist(max + 1); if (lambda <= 0) { cerr << "Exponential distribution must have a positive parameter value\n"; return dist; } double sum = 0; for (int k = min; k <= max; k++) { double pk = lambda * exp(-lambda * k); dist[k] = pk; sum += pk; if (pk/sum < EPSILON) break; } // Norm the distribution return normalize_dist(dist, sum); }
vector<double> gen_trunc_poisson(double lambda, int min, int max) { vector<double> dist(max + 1, 0.0);//initializes distribution to all 0 double sum = 0.0; if (lambda < 500) { for (int k = (int) lambda; k >= min; k--) { dist[k] = poisson_pmf(lambda, k); sum += dist[k]; if ( dist[k]/sum < EPSILON) break; } for (int k = (int) lambda + 1; k <= max; k++) { dist[k] = poisson_pmf(lambda, k); sum += dist[k]; if ( dist[k]/sum < EPSILON) { dist.resize(k + 1); break; } } } else { // use a normal approximation, avoiding the factorial and pow calculations // by starting 9 SD's above lambda, we should capture all densities greater than EPSILON int prob_max = (int) (lambda + 9.0 * sqrt(lambda)); max = MIN(max, prob_max); dist.resize(max + 1); for (int k = max; k >= min; k--) { dist[k] = normal_cdf(k + 0.5, lambda, lambda); // 0.5 is a continuity correction if ( k < max ) { dist[k+1] -= dist[k]; sum += dist[k+1]; } if ( k < lambda and dist[k+1] < EPSILON) { dist[k] = 0; break; } } } return normalize_dist(dist, sum); }