feat: Formatting support for Kalman related types added

This commit is contained in:
Mateusz Pusz
2021-04-14 20:22:20 +02:00
parent 5781791a28
commit cee27390e6
8 changed files with 61 additions and 21 deletions

View File

@@ -151,26 +151,53 @@ constexpr Q covariance_extrapolation(Q uncertainty, Q process_noise_variance)
} // namespace kalman } // namespace kalman
template<typename... Qs> template<typename... Qs>
struct fmt::formatter<kalman::state<Qs...>> : formatter<std::string> { struct fmt::formatter<kalman::state<Qs...>> {
constexpr auto parse(format_parse_context& ctx)
{
detail::dynamic_specs_handler<format_parse_context> handler(specs, ctx);
return detail::parse_format_specs(ctx.begin(), ctx.end(), handler);
}
template<typename FormatContext> template<typename FormatContext>
auto format(const kalman::state<Qs...>& s, FormatContext& ctx) auto format(const kalman::state<Qs...>& s, FormatContext& ctx)
{ {
std::string txt = [&]{ memory_buffer value_buffer;
auto to_value_buffer = std::back_inserter(value_buffer);
if (specs.precision != -1) {
if constexpr(sizeof...(Qs) == 1) if constexpr(sizeof...(Qs) == 1)
return fmt::format("{1:%.{0}Q %q}", precision, kalman::get<0>(s)); format_to(to_value_buffer, "{1:%.{0}Q %q}", specs.precision, kalman::get<0>(s));
else if constexpr(sizeof...(Qs) == 2) else if constexpr(sizeof...(Qs) == 2)
return fmt::format("{{ {1:%.{0}Q %q}, {2:%.{0}Q %q} }}", precision, kalman::get<0>(s), kalman::get<1>(s)); format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q} }}", specs.precision, kalman::get<0>(s), kalman::get<1>(s));
else else
return fmt::format("{{ {1:%.{0}Q %q}, {2:%.{0}Q %q}, {3:%.{0}Q %q} }}", precision, kalman::get<0>(s), kalman::get<1>(s), kalman::get<2>(s)); format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q}, {3:%.{0}Q %q} }}", specs.precision, kalman::get<0>(s), kalman::get<1>(s), kalman::get<2>(s));
}(); }
return formatter<std::string>::format(txt, ctx); else {
if constexpr(sizeof...(Qs) == 1)
format_to(to_value_buffer, "{}", kalman::get<0>(s));
else if constexpr(sizeof...(Qs) == 2)
format_to(to_value_buffer, "{{ {}, {} }}", kalman::get<0>(s), kalman::get<1>(s));
else
format_to(to_value_buffer, "{{ {}, {}, {} }}", kalman::get<0>(s), kalman::get<1>(s), kalman::get<2>(s));
}
basic_memory_buffer<char> global_format_buffer;
units::detail::global_format_specs<char> global_specs = { specs.fill, specs.align, specs.width };
units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs);
return format_to(ctx.out(), to_string(global_format_buffer), to_string(value_buffer));
} }
private: private:
int precision = 1; // TODO find the easiest way to parse it from context detail::dynamic_format_specs<char> specs;
}; };
template<typename Q> template<typename Q>
struct fmt::formatter<kalman::estimation<Q>> : formatter<std::string> { struct fmt::formatter<kalman::estimation<Q>> {
constexpr auto parse(format_parse_context& ctx)
{
detail::dynamic_specs_handler<format_parse_context> handler(specs, ctx);
return detail::parse_format_specs(ctx.begin(), ctx.end(), handler);
}
template<typename FormatContext> template<typename FormatContext>
auto format(kalman::estimation<Q> e, FormatContext& ctx) auto format(kalman::estimation<Q> e, FormatContext& ctx)
{ {
@@ -180,9 +207,22 @@ struct fmt::formatter<kalman::estimation<Q>> : formatter<std::string> {
else else
return t.relative(); return t.relative();
}(kalman::get<0>(e.state)); }(kalman::get<0>(e.state));
std::string txt = fmt::format("{0:%.{2}Q} ± {1:%.{2}Q} {0:%q}", q, sqrt(e.uncertainty), precision);
return formatter<std::string>::format(txt, ctx); memory_buffer value_buffer;
auto to_value_buffer = std::back_inserter(value_buffer);
if (specs.precision != -1) {
format_to(to_value_buffer, "{0:%.{2}Q} ± {1:%.{2}Q} {0:%q}", q, sqrt(e.uncertainty), specs.precision);
}
else {
format_to(to_value_buffer, "{0:%Q} ± {1:%Q} {0:%q}", q, sqrt(e.uncertainty));
}
basic_memory_buffer<char> global_format_buffer;
units::detail::global_format_specs<char> global_specs = { specs.fill, specs.align, specs.width };
units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs);
return format_to(ctx.out(), to_string(global_format_buffer), to_string(value_buffer));
} }
private: private:
int precision = 3; // TODO find the easiest way to parse it from context detail::dynamic_format_specs<char> specs;
}; };

