13#if !defined(ULTRA_ANALYZER_H)
14# error "Don't include this file directly, include the specific .h instead"
17#if !defined(ULTRA_ANALYZER_TCC)
18#define ULTRA_ANALYZER_TCC
23inline void merge_ct(
auto &destination,
const auto &source)
25 for (
const auto &[ct, n] : source)
33 { c.active_crossover_type() } -> std::convertible_to<int>;
36template<Indiv
idual I, Fitness F>
37group_stat<I, F>::group_stat(population_uid
id) : uid(id)
47template<Indiv
idual I, Fitness F>
48void group_stat<I, F>::add(
const I &ind,
const F &f)
52 const std::size_t len(active_slots(ind));
61 ++crossover_type[ind.active_crossover_type()];
64template<Indiv
idual I, Fitness F>
65void group_stat<I, F>::merge(group_stat gs)
68 fitness.merge(gs.fitness);
69 length.merge(gs.length);
71 internal::merge_ct(crossover_type, gs.crossover_type);
79template<Indiv
idual I, Fitness F>
80template<LayeredPopulation P, Evaluator E> analyzer<I, F>::analyzer(
81 const P &pop,
const E &eva)
83 const auto gather_subgroup_stats([&eva](
auto layer_iter)
87 for (
const auto &ind : *layer_iter)
88 ret.
add(ind, eva(ind));
93 const auto range(pop.range_of_layers());
94 std::vector<std::future<group_stat<I, F>>> tasks;
95 for (
auto l(range.begin()); l != range.end(); ++l)
96 tasks.push_back(std::async(std::launch::async, gather_subgroup_stats, l));
98 for (
auto &task : tasks)
99 group_stat_.push_back(task.get());
105template<Indiv
idual I, Fitness F>
111template<Indiv
idual I, Fitness F>
112const group_stat<I, F> *analyzer<I, F>::group(population_uid uid)
const
114 const auto iter(std::ranges::find_if(group_stat_,
115 [uid](
const auto &grp)
117 return grp.uid == uid;
120 return iter == group_stat_.end() ? nullptr : std::addressof(*iter);
123template<Indiv
idual I, Fitness F>
124group_stat<I, F> *analyzer<I, F>::group(population_uid uid)
127 return const_cast<group_stat<I, F> *
>(std::as_const(*this).group(uid));
133template<Indiv
idual I, Fitness F>
134group_stat<I, F> analyzer<I, F>::overall_group_stat()
const
136 group_stat<I, F> ret;
138 for (
const auto &gs : group_stat_)
148template<Indiv
idual I, Fitness F>
149auto analyzer<I, F>::crossover_types()
const
151 decltype(group_stat<I, F>::crossover_type) ret;
152 for (
const auto &gs : group_stat_)
153 internal::merge_ct(ret, gs.crossover_type);
162template<Indiv
idual I, Fitness F>
163const auto &analyzer<I, F>::crossover_types(population_uid g)
const
165 const auto *ptr(group(g));
168 return ptr->crossover_type;
175template<Indiv
idual I, Fitness F>
176template<Population P>
186template<Indiv
idual I, Fitness F>
190 for (
const auto &gs : group_stat_)
201template<Indiv
idual I, Fitness F>
202const distribution<double> &analyzer<I, F>::age_dist(population_uid g)
const
204 const auto *ptr(group(g));
215template<Indiv
idual I, Fitness F>
216template<Population P>
226template<Indiv
idual I, Fitness F>
230 for (
const auto &gs : group_stat_)
231 ret.merge(gs.fitness);
241template<Indiv
idual I, Fitness F>
242const distribution<F> &analyzer<I, F>::fit_dist(population_uid g)
const
244 const auto *ptr(group(g));
255template<Indiv
idual I, Fitness F>
256template<Population P>
266template<Indiv
idual I, Fitness F>
270 for (
const auto &gs : group_stat_)
271 ret.merge(gs.length);
281template<Indiv
idual I, Fitness F>
282const distribution<double> &analyzer<I, F>::length_dist(population_uid g)
const
284 const auto *ptr(group(g));
295template<Indiv
idual I, Fitness F>
296template<Population P>
305template<Indiv
idual I, Fitness F>
308 const auto ad(age_dist());
309 const auto cts(crossover_types());
310 const auto fd(fit_dist());
311 const auto ld(length_dist());
313 for (
const auto &g : group_stat_)
315 if (g.age.min() < ad.min())
317 if (g.age.max() > ad.max())
320 if (!g.fitness.empty())
325 if (g.fitness.min() < fd.min())
327 if (g.fitness.max() > fd.max())
331 if (g.length.min() < ld.min())
333 if (g.length.max() > ld.max())
338 std::size_t sum_cross(0);
340 for (
auto [type,num] : g.crossover_type)
344 if (type >= I::NUM_CROSSOVERS)
347 if (num > cts.at(type))
351 if (sum_cross != g.age.size())
356 if (!g.crossover_type.empty())
360 if (g.age.size() != g.length.size())
362 if (g.fitness.size() > g.age.size())
378template<Indiv
idual I, Fitness F>
379void analyzer<I, F>::add(
const I &ind,
const F &f, population_uid uid)
381 if (
auto *selected = group(uid))
382 selected->add(ind, f);
385 group_stat_.emplace_back(uid);
386 group_stat_.back().add(ind, f);
distribution< double > age_dist() const
Definition analyzer.h:188
distribution< double > length_dist() const
Definition analyzer.h:268
auto crossover_types() const
Definition analyzer.h:150
bool is_valid() const
Definition analyzer.h:307
distribution< F > fit_dist() const
Definition analyzer.h:228
void clear()
Definition analyzer.h:107
Definition distribution.h:36
Definition analyzer.tcc:31
void add(const I &, const F &)
Definition analyzer.h:49