Wildmeshing Toolkit
Loading...
Searching...
No Matches
QualityStats.hpp
1#pragma once
2
3#include <wmtk/utils/Logger.hpp>
4
5#include "expression_parser/Expression.hpp"
6
7#include <cmath>
8#include <string>
9#include <tuple>
10#include <vector>
11
12namespace wmtk::components::simwild {
13
23{
25 std::string label;
27 double target = 0.;
29 double max_quality = -1.;
30 double sum_quality = 0.;
31 size_t count = 0;
32
33 double avg_quality() const { return count > 0 ? sum_quality / count : 0.; }
35 double max_relative() const { return count > 0 ? max_quality / target : -1.; }
36};
37
40{
43 std::vector<QualityGroup> groups;
45 double max_relative = -1.;
46 double avg_relative = 0.;
47 size_t count = 0;
48};
49
65template <class ValidFn, class TagsFn, class QualityFn>
66QualityBreakdown collect_quality_breakdown(
67 const size_t capacity,
68 const std::vector<std::tuple<expression_parser::ExpressionPtr, double>>& quality_field,
69 const double base_target,
70 ValidFn&& is_valid,
71 TagsFn&& tags_of,
72 QualityFn&& quality_of)
73{
75 out.groups.resize(quality_field.size() + 1);
76 out.groups[0].label = "(default)";
77 out.groups[0].target = base_target;
78 for (size_t i = 0; i < quality_field.size(); ++i) {
79 const auto& [expr, target] = quality_field[i];
80 out.groups[i + 1].label = expr->to_string();
81 out.groups[i + 1].target = target;
82 }
83
84 for (size_t cid = 0; cid < capacity; ++cid) {
85 if (!is_valid(cid)) {
86 continue;
87 }
88 const auto& tags = tags_of(cid);
89
90 // Last match wins, mirroring target_quality. Scanning backwards finds it first, and the
91 // common case -- a cell matching nothing -- still costs the whole field either way.
92 size_t group = 0;
93 for (size_t i = quality_field.size(); i-- > 0;) {
94 if (std::get<0>(quality_field[i])->eval(tags)) {
95 group = i + 1;
96 break;
97 }
98 }
99
100 const double quality = quality_of(cid);
101 QualityGroup& g = out.groups[group];
102 g.max_quality = std::max(g.max_quality, quality);
103 g.sum_quality += quality;
104 ++g.count;
105
106 const double relative = quality / g.target;
107 out.max_relative = std::max(out.max_relative, relative);
108 out.avg_relative += relative;
109 ++out.count;
110 }
111
112 if (out.count > 0) {
113 out.avg_relative /= out.count;
114 }
115 return out;
116}
117
126inline void log_quality_breakdown(const QualityBreakdown& breakdown)
127{
128 std::vector<const QualityGroup*> order;
129 order.reserve(breakdown.groups.size());
130 for (const auto& g : breakdown.groups) {
131 order.push_back(&g);
132 }
133 std::sort(order.begin(), order.end(), [](const QualityGroup* a, const QualityGroup* b) {
134 return a->max_relative() > b->max_relative();
135 });
136
137 logger().info(
138 "Quality by tag ({} cells, max rel = {:.4}, avg rel = {:.4}):",
139 breakdown.count,
140 breakdown.max_relative,
141 breakdown.avg_relative);
142 for (const QualityGroup* g : order) {
143 if (g->count == 0) {
144 logger().info(" {:<20} no cells", g->label);
145 continue;
146 }
147 logger().info(
148 " {:<20} n = {:>8}, max = {:>8.6}, avg = {:>8.6}, target = {:>6.6}, max rel = {:6>.4}",
149 g->label,
150 g->count,
151 g->max_quality,
152 g->avg_quality(),
153 g->target,
154 g->max_relative());
155 }
156}
157
158} // namespace wmtk::components::simwild
Per-group breakdown plus the mesh-wide relative figures optimization_quality_stats returns.
Definition QualityStats.hpp:40
double max_relative
Mesh-wide max/avg of quality RELATIVE to each cell's own target.
Definition QualityStats.hpp:45
std::vector< QualityGroup > groups
Definition QualityStats.hpp:43
Quality of the cells governed by one entry of the quality field.
Definition QualityStats.hpp:23
std::string label
The expression as written in the spec, or "(default)" for the fallback group.
Definition QualityStats.hpp:25
double max_relative() const
Quality relative to this group's own target – the number the stopping criterion sees.
Definition QualityStats.hpp:35
double target
The target the optimizer applies to this group – the entry's value, or stop_energy.
Definition QualityStats.hpp:27
double max_quality
Largest and summed ABSOLUTE quality; avg_quality divides the sum by count.
Definition QualityStats.hpp:29