void running_stat_add_sample( running_statistics* data, float new_value ) { /* oldest value is the current index as it's one past the last value added */ float old_value = data->arr[data->idx]; /* Remove oldest value from sum if the index has wrapped around */ if( data->wrapped ) { /* remove old value from sum using Kahan summation */ data->sum = kahan_sum( &data->kahan_sub, -old_value, data->sum ); if( data->cmpt_var ) { variance_remove( &data->var, old_value ); } } /* Add new value in place of oldest value */ data->arr[data->idx++] = new_value; /* Add new value to sum using Kahan summation */ data->sum = kahan_sum( &data->kahan_add, new_value, data->sum ); /* Reset idx to 0 when it reaches max_sz and remember that it wrapped */ if( data->idx >= data->max_sz ) { data->idx = 0; data->wrapped = 1; } if( data->cmpt_var ) { variance_add( &data->var, new_value ); } }
utils::PopulationStatistics utils::PopulationStatistics::compute(std::vector<FitnessPair>& fitnesses, std::shared_ptr<FitnessCore>& fitness_core) { utils::PopulationStatistics::global_index++; utils::PopulationStatistics result = utils::PopulationStatistics(); // median and quartile calculation depends on the data being sorted std::sort(fitnesses.begin(), fitnesses.end(), [](FitnessPair& a, FitnessPair&b) { return a.fitness < b.fitness; }); unsigned int num_elements = (unsigned int) fitnesses.size(); result.min = fitnesses.front().fitness; result.max = fitnesses.back().fitness; result.mean = kahan_sum(fitnesses) / num_elements; result.median = num_elements % 2 == 0 ? ((fitnesses[num_elements / 2].fitness + fitnesses[num_elements / 2 + 1].fitness) / 2.0) : (fitnesses[num_elements / 2].fitness); result.lower_quartile = fitnesses[num_elements / 4].fitness; result.upper_quartile = fitnesses[(3 * num_elements) / 4].fitness; return result; }