// Find the best result found, set best to the particle, and return the performance double bestResult(double lbest[swarmsize][datasize], double lbestperf[swarmsize], double best[datasize]) { double perf; // Current best performance int i; // FOR-loop counters // Start with the first particle as best copyParticle(best,lbest[0]); perf = lbestperf[0]; // Iterate through the rest of the particles looking for better results for (i = 1; i < swarmsize; i++) { // If current performance of particle better than previous best, update previous best if (lbestperf[i] > perf) { copyParticle(best,lbest[i]); perf = lbestperf[i]; } } return perf; }
// Update the best performance of a single particle void updateLocalPerf(double swarm[swarmsize][datasize], double perf[swarmsize], double lbest[swarmsize][datasize], double lbestperf[swarmsize], double lbestage[swarmsize]) { int i; // FOR-loop counters // If current performance of particle better than previous best, update previous best for (i = 0; i < swarmsize; i++) { if (perf[i] > lbestperf[i]) { copyParticle(lbest[i],swarm[i]); lbestperf[i] = perf[i]; lbestage[i] = 1.0; } } }
// Update the best performance of a particle neighborhood void updateNBPerf(double lbest[swarmsize][datasize], double lbestperf[swarmsize], double nbbest[swarmsize][datasize], double nbbestperf[swarmsize], int neighbors[swarmsize][swarmsize]) { int i,j; // FOR-loop counters // For each particle, check the best performances of its neighborhood (-NB to NB, with wraparound from swarmsize-1 to 0) for (i = 0; i < swarmsize; i++) { nbbestperf[i] = lbestperf[i]; for (j = 0; j < swarmsize; j++) { // Make sure it's a valid particle if (!neighbors[i][j]) continue; // If current performance of particle better than previous best, update previous best if (lbestperf[j] > nbbestperf[i]) { copyParticle(nbbest[i],lbest[j]); nbbestperf[i] = lbestperf[j]; } } } }
// [[Rcpp::export]] Rcpp::List if2_s(Rcpp::NumericVector data, int T, int N, int NP, double coolrate, Rcpp::NumericVector params) { // params will be in the order R0, r, sigma, eta, berr, Sinit, Iinit, Rinit Rcpp::NumericMatrix statemeans(T, 3); Rcpp::NumericMatrix statedata(NP, 4); srand(time(NULL)); // Seed PRNG with system time double w[NP]; // particle weights Particle particles[NP]; // particle estimates for current step Particle particles_old[NP]; // intermediate particle states for resampling printf("Initializing particle states\n"); // Initialize particle parameter states (seeding) // Note that they will all be the same for this code as we are only filtering over the states for (int n = 0; n < NP; n++) { particles[n].R0 = params[0]; particles[n].r = params[1]; particles[n].sigma = params[2]; particles[n].eta = params[3]; particles[n].berr = params[4]; particles[n].Sinit = params[5]; particles[n].Iinit = params[6]; particles[n].Rinit = params[7]; } // START PASS THROUGH DATA printf("Starting filter\n"); printf("---------------\n"); // seed initial states for (int n = 0; n < NP; n++) { double Iinitcan; double i_infec = particles[n].Iinit; do { Iinitcan = i_infec + i_infec*randn(); } while (Iinitcan < 0 || N < Iinitcan); particles[n].S = N - Iinitcan; particles[n].I = Iinitcan; particles[n].R = 0.0; particles[n].B = (double) particles[n].R0 * particles[n].r / N; } State sMeans; getStateMeans(&sMeans, particles, NP); statemeans(0,0) = sMeans.S; statemeans(0,1) = sMeans.I; statemeans(0,2) = sMeans.R; // start run through data for (int t = 1; t < T; t++) { // generate individual predictions and weight for (int n = 0; n < NP; n++) { exp_euler_SIR(1.0/7.0, 0.0, 1.0, N, &particles[n]); double merr_par = particles[n].sigma; double y_diff = data[t] - particles[n].I; w[n] = 1.0/(merr_par*sqrt(2.0*M_PI)) * exp( - y_diff*y_diff / (2.0*merr_par*merr_par) ); } // cumulative sum for (int n = 1; n < NP; n++) { w[n] += w[n-1]; } // save particle states to resample from for (int n = 0; n < NP; n++){ copyParticle(&particles_old[n], &particles[n]); } // resampling for (int n = 0; n < NP; n++) { double w_r = randu() * w[NP-1]; int i = 0; while (w_r > w[i]) { i++; } // i is now the index to copy state from copyParticle(&particles[n], &particles_old[i]); } State sMeans; getStateMeans(&sMeans, particles, NP); statemeans(t,0) = sMeans.S; statemeans(t,1) = sMeans.I; statemeans(t,2) = sMeans.R; } // Get particle results to pass back to R for (int n = 0; n < NP; n++) { statedata(n, 0) = particles[n].S; statedata(n, 1) = particles[n].I; statedata(n, 2) = particles[n].R; statedata(n, 3) = particles[n].B; } return Rcpp::List::create( Rcpp::Named("statemeans") = statemeans, Rcpp::Named("statedata") = statedata ); }