static void check0 (void) { mpz_t y; mpfr_t x; int inexact, r; mpfr_exp_t e; /* Check for +0 */ mpfr_init (x); mpz_init (y); mpz_set_si (y, 0); for (r = 0; r < MPFR_RND_MAX; r++) { e = randexp (); inexact = mpfr_set_z_2exp (x, y, e, (mpfr_rnd_t) r); if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact) { printf ("mpfr_set_z_2exp(x,0,e) failed for e="); if (e < LONG_MIN) printf ("(<LONG_MIN)"); else if (e > LONG_MAX) printf ("(>LONG_MAX)"); else printf ("%ld", (long) e); printf (", rnd=%s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r)); exit (1); } } mpfr_clear(x); mpz_clear(y); }
// event router static Event* event_router(Customer* c,int component_id) { Event *event = NULL; switch(component_list[component_id]->type) { case 'Q': { Queue *queue = C2Q(component_list[component_id]); if(is_queue_empty(queue)) { event = (Event*)malloc(sizeof(Event)); event->component_id = component_id; event->event_type = DEPARTURE; event->serve_time = randexp(queue->P); event->timestamp = now_time+ event->serve_time; event->next = NULL; }else event = NULL; en_queue(queue,c); }break; case 'F': { Fork *fork = C2F(component_list[component_id]); event = event_router(c,simulation_fork(fork)); }break; case 'E': { Exit *_exit = C2E(component_list[component_id]); simulation_exit(_exit,c); event = NULL; }break; } return event; }
//create customer static double generate_customer(Generator* generator,double current_time,Customer** c) { double next_time = current_time+randexp(generator->P); (*c) = (Customer*)malloc(sizeof(Customer)); (*c)->next = NULL; (*c)->prev = NULL; (*c)->time_create = current_time; (*c)->time_stamp = 0; (*c)->time_wait = 0; enter_customer++; return next_time; }
static void check (long i, mpfr_rnd_t rnd) { mpfr_t f; mpz_t z; mpfr_exp_t e; int inex; /* using CHAR_BIT * sizeof(long) bits of precision ensures that mpfr_set_z_2exp is exact below */ mpfr_init2 (f, CHAR_BIT * sizeof(long)); mpz_init (z); mpz_set_ui (z, i); /* the following loop ensures that no overflow occurs */ do e = randexp (); while (e > mpfr_get_emax () - CHAR_BIT * sizeof(long)); inex = mpfr_set_z_2exp (f, z, e, rnd); if (inex != 0) { printf ("Error in mpfr_set_z_2exp for i=%ld, e=%ld," " wrong ternary value\n", i, (long) e); printf ("expected 0, got %d\n", inex); exit (1); } mpfr_div_2si (f, f, e, rnd); if (mpfr_get_si (f, MPFR_RNDZ) != i) { printf ("Error in mpfr_set_z_2exp for i=%ld e=", i); if (e < LONG_MIN) printf ("(<LONG_MIN)"); else if (e > LONG_MAX) printf ("(>LONG_MAX)"); else printf ("%ld", (long) e); printf (" rnd_mode=%d\n", rnd); printf ("expected %ld\n", i); printf ("got "); mpfr_dump (f); exit (1); } mpfr_clear (f); mpz_clear (z); }
//simulate serving process static double simulation_serve(Customer* customer,Queue* queue) { double serve_time = randexp(queue->P); double next_time = now_time+serve_time; total_customer++; queue->total_customer++; double wtime = now_time - customer->time_stamp - customer->time_serve; total_wtime+= wtime; customer->time_wait += wtime; queue->total_wtime += wtime; if(min_wtime==-1||min_wtime>wtime) min_wtime = wtime; if(max_wtime<wtime) max_wtime = wtime; if (queue->min_wtime == -1 || queue->min_wtime > wtime) queue->min_wtime = wtime; if (queue->max_wtime < wtime) queue->max_wtime = wtime; return next_time; }
//====================================================================== // Main: //====================================================================== int main(int argc, char *argv[]) { //------------------------------------------------------------------------------------- // Load contact data set: //------------------------------------------------------------------------------------- // Check if correct number of parameters was passed to program: // Check if correct number of parameters was passed to program: if(argc<3){ std::cout << "Error! Data file not defined.\n"; return 0; } else { if(argc<5){ std::cout << "Error! Epidemic parameters not defined.\n"; return 0; } else { if(argc<6){ std::cout << "Error! Simulation time not specified.\n"; return 0; } else { if(argc<7){ std::cout << "Error! Ensemble size not specified.\n"; return 0; } else { if(argc<8){ std::cout << "Error! Output time-resolution not specified.\n"; return 0;} } } } } // Set parameter values as specified: char *datafile=argv[1]; //dataset file name dt=atoi(argv[2]); //dataset time resolution (integer) char *beta_str = argv[3]; // base infection rate double beta = atof(beta_str); char *mu_str = argv[4]; // base recovery rate double mu = atof(mu_str); COUNTER betaprec=strlen(beta_str)-2; COUNTER muprec=strlen(mu_str)-2; COUNTER T_simulation = atoi(argv[5]); //simulation time COUNTER ensembleSize = atoi(argv[6]); //ensemble size (number of realizations) COUNTER outputTimeResolution = atoi(argv[7]); //output time-resolution // Open input file and load contact_lists: sprintf(inputname,"%s",datafile); const CONTACTS_LIST contactListList_original=loadContactListList(inputname); // Check if length of contacts_list > 0 and end program if it is not: if(contactListList_original.size()==0){ std::cout << "Error! Dataset empty.\n"; return 0; } //------------------------------------------------------------------------------------- // Define variables: //------------------------------------------------------------------------------------- NODES infected; //list of infected nodes double Mu; //cumulative recovery rate BOOLS isSusceptible, isInfected; //list which nodes are susceptible/infected, respectively COUNTER I,R; //number of infected and recovered nodes COUNTER SI; //number of susceptible nodes in contact with infectious nodes NODES si_s; //list of susceptible nodes in contact with infected nodes double Beta; //cumulative infection rate double Lambda; //cumulative transition rate double xi; // COUNTER t; //time counter COUNTER t_infectionStart; //starting time of infection NODE root; //root node of infection NODE i,j; double tau; //renormalized waiting time until next event CONTACTS_LIST contactListList(contactListList_original.size()); CONTACTS_LIST::iterator contactList_iterator; //iterator over list of contacts CONTACTS::iterator contact_iterator; //iterator over contacts double r_transitionType; //random variable for choosing which type of transition happens COUNTER m; //transition process number COUNTER n; //time-counter NODES::iterator node_iterator; //iterator over list of nodes NODES::reverse_iterator node_reverseIterator; //reverse iterator over list of nodes NODES::iterator last; //iterator for use when generating unique list of new infected nodes NODES numbersToRemove; // Containers for output data: NODES sumI_t(T_simulation/outputTimeResolution); //list of number of infected nodes in each recorded frame NODES sumR_t(T_simulation/outputTimeResolution); //list of number of recovered nodes in each recorded frame NODES hist_R(N+1); //histogram of R values after I=0 // Random number generators: boost::variate_generator<ENG,DIST_INT> randint(eng,dist_int); //random integer boost::variate_generator<ENG,DIST_REAL> rand(eng,dist_rand); //random float on [0,1[ boost::variate_generator<ENG,DIST_EXP> randexp(eng,dist_exp); //random exponentially distributed float //------------------------------------------------------------------------------------- // Simulate: //------------------------------------------------------------------------------------- std::clock_t clockStart = std::clock(); //timer COUNTER stopped=0; //counter of number of simulations that stopped (I=0) during T_simulation for(COUNTER q=0; q<ensembleSize; q++) { std::cout << q << "/" << ensembleSize << std::endl; //print realization # to screen // Copy list of contacts: contactListList=contactListList_original; // Choose at random infectious root node: root=randint(N); // Initialize lists of infected nodes and infected node IDs: R=0; infected.clear(); infected.push_back(root); I=1; Mu=mu; isInfected.assign(N,false); isInfected[root]=true; isSusceptible.assign(N,true); isSusceptible[root]=false; // First waiting "time": tau=randexp(1); // Random starting time of infection: t_infectionStart=randint(T_data); // Reset simulation time to zero: t=0; // Loop until either I=0 or t>=T_simulation while(I>0 && t<T_simulation) { // Loop over list of contact lists: for(contactList_iterator=contactListList.begin()+t_infectionStart; contactList_iterator!=contactListList.end(); contactList_iterator++) { // Create list of susceptible nodes in contact with infected nodes: si_s.clear(); numbersToRemove.clear(); n=0; for(contact_iterator=(*contactList_iterator).begin(); contact_iterator!=(*contactList_iterator).end(); contact_iterator++, n++) { i=(*contact_iterator).i; j=(*contact_iterator).j; if(isSusceptible[i]) { if(isInfected[j]){ si_s.push_back(i); } else { if(!isSusceptible[j]){ numbersToRemove.push_back(n); } } } else { if(isSusceptible[j]) { if(isInfected[i]){ si_s.push_back(j); } else{ numbersToRemove.push_back(n); } } else{ numbersToRemove.push_back(n); } } } // Remove obsolete contacts: for(node_reverseIterator=numbersToRemove.rbegin(); node_reverseIterator!=numbersToRemove.rend(); node_reverseIterator++) { // std::cout << *node_reverseIterator << " "; (*contactList_iterator)[*node_reverseIterator]=(*contactList_iterator).back(); (*contactList_iterator).pop_back(); } SI=si_s.size(); //number of possible S->I transitions Beta=(double)SI*beta; //cumulative infection rate Lambda=Beta+Mu; //cumulative transition rate: // Check if transition takes place during time-step: if(tau>=Lambda) //no transition takes place { tau-=Lambda; } else //at least one transition takes place { xi=1.; //fraction of time-step left before transition // Sampling step: while(tau<xi*Lambda) //repeat if next tau is smaller than ~ Lambda-tau { xi-=tau/Lambda; //fraction of time-step left after transition r_transitionType=Lambda*rand(); //random variable for weighted sampling of transitions if(r_transitionType<Beta) //S->I { m=randint(SI); //transition m isInfected[si_s[m]]=true; isSusceptible[si_s[m]]=false; // Add infected node to list: infected.push_back(si_s[m]); I++; Mu+=mu; } else //I->R { m=randint(I); //transition m isInfected[infected[m]]=false; // Remove drawn element from infected: infected[m]=infected.back(); infected.pop_back(); I--; R++; Mu-=mu; } // Redo list of S-I contacts: si_s.clear(); for(contact_iterator=(*contactList_iterator).begin(); contact_iterator!=(*contactList_iterator).end(); contact_iterator++) { i=(*contact_iterator).i; j=(*contact_iterator).j; if(isInfected[i]) { if(isSusceptible[j]) { si_s.push_back(j); } } else { if(isInfected[j]) { if(isSusceptible[i]) { si_s.push_back(i); } } } } SI=si_s.size(); Beta=beta*(double)SI; Lambda=Beta+Mu; //new cumulative transition rate // Draw new renormalized waiting time: tau=randexp(1); } tau-=xi*Lambda; } // Stop if I=0: if(I==0) { stopped++; hist_R[R]++; for(n=t; n<T_simulation; n++) { if(n % outputTimeResolution ==0){ sumR_t[n/outputTimeResolution]+=R; } } break; } // Read out I and R if t is divisible by outputTimeResolution if(t % outputTimeResolution ==0) { if(t>=T_simulation) //stop if max simulation time-steps has been reached { break; } else { sumI_t[t/outputTimeResolution]+=I; sumR_t[t/outputTimeResolution]+=R; } } t++; } t_infectionStart=0; } } double t_simu = ( std::clock() - clockStart ) / (double) CLOCKS_PER_SEC; //------------------------------------------------------------------------------------- // Save epidemic data to disk: //------------------------------------------------------------------------------------- clockStart=std::clock(); // Open output file: sprintf(outputname,"avg(I_t)-%s,N=%u,dt=%u,T=%u,beta=%.*f,mu=%.*f,Q=%u,res=%u.txt",datafile,N,dt,T_simulation,betaprec,beta,muprec,mu,ensembleSize,outputTimeResolution); output.open(outputname); // Write I_t to file: for(node_iterator=sumI_t.begin(); node_iterator!=sumI_t.end(); node_iterator++) { output << (double)*node_iterator/(double)ensembleSize << "\t"; } output.close(); // Open output file: sprintf(outputname,"avg(R_t)-%s,N=%u,dt=%u,T=%u,beta=%.*f,mu=%.*f,Q=%u,res=%u.txt",datafile,N,dt,T_simulation,betaprec,beta,muprec,mu,ensembleSize,outputTimeResolution); output.open(outputname); // Write R_t to file: for(node_iterator=sumR_t.begin(); node_iterator!=sumR_t.end(); node_iterator++) { output << (double)*node_iterator/(double)ensembleSize << "\t"; } output << "\n"; output.close(); // Open output file: sprintf(outputname,"p(R)-%s,N=%u,dt=%u,T=%u,beta=%.*f,mu=%.*f,Q=%u,res=%u.txt",datafile,N,dt,T_simulation,betaprec,beta,muprec,mu,ensembleSize,outputTimeResolution); output.open(outputname); // Write histrogram of R, h(R) to file: for(node_iterator=hist_R.begin(); node_iterator!=hist_R.end(); node_iterator++) { output << (double)*node_iterator/(double)ensembleSize << "\t"; } output.close(); double t_write = ( std::clock() - clockStart ) / (double) CLOCKS_PER_SEC; std::cout << std::endl << "temporal Gillespie---homogeneous & Poissonian SIR w/ contact removal: N=" << N << ", T=" << T_data << ", beta=" << beta << ", mu=" << mu; std::cout << ", output time-resolution = " << outputTimeResolution << std::endl; std::cout << "Simulation time: " << t_simu << "s, Stopped simulations: " << stopped << "/" << ensembleSize << std::endl; std::cout << "Writing to file: " << t_write << "s" << std::endl; return 0; }
int main(int argc, char **argv) { #if DEBUG feenableexcept(FE_DIVBYZERO| FE_INVALID|FE_OVERFLOW); // enable exceptions #endif if(argc ^ 2){ printf("Usage: ./sa sa.config\n"); exit(1); } if(read_config(argv[1])){ // read config printf("READDATA: Can't process %s \n", argv[1]); return 1; } T = T+SKIP; // increase T by SKIP to go from 0 to T all the way in time units // precomputing I_Gamma = 1.0/Gamma; I_Alpha = 1.0/Alpha; Bo = B; X0_Be = pow(X0, Beta); GaBe = Gamma * Beta; // event probabilites scaling by G; PE[0] = PE[0]*(double)G; PE[1] = PE[1]*(double)G; PE[2] = PE[2]*(double)G; initrand(Seed); init(); // note: method is in init.c // allocate memory at initial int i, j, ev, k = 0; // m; unsigned long seed; double dt, ct, tt; // tt: time of simulation; dt: delta time after which next event occurs; ct: counter time to check with skip time for stat calculation time_t now; for( i = 0; i < Runs; i++){ tt = 0.0, ct = 0.0; k = 0; //m = 0; if(Seed == 0){ now = time(0); seed = ((unsigned long)now); seed = 1454011037; initrand(seed); printf("\n run: %d rand seed: %lu\n",i+1, seed); } set_init_xrvpi(); // sets initial strategies vector, roles, valuations and payoffs calc_stat(0, i); for( j = 0; j < N; j++) printf("%.4lf ", V[0][j]); printf("\n"); // Gillespie's stochastic simulation while(tt < T){ // calc lambda; lambda = summation of P[j]s for(Lambda = 0, j = EVENTS; j--;) Lambda += PE[j]; // select time for next event dt = randexp(Lambda); //printf("dt: %.4lf\n", dt); // select next event ev = select_event(); // play the event play_event(ev); // update time tt += dt; // calc stat ct += dt; if(ct >= SKIP){ calc_stat(++k, i); // calculates all the stats ct = 0.0; } // update events associated probabilites if necessary } #if ALLDATAFILE calc_stat(-1, -1); // free file pointers for individual run data files #if !CLUSTER plotallIndividualRun(i, 0); // note: method is in dataplot.c #if GRAPHS plotallIndividualRun(i, 1); // note: method is in dataplot.c #endif #endif // write traits of final state { int m, n; char tstr[200], str[100]; sprintf(str, "traits%d.dat", i); sprintf(str, "traits%d.dat", i); prep_file(tstr, str); FILE *fp = fopen(tstr, "w"); for(m = 0; m < G; m++){ for( n = 0; n < GS[m]; n++){ fprintf(fp, "%.4lf %.4lf ", dxi[m][n], dsi[m][n]); } fprintf(fp, "\n"); } fclose(fp); } #if PUNISH #if DISP_MATRIX plotTraits(i, 0); // note: method is in dataplot.c #endif #if GRAPHS plotTraits(i, 1); // note: method is in dataplot.c #endif #endif #endif } // write effort and payoff data writefile_effort_fertility(); // note: method is in dataplot.c writefile_threshold_aggressiveness(); // note: method is in dataplot.c // plot data with graphics using gnuplot if(!CLUSTER){ plotall(0); // note: method is in dataplot.c #if GRAPHS plotall(1); // note: method is in dataplot.c #endif } #if PUNISH #if DISP_MATRIX displayMatrix(); #endif #endif cleanup(); // note: method is in init.c return 0; }