36template <
typename Rep,
typename Period = std::ratio<1>>
37constexpr double to_ms(
const std::chrono::duration<Rep, Period>& duration) {
38 using std::chrono::duration_cast;
39 using std::chrono::microseconds;
40 return duration_cast<microseconds>(duration).count() / 1e3;
47template <
typename Scalar>
49 if (value == Scalar(0)) {
53 int exponent =
static_cast<int>(
log10(value));
57 }
else if (exponent == 1) {
61 int n = std::abs(exponent);
64 digits.emplace_back(n % 10);
68 std::string output =
"10";
74 constexpr std::array strs = {
"⁰",
"¹",
"²",
"³",
"⁴",
75 "⁵",
"⁶",
"⁷",
"⁸",
"⁹"};
76 for (
const auto& digit : digits | std::views::reverse) {
77 output += strs[digit];
85#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
91template <
typename Scalar>
93 const Eigen::Vector<Scalar, Eigen::Dynamic>& c_e) {
94 slp::println(
"The problem has too few degrees of freedom.");
95 slp::println(
"Violated constraints (cₑ(x) = 0) in order of declaration:");
96 for (
int row = 0; row < c_e.rows(); ++row) {
97 if (c_e[row] < Scalar(0)) {
98 slp::println(
" {}/{}: {} = 0", row + 1, c_e.rows(), c_e[row]);
103#define print_too_few_dofs_error(...)
106#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
112template <
typename Scalar>
114 const Eigen::Vector<Scalar, Eigen::Dynamic>& c_e) {
116 "The problem is locally infeasible due to violated equality "
118 slp::println(
"Violated constraints (cₑ(x) = 0) in order of declaration:");
119 for (
int row = 0; row < c_e.rows(); ++row) {
120 if (c_e[row] < Scalar(0)) {
121 slp::println(
" {}/{}: {} = 0", row + 1, c_e.rows(), c_e[row]);
126#define print_c_e_local_infeasibility_error(...)
129#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
135template <
typename Scalar>
137 const Eigen::Vector<Scalar, Eigen::Dynamic>& c_i) {
139 "The problem is locally infeasible due to violated inequality "
141 slp::println(
"Violated constraints (cᵢ(x) ≥ 0) in order of declaration:");
142 for (
int row = 0; row < c_i.rows(); ++row) {
143 if (c_i[row] < Scalar(0)) {
144 slp::println(
" {}/{}: {} ≥ 0", row + 1, c_i.rows(), c_i[row]);
149#define print_c_i_local_infeasibility_error(...)
152#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
154 const std::span<
const std::pair<Eigen::Index, Eigen::Index>>
155 conflicting_lower_upper_bound_indices) {
157 "The problem is globally infeasible due to conflicting bound "
159 for (
const auto& [lower_bound_idx, upper_bound_idx] :
160 conflicting_lower_upper_bound_indices) {
162 " Inequality constraint {} gives a lower bound that is greater than "
163 "the upper bound given by inequality constraint {}",
164 lower_bound_idx, upper_bound_idx);
168#define print_bound_constraint_global_infeasibility_error(...)
171#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
189template <
typename Scalar,
typename Rep,
typename Period = std::ratio<1>>
191 const std::chrono::duration<Rep, Period>& time,
192 Scalar error, Scalar cost,
193 Scalar infeasibility, Scalar complementarity,
194 Scalar μ, Scalar δ, Scalar primal_α,
195 Scalar primal_α_max, Scalar α_reduction_factor,
197 if (iterations % 20 == 0) {
198 if (iterations == 0) {
204 "{:━^4}┯{:━^4}┯{:━^9}┯{:━^12}┯{:━^13}┯{:━^12}┯{:━^12}┯{:━^8}┯{:━^5}┯"
205 "{:━^8}┯{:━^8}┯{:━^2}",
206 "",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"");
207 if (iterations == 0) {
213 "┃{:^4}│{:^4}│{:^9}│{:^12}│{:^13}│{:^12}│{:^12}│{:^8}│{:^5}│{:^8}│{:^8}"
215 "iter",
"type",
"time (ms)",
"error",
"cost",
"infeas.",
"complement.",
216 "μ",
"reg",
"primal α",
"dual α",
"↩");
218 "┡{:━^4}┷{:━^4}┷{:━^9}┷{:━^12}┷{:━^13}┷{:━^12}┷{:━^12}┷{:━^8}┷{:━^5}┷"
219 "{:━^8}┷{:━^8}┷{:━^2}┩",
220 "",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"");
235 static_cast<int>(
log(primal_α / primal_α_max) /
log(α_reduction_factor));
237 constexpr std::array ITERATION_TYPES = {
"norm",
"✓SOC",
"XSOC"};
239 "│{:4} {:4} {:9.3f} {:12e} {:13e} {:12e} {:12e} {:.2e} {:<5} {:.2e} "
241 iterations, ITERATION_TYPES[
static_cast<uint8_t
>(type)],
to_ms(time),
242 error, cost, infeasibility, complementarity, μ,
power_of_10(δ), primal_α,
246#define print_iteration_diagnostics(...)
249#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
255#define print_bottom_iteration_diagnostics(...)
265 value = std::clamp(value, 0.0, 1.0);
268 int fpart =
static_cast<int>(std::modf(value * Width, &ipart) * 8);
270 constexpr std::array strs = {
" ",
"▏",
"▎",
"▍",
"▌",
"▋",
"▊",
"▉",
"█"};
274 while (
index < ipart) {
282 while (
index < Width) {
290#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
296 auto solve_duration =
to_ms(solve_profilers[0].total_duration());
298 slp::println(
"┏{:━^23}┯{:━^18}┯{:━^10}┯{:━^9}┯{:━^4}┓",
"",
"",
"",
"",
"");
299 slp::println(
"┃{:^23}│{:^18}│{:^10}│{:^9}│{:^4}┃",
"solver trace",
"percent",
300 "total (ms)",
"each (ms)",
"runs");
301 slp::println(
"┡{:━^23}┷{:━^18}┷{:━^10}┷{:━^9}┷{:━^4}┩",
"",
"",
"",
"",
"");
303 for (
auto& profiler : solve_profilers) {
304 double norm = solve_duration == 0.0
305 ? (&profiler == &solve_profilers[0] ? 1.0 : 0.0)
306 :
to_ms(profiler.total_duration()) / solve_duration;
307 slp::println(
"│{:<23} {:>6.2f}%▕{}▏ {:>10.3f} {:>9.3f} {:>4}│",
309 to_ms(profiler.total_duration()),
310 to_ms(profiler.average_duration()), profiler.num_solves());
316#define print_solver_diagnostics(...)
319#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
325 auto setup_duration =
to_ms(setup_profilers[0].duration());
328 slp::println(
"┏{:━^23}┯{:━^18}┯{:━^10}┯{:━^9}┯{:━^4}┓",
"",
"",
"",
"",
"");
329 slp::println(
"┃{:^23}│{:^18}│{:^10}│{:^9}│{:^4}┃",
"autodiff trace",
330 "percent",
"total (ms)",
"each (ms)",
"runs");
331 slp::println(
"┡{:━^23}┷{:━^18}┷{:━^10}┷{:━^9}┷{:━^4}┩",
"",
"",
"",
"",
"");
334 for (
auto& profiler : setup_profilers) {
335 double norm = setup_duration == 0.0
336 ? (&profiler == &setup_profilers[0] ? 1.0 : 0.0)
337 :
to_ms(profiler.duration()) / setup_duration;
338 slp::println(
"│{:<23} {:>6.2f}%▕{}▏ {:>10.3f} {:>9.3f} {:>4}│",
340 to_ms(profiler.duration()),
to_ms(profiler.duration()),
"1");
346#define print_autodiff_diagnostics(...)
@ index
Definition base.h:690
wpi::util::SmallVector< T > small_vector
Definition small_vector.hpp:10
Definition expression_graph.hpp:11
void print_iteration_diagnostics(int iterations, IterationType type, const std::chrono::duration< Rep, Period > &time, Scalar error, Scalar cost, Scalar infeasibility, Scalar complementarity, Scalar μ, Scalar δ, Scalar primal_α, Scalar primal_α_max, Scalar α_reduction_factor, Scalar dual_α)
Prints diagnostics for the current iteration.
Definition print_diagnostics.hpp:190
Variable< Scalar > log10(const Variable< Scalar > &x)
log10() for Variables.
Definition variable.hpp:512
void print_c_i_local_infeasibility_error(const Eigen::Vector< Scalar, Eigen::Dynamic > &c_i)
Prints inequality constraint local infeasibility error.
Definition print_diagnostics.hpp:136
constexpr double to_ms(const std::chrono::duration< Rep, Period > &duration)
Converts std::chrono::duration to a number of milliseconds rounded to three decimals.
Definition print_diagnostics.hpp:37
std::string histogram(double value)
Renders histogram of the given normalized value.
Definition print_diagnostics.hpp:264
IterationType
Iteration type.
Definition print_diagnostics.hpp:25
@ NORMAL
Normal iteration.
Definition print_diagnostics.hpp:27
@ ACCEPTED_SOC
Accepted second-order correction iteration.
Definition print_diagnostics.hpp:29
@ REJECTED_SOC
Rejected second-order correction iteration.
Definition print_diagnostics.hpp:31
void print_bound_constraint_global_infeasibility_error(const std::span< const std::pair< Eigen::Index, Eigen::Index > > conflicting_lower_upper_bound_indices)
Definition print_diagnostics.hpp:153
Variable< Scalar > log(const Variable< Scalar > &x)
log() for Variables.
Definition variable.hpp:503
std::string power_of_10(Scalar value)
Renders value as power of 10.
Definition print_diagnostics.hpp:48
void print_bottom_iteration_diagnostics()
Prints bottom of iteration diagnostics table.
Definition print_diagnostics.hpp:251
void println(fmt::format_string< T... > fmt, T &&... args)
Wrapper around fmt::println() that squelches write failure exceptions.
Definition print.hpp:37
void print_solver_diagnostics(const gch::small_vector< SolveProfiler > &solve_profilers)
Prints solver diagnostics.
Definition print_diagnostics.hpp:294
void print_too_few_dofs_error(const Eigen::Vector< Scalar, Eigen::Dynamic > &c_e)
Prints error for too few degrees of freedom.
Definition print_diagnostics.hpp:92
void print(fmt::format_string< T... > fmt, T &&... args)
Wrapper around fmt::print() that squelches write failure exceptions.
Definition print.hpp:19
void print_autodiff_diagnostics(const gch::small_vector< SetupProfiler > &setup_profilers)
Prints autodiff diagnostics.
Definition print_diagnostics.hpp:323
void print_c_e_local_infeasibility_error(const Eigen::Vector< Scalar, Eigen::Dynamic > &c_e)
Prints equality constraint local infeasibility error.
Definition print_diagnostics.hpp:113