void SphereState::decrementBetaInTime(double deltaTime) {
    beta -= 0.5 * deltaTime;
    adjustBeta();
}
Exemple #2
0
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);
        }
    }
}