void SphereState::decrementBetaInTime(double deltaTime) { beta -= 0.5 * deltaTime; adjustBeta(); }
void match_prevalence(int treatmentNumber, int simNumber, double treatment, double startingBeta) { std::cout << "Treatment #" << treatmentNumber << " and simulation #" << simNumber << ":" << std::endl; std::array<double, INIT_NUM_STYPES> betas; betas.fill(startingBeta); std::array<double, INIT_NUM_STYPES> serotype_ranks; for(int i = 0; i < INIT_NUM_STYPES; i++) { serotype_ranks[i] = i + 1; } double best_likelihood = std::numeric_limits<double>::lowest(); std::array<double, INIT_NUM_STYPES> best_betas = betas; std::array<double, INIT_NUM_STYPES> best_serotype_ranks = serotype_ranks; double prevError = 10.0; double oldPrevError = 1.0; double weight = INIT_WEIGHT; std::array<int, INIT_NUM_STYPES + 1> observed_prevalence = {283, 237, 184, 117, 90, 85, 84, 70, 56, 54, 53, 51, 49, 49, 43, 38, 34, 34, 29, 25, 23, 21, 19, 18, 15, 0, 10079}; for(int attempt = 0; attempt < 10; attempt++) { SimPars thesePars(treatmentNumber, simNumber); thesePars.set_serotype_ranks(serotype_ranks); thesePars.set_betas(betas); Simulation thisSim(treatmentNumber, simNumber, &thesePars); thisSim.runDemSim(); auto serotype_counts = thisSim.runTestEpidSim(); std::array<double, INIT_NUM_STYPES + 1> expected_prevalence = {0}; std::array<double, INIT_NUM_STYPES> prevalence_error = {0}; double expected_population = std::accumulate(serotype_counts.begin(), serotype_counts.end(), 0.0); double infected_prevalence = 0; int observed_population = std::accumulate(observed_prevalence.begin(), observed_prevalence.begin() + INIT_NUM_STYPES + 1, 0); double target_prevalence = std::accumulate(observed_prevalence.begin(), observed_prevalence.begin() + INIT_NUM_STYPES, 0.0) / observed_population; for(int i = 0; i < INIT_NUM_STYPES; i++) { infected_prevalence += serotype_counts[i] / (double)expected_population; prevalence_error[i] = expected_prevalence[i] - observed_prevalence[i] / (double)observed_population; if(i == HFLU_INDEX) { prevalence_error[i] = 0; } expected_prevalence[i] = (serotype_counts[i] + 0.01) / (expected_population + INIT_NUM_STYPES * 0.01); } expected_prevalence.back() = 1 - infected_prevalence; double likelihood = calculate_likelihood(expected_prevalence, observed_prevalence); if(likelihood > best_likelihood) { best_likelihood = likelihood; best_betas = betas; best_serotype_ranks = serotype_ranks; } else { betas = best_betas; serotype_ranks = best_serotype_ranks; } std::cout << "Likelihood=" << likelihood << "(best=" << best_likelihood << ")" << std::endl; if(attempt % 2 == 0) { std::cout << "Fitting overall prevalence" << std::endl; prevError = infected_prevalence - target_prevalence; std::cout << "Observed prevalence=" << target_prevalence << "; expected prevalence=" << infected_prevalence << "; error=" << prevError << "; weight = " << weight << std::endl; if(abs(prevError) > PREV_ERROR_THOLD) { // if error changed signs and overshot, reduce weight if(prevError * oldPrevError < 0) { weight *= COOL_DOWN; } // if climbing too slowly, increase weight else if(abs(target_prevalence - prevError) / abs(target_prevalence - oldPrevError) > TEMP_THOLD) { weight *= WARM_UP; } adjustBeta(prevError, weight, betas); oldPrevError = prevError; } } else { std::cout << "Fitting per-serotype prevalence" << std::endl; adjust_ranks(prevalence_error, serotype_ranks); } } }