View File

@@ -40,7 +40,7 @@ void print_header(const kalman::State auto& initial)
void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next) void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next)
{ {
fmt::print("{:2} | {:8} | {} | {}\n", iteration, measured, current, next); fmt::print("{:2} | {:8} | {:.1} | {:.1}\n", iteration, measured, current, next);
} }
int main() int main()

View File

@@ -35,12 +35,12 @@ using namespace units;
void print_header(const kalman::State auto& initial) void print_header(const kalman::State auto& initial)
{ {
fmt::print("Initial: {}\n", initial); fmt::print("Initial: {}\n", initial);
fmt::print("{:>2} | {:>8} | {:>23} | {:>23}\n", "N", "Measured", "Curr. Estimate", "Next Estimate"); fmt::print("{:>2} | {:>8} | {:>24} | {:>24}\n", "N", "Measured", "Curr. Estimate", "Next Estimate");
} }
void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next) void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next)
{ {
fmt::print("{:2} | {:8} | {} | {}\n", iteration, measured, current, next); fmt::print("{:2} | {:8} | {:>24.1} | {:>24.1}\n", iteration, measured, current, next);
} }
int main() int main()

View File

@@ -41,7 +41,7 @@ void print_header(const kalman::State auto& initial)
void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next) void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next)
{ {
fmt::print("{:2} | {:8} | {:>35} | {:>35}\n", iteration, measured, current, next); fmt::print("{:2} | {:8} | {:>35.1} | {:>35.1}\n", iteration, measured, current, next);
} }
int main() int main()

View File

@@ -40,7 +40,7 @@ void print_header(kalman::estimation<Q> initial)
template<Quantity Q, Dimensionless K> template<Quantity Q, Dimensionless K>
void print(auto iteration, K gain, Q measured, kalman::estimation<Q> current, kalman::estimation<Q> next) void print(auto iteration, K gain, Q measured, kalman::estimation<Q> current, kalman::estimation<Q> next)
{ {
fmt::print("{:2} | {:5%.2Q} | {:8} | {:16} | {:16}\n", iteration, gain, measured, current, next); fmt::print("{:2} | {:5%.2Q} | {:8} | {:>16.2} | {:>16.2}\n", iteration, gain, measured, current, next);
} }
int main() int main()

View File

@@ -61,7 +61,7 @@ void print_header(kalman::estimation<QP> initial)
template<QuantityPoint QP, Dimensionless K> template<QuantityPoint QP, Dimensionless K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next) void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{ {
fmt::print("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18} | {:>18}\n", iteration, gain, measured.relative(), current, next); fmt::print("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, measured.relative(), current, next);
} }
int main() int main()

View File

@@ -61,7 +61,7 @@ void print_header(kalman::estimation<QP> initial)
template<QuantityPoint QP, Dimensionless K> template<QuantityPoint QP, Dimensionless K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next) void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{ {
fmt::print("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18} | {:>18}\n", iteration, gain, measured.relative(), current, next); fmt::print("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, measured.relative(), current, next);
} }
int main() int main()

View File

@@ -55,13 +55,13 @@ template<QuantityPoint QP>
void print_header(kalman::estimation<QP> initial) void print_header(kalman::estimation<QP> initial)
{ {
fmt::print("Initial: {}\n", initial); fmt::print("Initial: {}\n", initial);
fmt::print("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured", "Curr. Estimate", "Next Estimate"); fmt::print("{:>2} | {:>7} | {:>10} | {:>16} | {:>16}\n", "N", "Gain", "Measured", "Curr. Estimate", "Next Estimate");
} }
template<QuantityPoint QP, Dimensionless K> template<QuantityPoint QP, Dimensionless K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next) void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{ {
fmt::print("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18} | {:>18}\n", iteration, gain, measured.relative(), current, next); fmt::print("{:2} | {:7%.3Q} | {:10%.3Q %q} | {:>16.2} | {:>16.2}\n", iteration, gain, measured.relative(), current, next);
} }
int main() int main()